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
22 from DebugFlags import debug_disposal_code
24 absolute_path_length = 0
26 def relative_position(pos):
28 We embed the relative filename in the generated C file, since we
29 don't want to have to regnerate and compile all the source code
30 whenever the Python install directory moves (which could happen,
31 e.g,. when distributing binaries.)
34 a position tuple -- (absolute filename, line number column position)
42 global absolute_path_length
43 if absolute_path_length==0:
44 absolute_path_length = len(os.path.abspath(os.getcwd()))
45 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
47 def embed_position(pos, docstring):
48 if not Options.embed_pos_in_docstring:
50 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
53 return EncodedString(pos_line)
55 # make sure we can encode the filename in the docstring encoding
56 # otherwise make the docstring a unicode string
57 encoding = docstring.encoding
58 if encoding is not None:
60 encoded_bytes = pos_line.encode(encoding)
61 except UnicodeEncodeError:
65 # reuse the string encoding of the original docstring
66 doc = EncodedString(pos_line)
68 doc = EncodedString(pos_line + u'\n' + docstring)
69 doc.encoding = encoding
73 from Code import CCodeWriter
74 from types import FunctionType
76 def write_func_call(func):
78 if len(args) > 1 and isinstance(args[1], CCodeWriter):
79 # here we annotate the code with this function call
80 # but only if new code is generated
82 marker = ' /* %s -> %s.%s %s */' % (
83 ' ' * code.call_level,
84 node.__class__.__name__,
87 pristine = code.buffer.stream.tell()
89 start = code.buffer.stream.tell()
91 res = func(*args, **kwds)
93 if start == code.buffer.stream.tell():
94 code.buffer.stream.seek(pristine)
96 marker = marker.replace('->', '<-')
100 return func(*args, **kwds)
103 class VerboseCodeWriter(type):
104 # Set this as a metaclass to trace function calls in code.
105 # This slows down code generation and makes much larger files.
106 def __new__(cls, name, bases, attrs):
108 for mname, m in attrs.items():
109 if isinstance(m, FunctionType):
110 attrs[mname] = write_func_call(m)
111 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
115 # pos (string, int, int) Source file position
116 # is_name boolean Is a NameNode
117 # is_literal boolean Is a ConstNode
119 # Uncomment this for debugging.
120 # __metaclass__ = VerboseCodeWriter
126 # All descandants should set child_attrs to a list of the attributes
127 # containing nodes considered "children" in the tree. Each such attribute
128 # can either contain a single node or a list of nodes. See Visitor.py.
131 def __init__(self, pos, **kw):
133 self.__dict__.update(kw)
135 gil_message = "Operation"
137 def gil_check(self, env):
142 error(self.pos, "%s not allowed without gil" % self.gil_message)
144 def clone_node(self):
145 """Clone the node. This is defined as a shallow copy, except for member lists
146 amongst the child attributes (from get_child_accessors) which are also
147 copied. Lists containing child nodes are thus seen as a way for the node
148 to hold multiple children directly; the list is not treated as a seperate
149 level in the tree."""
150 result = copy.copy(self)
151 for attrname in result.child_attrs:
152 value = getattr(result, attrname)
153 if isinstance(value, list):
154 setattr(result, attrname, [x for x in value])
159 # There are 4 phases of parse tree processing, applied in order to
160 # all the statements in a given scope-block:
162 # (0) analyse_control_flow
163 # Create the control flow tree into which state can be asserted and
166 # (1) analyse_declarations
167 # Make symbol table entries for all declarations at the current
168 # level, both explicit (def, cdef, etc.) and implicit (assignment
169 # to an otherwise undeclared name).
171 # (2) analyse_expressions
172 # Determine the result types of expressions and fill in the
173 # 'type' attribute of each ExprNode. Insert coercion nodes into the
174 # tree where needed to convert to and from Python objects.
175 # Allocate temporary locals for intermediate results. Fill
176 # in the 'result_code' attribute of each ExprNode with a C code
180 # Emit C code for all declarations, statements and expressions.
181 # Recursively applies the 3 processing phases to the bodies of
185 def analyse_control_flow(self, env):
188 def analyse_declarations(self, env):
191 def analyse_expressions(self, env):
192 raise InternalError("analyse_expressions not implemented for %s" % \
193 self.__class__.__name__)
195 def generate_code(self, code):
196 raise InternalError("generate_code not implemented for %s" % \
197 self.__class__.__name__)
199 def annotate(self, code):
200 # mro does the wrong thing
201 if isinstance(self, BlockNode):
202 self.body.annotate(code)
207 except AttributeError:
209 if not self.child_attrs:
212 for attr in self.child_attrs:
213 child = getattr(self, attr)
214 # Sometimes lists, sometimes nodes
217 elif isinstance(child, list):
219 pos = max(pos, c.end_pos())
221 pos = max(pos, child.end_pos())
225 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
227 return "<...nesting level cutoff...>"
228 if encountered is None:
230 if id(self) in encountered:
231 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
232 encountered.add(id(self))
234 def dump_child(x, level):
235 if isinstance(x, Node):
236 return x.dump(level, filter_out, cutoff-1, encountered)
237 elif isinstance(x, list):
238 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
243 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
245 return "<%s (%d)>" % (self.__class__.__name__, id(self))
248 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
249 for key, value in attrs:
250 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
251 res += "%s>" % indent
254 class CompilerDirectivesNode(Node):
256 Sets compiler directives for the children nodes
258 # directives {string:value} A dictionary holding the right value for
259 # *all* possible directives.
261 child_attrs = ["body"]
263 def analyse_control_flow(self, env):
265 env.directives = self.directives
266 self.body.analyse_control_flow(env)
269 def analyse_declarations(self, env):
271 env.directives = self.directives
272 self.body.analyse_declarations(env)
275 def analyse_expressions(self, env):
277 env.directives = self.directives
278 self.body.analyse_expressions(env)
281 def generate_function_definitions(self, env, code):
282 env_old = env.directives
283 code_old = code.globalstate.directives
284 code.globalstate.directives = self.directives
285 self.body.generate_function_definitions(env, code)
286 env.directives = env_old
287 code.globalstate.directives = code_old
289 def generate_execution_code(self, code):
290 old = code.globalstate.directives
291 code.globalstate.directives = self.directives
292 self.body.generate_execution_code(code)
293 code.globalstate.directives = old
295 def annotate(self, code):
296 old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.annotate(code)
299 code.globalstate.directives = old
301 class BlockNode(object):
302 # Mixin class for nodes representing a declaration block.
304 def generate_const_definitions(self, env, code):
305 if env.const_entries:
306 for entry in env.const_entries:
307 if not entry.is_interned:
308 code.globalstate.add_const_definition(entry)
310 def generate_interned_string_decls(self, env, code):
311 entries = env.global_scope().new_interned_string_entries
313 for entry in entries:
314 code.globalstate.add_interned_string_decl(entry)
317 def generate_py_string_decls(self, env, code):
319 return # earlier error
320 entries = env.pystring_entries
322 for entry in entries:
323 if not entry.is_interned:
324 code.globalstate.add_py_string_decl(entry)
326 def generate_interned_num_decls(self, env, code):
327 # Flush accumulated interned nums from the global scope
328 # and generate declarations for them.
329 genv = env.global_scope()
330 entries = genv.interned_nums
332 for entry in entries:
333 code.globalstate.add_interned_num_decl(entry)
336 def generate_cached_builtins_decls(self, env, code):
337 entries = env.global_scope().undeclared_cached_builtins
338 for entry in entries:
339 code.globalstate.add_cached_builtin_decl(entry)
343 class StatListNode(Node):
344 # stats a list of StatNode
346 child_attrs = ["stats"]
348 def create_analysed(pos, env, *args, **kw):
349 node = StatListNode(pos, *args, **kw)
350 return node # No node-specific analysis necesarry
351 create_analysed = staticmethod(create_analysed)
353 def analyse_control_flow(self, env):
354 for stat in self.stats:
355 stat.analyse_control_flow(env)
357 def analyse_declarations(self, env):
358 #print "StatListNode.analyse_declarations" ###
359 for stat in self.stats:
360 stat.analyse_declarations(env)
362 def analyse_expressions(self, env):
363 #print "StatListNode.analyse_expressions" ###
364 for stat in self.stats:
365 stat.analyse_expressions(env)
367 def generate_function_definitions(self, env, code):
368 #print "StatListNode.generate_function_definitions" ###
369 for stat in self.stats:
370 stat.generate_function_definitions(env, code)
372 def generate_execution_code(self, code):
373 #print "StatListNode.generate_execution_code" ###
374 for stat in self.stats:
375 code.mark_pos(stat.pos)
376 stat.generate_execution_code(code)
378 def annotate(self, code):
379 for stat in self.stats:
383 class StatNode(Node):
385 # Code generation for statements is split into the following subphases:
387 # (1) generate_function_definitions
388 # Emit C code for the definitions of any structs,
389 # unions, enums and functions defined in the current
392 # (2) generate_execution_code
393 # Emit C code for executable statements.
396 def generate_function_definitions(self, env, code):
399 def generate_execution_code(self, code):
400 raise InternalError("generate_execution_code not implemented for %s" % \
401 self.__class__.__name__)
404 class CDefExternNode(StatNode):
405 # include_file string or None
408 child_attrs = ["body"]
410 def analyse_declarations(self, env):
411 if self.include_file:
412 env.add_include_file(self.include_file)
413 old_cinclude_flag = env.in_cinclude
415 self.body.analyse_declarations(env)
416 env.in_cinclude = old_cinclude_flag
418 def analyse_expressions(self, env):
421 def generate_execution_code(self, code):
424 def annotate(self, code):
425 self.body.annotate(code)
428 class CDeclaratorNode(Node):
429 # Part of a C declaration.
431 # Processing during analyse_declarations phase:
434 # Returns (name, type) pair where name is the
435 # CNameDeclaratorNode of the name being declared
436 # and type is the type it is being declared as.
438 # calling_convention string Calling convention of CFuncDeclaratorNode
439 # for which this is a base
443 calling_convention = ""
446 class CNameDeclaratorNode(CDeclaratorNode):
447 # name string The Pyrex name being declared
448 # cname string or None C name, if specified
449 # default ExprNode or None the value assigned on declaration
451 child_attrs = ['default']
455 def analyse(self, base_type, env, nonempty = 0):
456 if nonempty and self.name == '':
457 # May have mistaken the name for the type.
458 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
459 error(self.pos, "Missing argument name")
460 elif base_type.is_void:
461 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
463 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
464 base_type = py_object_type
465 self.type = base_type
466 return self, base_type
468 class CPtrDeclaratorNode(CDeclaratorNode):
469 # base CDeclaratorNode
471 child_attrs = ["base"]
473 def analyse(self, base_type, env, nonempty = 0):
474 if base_type.is_pyobject:
476 "Pointer base type cannot be a Python object")
477 ptr_type = PyrexTypes.c_ptr_type(base_type)
478 return self.base.analyse(ptr_type, env, nonempty = nonempty)
480 class CArrayDeclaratorNode(CDeclaratorNode):
481 # base CDeclaratorNode
484 child_attrs = ["base", "dimension"]
486 def analyse(self, base_type, env, nonempty = 0):
488 self.dimension.analyse_const_expression(env)
489 if not self.dimension.type.is_int:
490 error(self.dimension.pos, "Array dimension not integer")
491 size = self.dimension.result()
499 if not base_type.is_complete():
501 "Array element type '%s' is incomplete" % base_type)
502 if base_type.is_pyobject:
504 "Array element cannot be a Python object")
505 if base_type.is_cfunction:
507 "Array element cannot be a function")
508 array_type = PyrexTypes.c_array_type(base_type, size)
509 return self.base.analyse(array_type, env, nonempty = nonempty)
512 class CFuncDeclaratorNode(CDeclaratorNode):
513 # base CDeclaratorNode
514 # args [CArgDeclNode]
515 # has_varargs boolean
516 # exception_value ConstNode
517 # exception_check boolean True if PyErr_Occurred check needed
518 # nogil boolean Can be called without gil
519 # with_gil boolean Acquire gil around function body
521 child_attrs = ["base", "args", "exception_value"]
524 optional_arg_count = 0
526 def analyse(self, return_type, env, nonempty = 0):
530 for arg_node in self.args:
531 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
532 name = name_declarator.name
533 if name_declarator.cname:
535 "Function argument cannot have C name specification")
536 # Turn *[] argument into **
538 type = PyrexTypes.c_ptr_type(type.base_type)
539 # Catch attempted C-style func(void) decl
541 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
542 # if type.is_pyobject and self.nogil:
544 # "Function with Python argument cannot be declared nogil")
545 func_type_args.append(
546 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
548 self.optional_arg_count += 1
549 elif self.optional_arg_count:
550 error(self.pos, "Non-default argument follows default argument")
552 if self.optional_arg_count:
553 scope = StructOrUnionScope()
554 scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
555 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
556 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
557 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
558 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
563 cname = struct_cname)
564 self.op_args_struct.defined_in_pxd = 1
565 self.op_args_struct.used = 1
569 if return_type.is_pyobject \
570 and (self.exception_value or self.exception_check) \
571 and self.exception_check != '+':
573 "Exception clause not allowed for function returning Python object")
575 if self.exception_value:
576 self.exception_value.analyse_const_expression(env)
577 if self.exception_check == '+':
578 exc_val_type = self.exception_value.type
579 if not exc_val_type.is_error and \
580 not exc_val_type.is_pyobject and \
581 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
582 error(self.exception_value.pos,
583 "Exception value must be a Python exception or cdef function with no arguments.")
584 exc_val = self.exception_value
586 exc_val = self.exception_value.result()
587 if not return_type.assignable_from(self.exception_value.type):
588 error(self.exception_value.pos,
589 "Exception value incompatible with function return type")
590 exc_check = self.exception_check
591 if return_type.is_array:
593 "Function cannot return an array")
594 if return_type.is_cfunction:
596 "Function cannot return a function")
597 func_type = PyrexTypes.CFuncType(
598 return_type, func_type_args, self.has_varargs,
599 optional_arg_count = self.optional_arg_count,
600 exception_value = exc_val, exception_check = exc_check,
601 calling_convention = self.base.calling_convention,
602 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
603 if self.optional_arg_count:
604 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
605 return self.base.analyse(func_type, env)
608 class CArgDeclNode(Node):
609 # Item in a function declaration argument list.
611 # base_type CBaseTypeNode
612 # declarator CDeclaratorNode
613 # not_none boolean Tagged with 'not None'
614 # default ExprNode or None
615 # default_entry Symtab.Entry Entry for the variable holding the default value
616 # default_result_code string cname or code fragment for default value
617 # is_self_arg boolean Is the "self" arg of an extension type method
618 # is_kw_only boolean Is a keyword-only argument
620 child_attrs = ["base_type", "declarator", "default"]
625 name_declarator = None
627 def analyse(self, env, nonempty = 0):
628 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
629 if self.type is None:
630 # The parser may missinterpret names as types...
632 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
634 self.declarator.name = self.base_type.name
635 self.base_type.name = None
636 self.base_type.is_basic_c_type = False
639 could_be_name = False
640 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
641 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
642 self.declarator.name = self.base_type.arg_name
643 return self.declarator.analyse(base_type, env, nonempty = nonempty)
645 return self.name_declarator, self.type
647 def annotate(self, code):
649 self.default.annotate(code)
652 class CBaseTypeNode(Node):
653 # Abstract base class for C base type nodes.
655 # Processing during analyse_declarations phase:
662 class CAnalysedBaseTypeNode(Node):
667 def analyse(self, env, could_be_name = False):
670 class CSimpleBaseTypeNode(CBaseTypeNode):
672 # module_path [string] Qualifying name components
673 # is_basic_c_type boolean
676 # is_self_arg boolean Is self argument of C method
679 arg_name = None # in case the argument name was interpreted as a type
681 def analyse(self, env, could_be_name = False):
682 # Return type descriptor.
683 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
685 if self.is_basic_c_type:
686 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
688 error(self.pos, "Unrecognised type modifier combination")
689 elif self.name == "object" and not self.module_path:
690 type = py_object_type
691 elif self.name is None:
692 if self.is_self_arg and env.is_c_class_scope:
693 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
694 type = env.parent_type
696 type = py_object_type
699 scope = env.find_imported_module(self.module_path, self.pos)
703 if scope.is_c_class_scope:
704 scope = scope.global_scope()
705 entry = scope.lookup(self.name)
706 if entry and entry.is_type:
709 if self.is_self_arg and env.is_c_class_scope:
710 type = env.parent_type
712 type = py_object_type
713 self.arg_name = self.name
715 error(self.pos, "'%s' is not a type identifier" % self.name)
719 return PyrexTypes.error_type
721 class CBufferAccessTypeNode(CBaseTypeNode):
723 # positional_args [ExprNode] List of positional arguments
724 # keyword_args DictNode Keyword arguments
725 # base_type_node CBaseTypeNode
728 # type PyrexType.BufferType ...containing the right options
731 child_attrs = ["base_type_node", "positional_args",
732 "keyword_args", "dtype_node"]
738 def analyse(self, env, could_be_name = False):
739 base_type = self.base_type_node.analyse(env)
740 if base_type.is_error: return base_type
743 options = Buffer.analyse_buffer_options(
746 self.positional_args,
748 base_type.buffer_defaults)
750 self.type = PyrexTypes.BufferType(base_type, **options)
753 class CComplexBaseTypeNode(CBaseTypeNode):
754 # base_type CBaseTypeNode
755 # declarator CDeclaratorNode
757 child_attrs = ["base_type", "declarator"]
759 def analyse(self, env, could_be_name = False):
760 base = self.base_type.analyse(env, could_be_name)
761 _, type = self.declarator.analyse(base, env)
765 class CVarDefNode(StatNode):
766 # C variable definition or forward/extern function declaration.
768 # visibility 'private' or 'public' or 'extern'
769 # base_type CBaseTypeNode
770 # declarators [CDeclaratorNode]
773 # need_properties [entry]
774 # pxd_locals [CVarDefNode] (used for functions declared in pxd)
776 child_attrs = ["base_type", "declarators"]
780 def analyse_declarations(self, env, dest_scope = None):
783 self.dest_scope = dest_scope
784 base_type = self.base_type.analyse(env)
785 if (dest_scope.is_c_class_scope
786 and self.visibility == 'public'
787 and base_type.is_pyobject
788 and (base_type.is_builtin_type or base_type.is_extension_type)):
789 self.need_properties = []
791 visibility = 'private'
793 need_property = False
794 visibility = self.visibility
796 for declarator in self.declarators:
797 name_declarator, type = declarator.analyse(base_type, env)
798 if not type.is_complete():
799 if not (self.visibility == 'extern' and type.is_array):
800 error(declarator.pos,
801 "Variable type '%s' is incomplete" % type)
802 if self.visibility == 'extern' and type.is_pyobject:
803 error(declarator.pos,
804 "Python object cannot be declared extern")
805 name = name_declarator.name
806 cname = name_declarator.cname
808 error(declarator.pos, "Missing name in declaration.")
810 if type.is_cfunction:
811 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
812 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
814 if entry is not None:
815 entry.pxd_locals = self.pxd_locals
817 if self.in_pxd and self.visibility != 'extern':
819 "Only 'extern' C variable declaration allowed in .pxd file")
820 entry = dest_scope.declare_var(name, type, declarator.pos,
821 cname = cname, visibility = visibility, is_cdef = 1)
823 self.need_properties.append(entry)
824 entry.needs_property = 1
827 class CStructOrUnionDefNode(StatNode):
829 # cname string or None
830 # kind "struct" or "union"
831 # typedef_flag boolean
832 # visibility "public" or "private"
834 # attributes [CVarDefNode] or None
837 child_attrs = ["attributes"]
839 def analyse_declarations(self, env):
841 if self.attributes is not None:
842 scope = StructOrUnionScope(self.name)
843 self.entry = env.declare_struct_or_union(
844 self.name, self.kind, scope, self.typedef_flag, self.pos,
845 self.cname, visibility = self.visibility)
846 if self.attributes is not None:
847 if self.in_pxd and not env.in_cinclude:
848 self.entry.defined_in_pxd = 1
849 for attr in self.attributes:
850 attr.analyse_declarations(env, scope)
851 if self.visibility != 'extern':
852 need_typedef_indirection = False
853 for attr in scope.var_entries:
856 type = type.base_type
857 if type == self.entry.type:
858 error(attr.pos, "Struct cannot contain itself as a member.")
859 if self.typedef_flag:
861 type = type.base_type
862 if type == self.entry.type:
863 need_typedef_indirection = True
864 if need_typedef_indirection:
865 # C can't handle typedef structs that refer to themselves.
866 struct_entry = self.entry
867 cname = env.new_const_cname()
868 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
869 struct_entry.type.typedef_flag = False
870 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
872 def analyse_expressions(self, env):
875 def generate_execution_code(self, code):
879 class CEnumDefNode(StatNode):
880 # name string or None
881 # cname string or None
882 # items [CEnumDefItemNode]
883 # typedef_flag boolean
884 # visibility "public" or "private"
888 child_attrs = ["items"]
890 def analyse_declarations(self, env):
891 self.entry = env.declare_enum(self.name, self.pos,
892 cname = self.cname, typedef_flag = self.typedef_flag,
893 visibility = self.visibility)
894 if self.items is not None:
895 if self.in_pxd and not env.in_cinclude:
896 self.entry.defined_in_pxd = 1
897 for item in self.items:
898 item.analyse_declarations(env, self.entry)
900 def analyse_expressions(self, env):
901 if self.visibility == 'public':
902 self.temp = env.allocate_temp_pyobject()
903 env.release_temp(self.temp)
905 def generate_execution_code(self, code):
906 if self.visibility == 'public':
907 for item in self.entry.enum_values:
908 code.putln("%s = PyInt_FromLong(%s); %s" % (
911 code.error_goto_if_null(self.temp, item.pos)))
912 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
916 code.error_goto(item.pos)))
917 code.putln("%s = 0;" % self.temp)
920 class CEnumDefItemNode(StatNode):
922 # cname string or None
923 # value ExprNode or None
925 child_attrs = ["value"]
927 def analyse_declarations(self, env, enum_entry):
929 self.value.analyse_const_expression(env)
930 if not self.value.type.is_int:
931 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
932 self.value.analyse_const_expression(env)
933 value = self.value.result()
936 entry = env.declare_const(self.name, enum_entry.type,
937 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
938 enum_entry.enum_values.append(entry)
941 class CTypeDefNode(StatNode):
942 # base_type CBaseTypeNode
943 # declarator CDeclaratorNode
944 # visibility "public" or "private"
947 child_attrs = ["base_type", "declarator"]
949 def analyse_declarations(self, env):
950 base = self.base_type.analyse(env)
951 name_declarator, type = self.declarator.analyse(base, env)
952 name = name_declarator.name
953 cname = name_declarator.cname
954 entry = env.declare_typedef(name, type, self.pos,
955 cname = cname, visibility = self.visibility)
956 if self.in_pxd and not env.in_cinclude:
957 entry.defined_in_pxd = 1
959 def analyse_expressions(self, env):
961 def generate_execution_code(self, code):
965 class FuncDefNode(StatNode, BlockNode):
966 # Base class for function definition nodes.
968 # return_type PyrexType
969 # #filename string C name of filename string const
971 # needs_closure boolean Whether or not this function has inner functions/classes/yield
972 # pxd_locals [CVarDefNode] locals defined in the pxd
976 needs_closure = False
979 def analyse_default_values(self, env):
980 genv = env.global_scope()
981 for arg in self.args:
984 if not hasattr(arg, 'default_entry'):
985 arg.default.analyse_types(env)
986 arg.default = arg.default.coerce_to(arg.type, genv)
987 if arg.default.is_literal:
988 arg.default_entry = arg.default
989 arg.default_result_code = arg.default.calculate_result_code()
990 if arg.default.type != arg.type and not arg.type.is_int:
991 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
993 arg.default.allocate_temps(genv)
994 arg.default_entry = genv.add_default_value(arg.type)
995 if arg.type.is_pyobject:
996 arg.default_entry.init = 0
997 arg.default_entry.used = 1
998 arg.default_result_code = arg.default_entry.cname
1001 "This argument cannot have a default value")
1004 def need_gil_acquisition(self, lenv):
1007 def create_local_scope(self, env):
1009 while env.is_py_class_scope or env.is_c_class_scope:
1010 env = env.outer_scope
1011 if self.needs_closure:
1012 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1014 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1015 lenv.return_type = self.return_type
1016 type = self.entry.type
1017 if type.is_cfunction:
1018 lenv.nogil = type.nogil and not type.with_gil
1019 self.local_scope = lenv
1022 def generate_function_definitions(self, env, code):
1025 lenv = self.local_scope
1027 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1028 self.entry.scope.is_c_class_scope)
1030 # Generate C code for header and body of function
1031 code.enter_cfunc_scope()
1032 code.return_from_error_cleanup_label = code.new_label()
1034 # ----- Top-level constants used by this function
1035 code.mark_pos(self.pos)
1036 self.generate_interned_num_decls(lenv, code)
1037 self.generate_interned_string_decls(lenv, code)
1038 self.generate_py_string_decls(lenv, code)
1039 self.generate_cached_builtins_decls(lenv, code)
1041 #code.put_var_declarations(lenv.const_entries, static = 1)
1042 self.generate_const_definitions(lenv, code)
1043 # ----- Function header
1046 self.py_func.generate_function_header(code,
1047 with_pymethdef = env.is_py_class_scope,
1049 self.generate_function_header(code,
1050 with_pymethdef = env.is_py_class_scope)
1051 # ----- Local variable declarations
1052 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1053 self.generate_argument_declarations(lenv, code)
1054 if self.needs_closure:
1055 code.putln("/* TODO: declare and create scope object */")
1056 code.put_var_declarations(lenv.var_entries)
1058 if not self.return_type.is_void:
1059 if self.return_type.is_pyobject:
1063 (self.return_type.declaration_code(
1064 Naming.retval_cname),
1066 tempvardecl_code = code.insertion_point()
1067 self.generate_keyword_list(code)
1068 # ----- Extern library function declarations
1069 lenv.generate_library_function_declarations(code)
1070 # ----- GIL acquisition
1071 acquire_gil = self.need_gil_acquisition(lenv)
1073 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1074 # ----- Automatic lead-ins for certain special functions
1076 code.put_setup_refcount_context(self.entry.name)
1077 if is_getbuffer_slot:
1078 self.getbuffer_init(code)
1079 # ----- Fetch arguments
1080 self.generate_argument_parsing_code(env, code)
1081 # If an argument is assigned to in the body, we must
1082 # incref it to properly keep track of refcounts.
1083 for entry in lenv.arg_entries:
1084 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1085 code.put_var_incref(entry)
1086 # ----- Initialise local variables
1087 for entry in lenv.var_entries:
1088 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1089 code.put_init_var_to_py_none(entry)
1090 # ----- Initialise local buffer auxiliary variables
1091 for entry in lenv.var_entries + lenv.arg_entries:
1092 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1093 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1094 # ----- Check and convert arguments
1095 self.generate_argument_type_tests(code)
1096 # ----- Acquire buffer arguments
1097 for entry in lenv.arg_entries:
1098 if entry.type.is_buffer:
1099 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1100 # ----- Function body
1101 self.body.generate_execution_code(code)
1102 # ----- Default return value
1104 if self.return_type.is_pyobject:
1105 #if self.return_type.is_extension_type:
1106 # lhs = "(PyObject *)%s" % Naming.retval_cname
1108 lhs = Naming.retval_cname
1109 code.put_init_to_py_none(lhs, self.return_type)
1111 val = self.return_type.default_value
1113 code.putln("%s = %s;" % (Naming.retval_cname, val))
1114 # ----- Error cleanup
1115 if code.error_label in code.labels_used:
1116 code.put_goto(code.return_label)
1117 code.put_label(code.error_label)
1118 # cleanup temps the old way
1119 code.put_var_xdecrefs(lenv.temp_entries)
1120 # cleanup temps the new way
1121 for cname, type in code.funcstate.all_managed_temps():
1122 code.put_xdecref(cname, type)
1124 # Clean up buffers -- this calls a Python function
1125 # so need to save and restore error state
1126 buffers_present = len(lenv.buffer_entries) > 0
1128 code.globalstate.use_utility_code(restore_exception_utility_code)
1129 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1130 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1131 for entry in lenv.buffer_entries:
1132 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1133 #code.putln("%s = 0;" % entry.cname)
1134 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1136 err_val = self.error_value()
1137 exc_check = self.caller_will_check_exceptions()
1138 if err_val is not None or exc_check:
1139 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1141 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1142 % self.entry.qualified_name, 0)
1144 '__Pyx_WriteUnraisable("%s");' %
1145 self.entry.qualified_name)
1146 env.use_utility_code(unraisable_exception_utility_code)
1147 env.use_utility_code(restore_exception_utility_code)
1148 default_retval = self.return_type.default_value
1149 if err_val is None and default_retval:
1150 err_val = default_retval
1151 if err_val is not None:
1154 Naming.retval_cname,
1157 if is_getbuffer_slot:
1158 self.getbuffer_error_cleanup(code)
1160 # If we are using the non-error cleanup section we should
1161 # jump past it if we have an error. The if-test below determine
1162 # whether this section is used.
1163 if buffers_present or is_getbuffer_slot:
1164 code.put_goto(code.return_from_error_cleanup_label)
1167 # ----- Non-error return cleanup
1168 # If you add anything here, remember to add a condition to the
1169 # if-test above in the error block (so that it can jump past this
1171 code.put_label(code.return_label)
1172 for entry in lenv.buffer_entries:
1174 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1175 if is_getbuffer_slot:
1176 self.getbuffer_normal_cleanup(code)
1177 # ----- Return cleanup for both error and no-error return
1178 code.put_label(code.return_from_error_cleanup_label)
1179 if not Options.init_local_none:
1180 for entry in lenv.var_entries:
1181 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1182 entry.xdecref_cleanup = 1
1183 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1184 # Decref any increfed args
1185 for entry in lenv.arg_entries:
1186 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1187 code.put_var_decref(entry)
1189 # code.putln("/* TODO: decref scope object */")
1191 # This code is duplicated in ModuleNode.generate_module_init_func
1193 default_retval = self.return_type.default_value
1194 err_val = self.error_value()
1195 if err_val is None and default_retval:
1196 err_val = default_retval
1197 if self.return_type.is_pyobject:
1198 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1200 code.put_finish_refcount_context()
1203 code.putln("PyGILState_Release(_save);")
1205 if not self.return_type.is_void:
1206 code.putln("return %s;" % Naming.retval_cname)
1209 # ----- Go back and insert temp variable declarations
1210 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1211 tempvardecl_code.put_temp_declarations(code.funcstate)
1212 # ----- Python version
1213 code.exit_cfunc_scope()
1215 self.py_func.generate_function_definitions(env, code)
1216 self.generate_wrapper_functions(code)
1218 def declare_argument(self, env, arg):
1219 if arg.type.is_void:
1220 error(arg.pos, "Invalid use of 'void'")
1221 elif not arg.type.is_complete() and not arg.type.is_array:
1223 "Argument type '%s' is incomplete" % arg.type)
1224 return env.declare_arg(arg.name, arg.type, arg.pos)
1226 def generate_wrapper_functions(self, code):
1229 def generate_execution_code(self, code):
1230 # Evaluate and store argument default values
1231 for arg in self.args:
1232 default = arg.default
1234 if not default.is_literal:
1235 default.generate_evaluation_code(code)
1236 default.make_owned_reference(code)
1237 if default.is_temp and default.type.is_pyobject:
1238 cleanup = " %s = 0;" % default.result()
1243 arg.default_entry.cname,
1244 default.result_as(arg.default_entry.type),
1246 code.put_giveref(arg.default_entry.cname)
1247 default.free_temps(code)
1248 # For Python class methods, create and store function object
1250 self.assmt.generate_execution_code(code)
1253 # Special code for the __getbuffer__ function
1255 def getbuffer_init(self, code):
1256 info = self.local_scope.arg_entries[1].cname
1257 # Python 3.0 betas have a bug in memoryview which makes it call
1258 # getbuffer with a NULL parameter. For now we work around this;
1259 # the following line should be removed when this bug is fixed.
1260 code.putln("if (%s == NULL) return 0;" % info)
1261 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1262 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1264 def getbuffer_error_cleanup(self, code):
1265 info = self.local_scope.arg_entries[1].cname
1266 code.put_gotref("%s->obj" % info)
1267 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1270 def getbuffer_normal_cleanup(self, code):
1271 info = self.local_scope.arg_entries[1].cname
1272 code.putln("if (%s->obj == Py_None) {" % info)
1273 code.put_gotref("Py_None")
1274 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1277 class CFuncDefNode(FuncDefNode):
1278 # C function definition.
1280 # modifiers ['inline']
1281 # visibility 'private' or 'public' or 'extern'
1282 # base_type CBaseTypeNode
1283 # declarator CDeclaratorNode
1287 # with_gil boolean Acquire GIL around body
1289 # py_func wrapper for calling from Python
1290 # overridable whether or not this is a cpdef function
1291 # inline_in_pxd whether this is an inline function in a pxd file
1293 child_attrs = ["base_type", "declarator", "body", "py_func"]
1295 inline_in_pxd = False
1297 def unqualified_name(self):
1298 return self.entry.name
1300 def analyse_declarations(self, env):
1301 if 'locals' in env.directives:
1302 directive_locals = env.directives['locals']
1304 directive_locals = {}
1305 self.directive_locals = directive_locals
1306 base_type = self.base_type.analyse(env)
1307 # The 2 here is because we need both function and argument names.
1308 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1309 if not type.is_cfunction:
1311 "Suite attached to non-function declaration")
1312 # Remember the actual type according to the function header
1313 # written here, because the type in the symbol table entry
1314 # may be different if we're overriding a C method inherited
1315 # from the base type of an extension type.
1317 type.is_overridable = self.overridable
1318 declarator = self.declarator
1319 while not hasattr(declarator, 'args'):
1320 declarator = declarator.base
1321 self.args = declarator.args
1322 for formal_arg, type_arg in zip(self.args, type.args):
1323 formal_arg.type = type_arg.type
1324 formal_arg.name = type_arg.name
1325 formal_arg.cname = type_arg.cname
1326 name = name_declarator.name
1327 cname = name_declarator.cname
1328 self.entry = env.declare_cfunction(
1329 name, type, self.pos,
1330 cname = cname, visibility = self.visibility,
1331 defining = self.body is not None,
1332 api = self.api, modifiers = self.modifiers)
1333 self.entry.inline_func_in_pxd = self.inline_in_pxd
1334 self.return_type = type.return_type
1336 if self.overridable:
1338 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1339 self.py_func = DefNode(pos = self.pos,
1340 name = self.entry.name,
1343 starstar_arg = None,
1345 body = py_func_body,
1347 self.py_func.is_module_scope = env.is_module_scope
1348 self.py_func.analyse_declarations(env)
1349 self.entry.as_variable = self.py_func.entry
1350 # Reset scope entry the above cfunction
1351 env.entries[name] = self.entry
1352 self.py_func.interned_attr_cname = env.intern_identifier(
1353 self.py_func.entry.name)
1354 if not env.is_module_scope or Options.lookup_module_cpdef:
1355 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1356 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1358 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1360 args = self.type.args
1361 if omit_optional_args:
1362 args = args[:len(args) - self.type.optional_arg_count]
1363 arg_names = [arg.name for arg in args]
1365 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1367 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1368 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1369 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1370 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)
1371 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1373 def declare_arguments(self, env):
1374 for arg in self.type.args:
1376 error(arg.pos, "Missing argument name")
1377 self.declare_argument(env, arg)
1379 def need_gil_acquisition(self, lenv):
1381 with_gil = self.type.with_gil
1382 if type.nogil and not with_gil:
1383 if type.return_type.is_pyobject:
1385 "Function with Python return type cannot be declared nogil")
1386 for entry in lenv.var_entries + lenv.temp_entries:
1387 if entry.type.is_pyobject:
1388 error(self.pos, "Function declared nogil has Python locals or temporaries")
1391 def analyse_expressions(self, env):
1392 self.analyse_default_values(env)
1393 if self.overridable:
1394 self.py_func.analyse_expressions(env)
1396 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1399 visibility = self.entry.visibility
1400 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1401 arg_decls.append(arg.declaration_code())
1402 if with_dispatch and self.overridable:
1403 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1404 if type.optional_arg_count and with_opt_args:
1405 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1406 if type.has_varargs:
1407 arg_decls.append("...")
1409 arg_decls = ["void"]
1411 cname = self.entry.func_cname
1412 entity = type.function_header_code(cname, string.join(arg_decls, ", "))
1413 if visibility == 'public':
1414 dll_linkage = "DL_EXPORT"
1417 header = self.return_type.declaration_code(entity,
1418 dll_linkage = dll_linkage)
1419 if visibility == 'extern':
1420 storage_class = "%s " % Naming.extern_c_macro
1421 elif visibility == 'public':
1424 storage_class = "static "
1425 code.putln("%s%s %s {" % (
1427 ' '.join(self.modifiers).upper(), # macro forms
1430 def generate_argument_declarations(self, env, code):
1431 for arg in self.args:
1433 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1435 def generate_keyword_list(self, code):
1438 def generate_argument_parsing_code(self, env, code):
1440 if self.type.optional_arg_count:
1441 code.putln('if (%s) {' % Naming.optional_args_cname)
1442 for arg in self.args:
1444 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1445 declarator = arg.declarator
1446 while not hasattr(declarator, 'name'):
1447 declarator = declarator.base
1448 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1450 for _ in range(self.type.optional_arg_count):
1454 def generate_argument_conversion_code(self, code):
1457 def generate_argument_type_tests(self, code):
1458 # Generate type tests for args whose type in a parent
1459 # class is a supertype of the declared type.
1460 for arg in self.type.args:
1461 if arg.needs_type_test:
1462 self.generate_arg_type_test(arg, code)
1464 def generate_arg_type_test(self, arg, code):
1465 # Generate type test for one argument.
1466 if arg.type.typeobj_is_available():
1467 typeptr_cname = arg.type.typeptr_cname
1468 arg_code = "((PyObject *)%s)" % arg.cname
1470 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1475 type.is_builtin_type,
1476 code.error_goto(arg.pos)))
1478 error(arg.pos, "Cannot test type of extern C class "
1479 "without type object name specification")
1481 def error_value(self):
1482 if self.return_type.is_pyobject:
1486 return self.entry.type.exception_value
1488 def caller_will_check_exceptions(self):
1489 return self.entry.type.exception_check
1491 def generate_wrapper_functions(self, code):
1492 # If the C signature of a function has changed, we need to generate
1493 # wrappers to put in the slots here.
1496 func_type = entry.type
1497 while entry.prev_entry is not None:
1499 entry = entry.prev_entry
1500 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1502 self.generate_function_header(code,
1504 with_dispatch = entry.type.is_overridable,
1505 with_opt_args = entry.type.optional_arg_count,
1506 cname = entry.func_cname)
1507 if not self.return_type.is_void:
1509 args = self.type.args
1510 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1511 if entry.type.is_overridable:
1512 arglist.append(Naming.skip_dispatch_cname)
1513 elif func_type.is_overridable:
1515 if entry.type.optional_arg_count:
1516 arglist.append(Naming.optional_args_cname)
1517 elif func_type.optional_arg_count:
1518 arglist.append('NULL')
1519 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1523 class PyArgDeclNode(Node):
1524 # Argument which must be a Python object (used
1525 # for * and ** arguments).
1528 # entry Symtab.Entry
1532 class DecoratorNode(Node):
1535 # decorator NameNode or CallNode
1536 child_attrs = ['decorator']
1539 class DefNode(FuncDefNode):
1540 # A Python function definition.
1542 # name string the Python name of the function
1543 # decorators [DecoratorNode] list of decorators
1544 # args [CArgDeclNode] formal arguments
1545 # star_arg PyArgDeclNode or None * argument
1546 # starstar_arg PyArgDeclNode or None ** argument
1547 # doc EncodedString or None
1550 # The following subnode is constructed internally
1551 # when the def statement is inside a Python class definition.
1553 # assmt AssignmentNode Function construction/assignment
1555 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1559 num_required_kw_args = 0
1560 reqd_kw_flags_cname = "0"
1566 def __init__(self, pos, **kwds):
1567 FuncDefNode.__init__(self, pos, **kwds)
1569 for arg in self.args:
1576 self.num_kwonly_args = k
1577 self.num_required_kw_args = rk
1578 self.num_required_args = r
1580 def as_cfunction(self, cfunc=None, scope=None):
1582 error(self.star_arg.pos, "cdef function cannot have star argument")
1583 if self.starstar_arg:
1584 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1587 for formal_arg in self.args:
1588 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1589 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1591 type = py_object_type,
1592 pos = formal_arg.pos))
1593 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1595 has_varargs = False,
1596 exception_value = None,
1597 exception_check = False,
1600 is_overridable = True)
1601 cfunc = CVarDefNode(self.pos, type=cfunc_type, pxd_locals=[])
1603 cfunc_type = cfunc.type
1604 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1605 error(self.pos, "wrong number of arguments")
1606 error(declarator.pos, "previous declaration here")
1607 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1608 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1609 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1610 formal_arg.type = type_arg.type
1611 formal_arg.name_declarator = name_declarator
1613 if cfunc_type.exception_value is None:
1614 exception_value = None
1616 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1617 declarator = CFuncDeclaratorNode(self.pos,
1618 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1620 has_varargs = False,
1621 exception_check = cfunc_type.exception_check,
1622 exception_value = exception_value,
1623 with_gil = cfunc_type.with_gil,
1624 nogil = cfunc_type.nogil)
1625 return CFuncDefNode(self.pos,
1627 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1628 declarator = declarator,
1631 overridable = cfunc_type.is_overridable,
1633 with_gil = cfunc_type.with_gil,
1634 nogil = cfunc_type.nogil,
1635 visibility = 'private',
1637 pxd_locals = cfunc.pxd_locals)
1639 def analyse_declarations(self, env):
1640 if 'locals' in env.directives:
1641 directive_locals = env.directives['locals']
1643 directive_locals = {}
1644 self.directive_locals = directive_locals
1645 for arg in self.args:
1646 if hasattr(arg, 'name'):
1648 name_declarator = None
1650 base_type = arg.base_type.analyse(env)
1651 name_declarator, type = \
1652 arg.declarator.analyse(base_type, env)
1653 arg.name = name_declarator.name
1654 if arg.name in directive_locals:
1655 type_node = directive_locals[arg.name]
1656 other_type = type_node.analyse_as_type(env)
1657 if other_type is None:
1658 error(type_node.pos, "Not a type")
1659 elif (type is not PyrexTypes.py_object_type
1660 and not type.same_as(other_type)):
1661 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1662 error(type_node.pos, "Previous declaration here")
1665 if name_declarator and name_declarator.cname:
1667 "Python function argument cannot have C name specification")
1668 arg.type = type.as_argument_type()
1670 arg.needs_conversion = 0
1671 arg.needs_type_test = 0
1673 if arg.not_none and not arg.type.is_extension_type:
1675 "Only extension type arguments can have 'not None'")
1676 self.declare_pyfunction(env)
1677 self.analyse_signature(env)
1678 self.return_type = self.entry.signature.return_type()
1680 def analyse_signature(self, env):
1681 any_type_tests_needed = 0
1682 # Use the simpler calling signature for zero- and one-argument functions.
1683 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1684 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1685 if len(self.args) == 0:
1686 self.entry.signature = TypeSlots.pyfunction_noargs
1687 elif len(self.args) == 1:
1688 if self.args[0].default is None and not self.args[0].kw_only:
1689 self.entry.signature = TypeSlots.pyfunction_onearg
1690 elif self.entry.signature is TypeSlots.pymethod_signature:
1691 if len(self.args) == 1:
1692 self.entry.signature = TypeSlots.unaryfunc
1693 elif len(self.args) == 2:
1694 if self.args[1].default is None and not self.args[1].kw_only:
1695 self.entry.signature = TypeSlots.ibinaryfunc
1696 elif self.entry.is_special:
1697 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1698 sig = self.entry.signature
1699 nfixed = sig.num_fixed_args()
1700 for i in range(nfixed):
1701 if i < len(self.args):
1704 if sig.is_self_arg(i):
1706 arg.hdr_type = arg.type = env.parent_type
1707 arg.needs_conversion = 0
1709 arg.hdr_type = sig.fixed_arg_type(i)
1710 if not arg.type.same_as(arg.hdr_type):
1711 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1712 arg.needs_type_test = 1
1713 any_type_tests_needed = 1
1715 arg.needs_conversion = 1
1716 if arg.needs_conversion:
1717 arg.hdr_cname = Naming.arg_prefix + arg.name
1719 arg.hdr_cname = Naming.var_prefix + arg.name
1721 self.bad_signature()
1723 if nfixed < len(self.args):
1724 if not sig.has_generic_args:
1725 self.bad_signature()
1726 for arg in self.args:
1727 if arg.is_generic and \
1728 (arg.type.is_extension_type or arg.type.is_builtin_type):
1729 arg.needs_type_test = 1
1730 any_type_tests_needed = 1
1731 elif (arg.type is PyrexTypes.c_py_ssize_t_type
1732 or arg.type is PyrexTypes.c_size_t_type):
1733 # Don't use PyArg_ParseTupleAndKeywords's parsing
1734 # Py_ssize_t: want to use __index__ rather than __int__
1735 # size_t: no Python format char
1736 arg.needs_conversion = 1
1737 arg.hdr_type = PyrexTypes.py_object_type
1738 arg.hdr_cname = Naming.arg_prefix + arg.name
1739 if any_type_tests_needed:
1740 env.use_utility_code(arg_type_test_utility_code)
1742 def bad_signature(self):
1743 sig = self.entry.signature
1744 expected_str = "%d" % sig.num_fixed_args()
1745 if sig.has_generic_args:
1746 expected_str = expected_str + " or more"
1748 if name.startswith("__") and name.endswith("__"):
1749 desc = "Special method"
1753 "%s %s has wrong number of arguments "
1754 "(%d declared, %s expected)" % (
1755 desc, self.name, len(self.args), expected_str))
1757 def signature_has_nongeneric_args(self):
1758 argcount = len(self.args)
1759 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1763 def signature_has_generic_args(self):
1764 return self.entry.signature.has_generic_args
1766 def declare_pyfunction(self, env):
1767 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1769 entry = env.lookup_here(self.name)
1770 if entry and entry.type.is_cfunction and not self.is_wrapper:
1771 warning(self.pos, "Overriding cdef method with def method.", 5)
1772 entry = env.declare_pyfunction(self.name, self.pos)
1774 prefix = env.scope_prefix
1775 entry.func_cname = \
1776 Naming.pyfunc_prefix + prefix + name
1777 entry.pymethdef_cname = \
1778 Naming.pymethdef_prefix + prefix + name
1779 if Options.docstrings:
1780 entry.doc = embed_position(self.pos, self.doc)
1782 Naming.funcdoc_prefix + prefix + name
1786 def declare_arguments(self, env):
1787 for arg in self.args:
1789 error(arg.pos, "Missing argument name")
1790 if arg.needs_conversion:
1791 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1792 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1793 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1794 if arg.type.is_pyobject:
1795 arg.entry.init = "0"
1796 arg.entry.init_to_none = 0
1798 arg.entry = self.declare_argument(env, arg)
1800 arg.entry.is_self_arg = arg.is_self_arg
1801 if not arg.is_self_arg:
1802 arg.name_entry = env.get_string_const(
1803 arg.name, identifier = True)
1804 env.add_py_string(arg.name_entry, identifier = True)
1806 if arg.is_self_arg or \
1807 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1808 arg.entry.is_declared_generic = 1
1809 self.declare_python_arg(env, self.star_arg)
1810 self.declare_python_arg(env, self.starstar_arg)
1812 def declare_python_arg(self, env, arg):
1814 entry = env.declare_var(arg.name,
1815 PyrexTypes.py_object_type, arg.pos)
1818 entry.init_to_none = 0
1819 entry.xdecref_cleanup = 1
1821 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1823 def analyse_expressions(self, env):
1824 self.analyse_default_values(env)
1825 if env.is_py_class_scope:
1826 self.synthesize_assignment_node(env)
1828 def synthesize_assignment_node(self, env):
1830 self.assmt = SingleAssignmentNode(self.pos,
1831 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1832 rhs = ExprNodes.UnboundMethodNode(self.pos,
1833 class_cname = env.class_obj_cname,
1834 function = ExprNodes.PyCFunctionNode(self.pos,
1835 pymethdef_cname = self.entry.pymethdef_cname)))
1836 self.assmt.analyse_declarations(env)
1837 self.assmt.analyse_expressions(env)
1839 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1841 sig = self.entry.signature
1842 if sig.has_dummy_arg:
1843 arg_code_list.append(
1844 "PyObject *%s" % Naming.self_cname)
1845 for arg in self.args:
1846 if not arg.is_generic:
1848 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1850 arg_code_list.append(
1851 arg.hdr_type.declaration_code(arg.hdr_cname))
1852 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1853 arg_code_list.append("PyObject *unused")
1854 if sig.has_generic_args:
1855 arg_code_list.append(
1856 "PyObject *%s, PyObject *%s"
1857 % (Naming.args_cname, Naming.kwds_cname))
1858 arg_code = ", ".join(arg_code_list)
1859 dc = self.return_type.declaration_code(self.entry.func_cname)
1860 header = "static %s(%s)" % (dc, arg_code)
1861 code.putln("%s; /*proto*/" % header)
1864 if self.entry.doc and Options.docstrings:
1865 docstr = self.entry.doc
1866 if not isinstance(docstr, str):
1867 docstr = docstr.utf8encode()
1869 'static char %s[] = "%s";' % (
1870 self.entry.doc_cname,
1871 split_docstring(escape_byte_string(docstr))))
1874 "static PyMethodDef %s = " %
1875 self.entry.pymethdef_cname)
1876 code.put_pymethoddef(self.entry, ";")
1877 code.putln("%s {" % header)
1879 def generate_argument_declarations(self, env, code):
1880 for arg in self.args:
1881 if arg.is_generic: # or arg.needs_conversion:
1882 if arg.needs_conversion:
1883 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1885 code.put_var_declaration(arg.entry)
1887 def generate_keyword_list(self, code):
1888 if self.signature_has_generic_args() and \
1889 self.signature_has_nongeneric_args():
1891 "static PyObject **%s[] = {" %
1892 Naming.pykwdlist_cname)
1893 for arg in self.args:
1895 code.put('&%s,' % arg.name_entry.pystring_cname)
1898 def generate_argument_parsing_code(self, env, code):
1899 # Generate PyArg_ParseTuple call for generic
1900 # arguments, if any.
1901 if self.entry.signature.has_dummy_arg:
1902 # get rid of unused argument warning
1903 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1905 old_error_label = code.new_error_label()
1906 our_error_label = code.error_label
1907 end_label = code.new_label("argument_unpacking_done")
1909 has_kwonly_args = self.num_kwonly_args > 0
1910 has_star_or_kw_args = self.star_arg is not None \
1911 or self.starstar_arg is not None or has_kwonly_args
1913 if not self.signature_has_generic_args():
1914 if has_star_or_kw_args:
1915 error(self.pos, "This method cannot have * or keyword arguments")
1916 self.generate_argument_conversion_code(code)
1918 elif not self.signature_has_nongeneric_args():
1919 # func(*args) or func(**kw) or func(*args, **kw)
1920 self.generate_stararg_copy_code(code)
1923 positional_args = []
1926 for arg in self.args:
1927 arg_entry = arg.entry
1931 if not arg.is_self_arg:
1933 kw_only_args.append(arg)
1935 positional_args.append(arg)
1937 kw_only_args.append(arg)
1940 error(arg.pos, "Non-default argument following default argument")
1941 elif not arg.is_self_arg:
1942 positional_args.append(arg)
1943 if arg.needs_conversion:
1944 format = arg.hdr_type.parsetuple_format
1946 format = arg_entry.type.parsetuple_format
1949 "Cannot convert Python object argument to type '%s' (when parsing input arguments)"
1952 self.generate_tuple_and_keyword_parsing_code(
1953 positional_args, kw_only_args, end_label, code)
1955 code.error_label = old_error_label
1956 if code.label_used(our_error_label):
1957 if not code.label_used(end_label):
1958 code.put_goto(end_label)
1959 code.put_label(our_error_label)
1960 if has_star_or_kw_args:
1961 self.generate_arg_decref(self.star_arg, code)
1962 if self.starstar_arg:
1963 if self.starstar_arg.entry.xdecref_cleanup:
1964 code.put_var_xdecref(self.starstar_arg.entry)
1966 code.put_var_decref(self.starstar_arg.entry)
1967 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1968 code.putln("return %s;" % self.error_value())
1969 if code.label_used(end_label):
1970 code.put_label(end_label)
1972 def generate_arg_assignment(self, arg, item, code):
1973 if arg.type.is_pyobject:
1975 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1976 code.putln("%s = %s;" % (arg.entry.cname, item))
1978 func = arg.type.from_py_function
1980 code.putln("%s = %s(%s); %s" % (
1984 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1986 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1988 def generate_arg_xdecref(self, arg, code):
1990 code.put_var_xdecref(arg.entry)
1992 def generate_arg_decref(self, arg, code):
1994 code.put_var_decref(arg.entry)
1996 def generate_stararg_copy_code(self, code):
1997 if not self.star_arg:
1998 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1999 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2001 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2002 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2005 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2007 if self.starstar_arg:
2009 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2011 kwarg_check = "%s" % Naming.kwds_cname
2013 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2014 Naming.kwds_cname, Naming.kwds_cname)
2016 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2017 kwarg_check, Naming.kwds_cname, self.name,
2018 bool(self.starstar_arg), self.error_value()))
2020 if self.starstar_arg:
2021 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2022 self.starstar_arg.entry.cname,
2025 code.putln("if (unlikely(!%s)) return %s;" % (
2026 self.starstar_arg.entry.cname, self.error_value()))
2027 self.starstar_arg.entry.xdecref_cleanup = 0
2028 code.put_gotref(self.starstar_arg.entry.cname)
2032 code.put_incref(Naming.args_cname, py_object_type)
2033 code.putln("%s = %s;" % (
2034 self.star_arg.entry.cname,
2036 self.star_arg.entry.xdecref_cleanup = 0
2038 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2039 kw_only_args, success_label, code):
2040 argtuple_error_label = code.new_label("argtuple_error")
2042 min_positional_args = self.num_required_args - self.num_required_kw_args
2043 if len(self.args) > 0 and self.args[0].is_self_arg:
2044 min_positional_args -= 1
2045 max_positional_args = len(positional_args)
2046 has_fixed_positional_count = not self.star_arg and \
2047 min_positional_args == max_positional_args
2049 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2050 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2051 if self.num_required_kw_args:
2052 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2054 if self.starstar_arg or self.star_arg:
2055 self.generate_stararg_init_code(max_positional_args, code)
2057 # --- optimised code when we receive keyword arguments
2058 if self.num_required_kw_args:
2059 likely_hint = "likely"
2061 likely_hint = "unlikely"
2062 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2063 self.generate_keyword_unpacking_code(
2064 min_positional_args, max_positional_args,
2065 has_fixed_positional_count,
2066 positional_args, kw_only_args, argtuple_error_label, code)
2068 # --- optimised code when we do not receive any keyword arguments
2069 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2070 # Python raises arg tuple related errors first, so we must
2071 # check the length here
2072 if min_positional_args == max_positional_args and not self.star_arg:
2076 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2077 Naming.args_cname, compare, min_positional_args))
2078 code.put_goto(argtuple_error_label)
2080 if self.num_required_kw_args:
2081 # pure error case: keywords required but not passed
2082 if max_positional_args > min_positional_args and not self.star_arg:
2083 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2084 Naming.args_cname, max_positional_args))
2085 code.put_goto(argtuple_error_label)
2086 code.putln('} else {')
2087 for i, arg in enumerate(kw_only_args):
2089 # required keyword-only argument missing
2090 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2091 self.name.utf8encode(),
2092 arg.name_entry.pystring_cname))
2093 code.putln(code.error_goto(self.pos))
2096 elif min_positional_args == max_positional_args:
2097 # parse the exact number of positional arguments from the
2099 code.putln('} else {')
2100 for i, arg in enumerate(positional_args):
2101 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2102 self.generate_arg_assignment(arg, item, code)
2103 self.generate_arg_default_assignments(code)
2106 # parse the positional arguments from the variable length
2108 code.putln('} else {')
2109 self.generate_arg_default_assignments(code)
2110 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2112 code.putln('default:')
2113 reversed_args = list(enumerate(positional_args))[::-1]
2114 for i, arg in reversed_args:
2115 if i >= min_positional_args-1:
2116 if min_positional_args > 1:
2117 code.putln('case %2d:' % (i+1)) # pure code beautification
2119 code.put('case %2d: ' % (i+1))
2120 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2121 self.generate_arg_assignment(arg, item, code)
2122 if min_positional_args == 0:
2123 code.put('case 0: ')
2124 code.putln('break;')
2126 if min_positional_args:
2127 for i in range(min_positional_args-1, -1, -1):
2128 code.putln('case %2d:' % i)
2129 code.put_goto(argtuple_error_label)
2131 code.put('default: ')
2132 code.put_goto(argtuple_error_label)
2137 if code.label_used(argtuple_error_label):
2138 code.put_goto(success_label)
2139 code.put_label(argtuple_error_label)
2140 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2141 self.name.utf8encode(), has_fixed_positional_count,
2142 min_positional_args, max_positional_args,
2144 code.putln(code.error_goto(self.pos))
2146 def generate_arg_default_assignments(self, code):
2147 for arg in self.args:
2148 if arg.is_generic and arg.default:
2152 arg.default_result_code))
2154 def generate_stararg_init_code(self, max_positional_args, code):
2155 if self.starstar_arg:
2156 self.starstar_arg.entry.xdecref_cleanup = 0
2157 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2158 self.starstar_arg.entry.cname,
2159 self.starstar_arg.entry.cname,
2160 self.error_value()))
2161 code.put_gotref(self.starstar_arg.entry.cname)
2163 self.star_arg.entry.xdecref_cleanup = 0
2164 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2166 max_positional_args))
2167 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2168 self.star_arg.entry.cname, Naming.args_cname,
2169 max_positional_args, Naming.args_cname))
2170 code.put_gotref(self.star_arg.entry.cname)
2171 if self.starstar_arg:
2173 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2174 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2175 code.putln('return %s;' % self.error_value())
2178 code.putln("if (unlikely(!%s)) return %s;" % (
2179 self.star_arg.entry.cname, self.error_value()))
2180 code.putln('} else {')
2181 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2182 code.put_incref(Naming.empty_tuple, py_object_type)
2185 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2186 has_fixed_positional_count, positional_args,
2187 kw_only_args, argtuple_error_label, code):
2188 all_args = tuple(positional_args) + tuple(kw_only_args)
2189 max_args = len(all_args)
2192 for arg in all_args:
2193 if arg.default and arg.type.is_pyobject:
2194 default_value = arg.default_result_code
2195 if arg.type is not PyrexTypes.py_object_type:
2196 default_value = "(PyObject*)"+default_value
2197 default_args.append(default_value)
2199 default_args.append('0')
2200 code.putln("PyObject* values[%d] = {%s};" % (
2201 max_args, ', '.join(default_args)))
2202 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2205 # parse the tuple and check that it's not too long
2206 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2208 code.putln('default:')
2209 for i in range(max_positional_args-1, -1, -1):
2210 code.put('case %2d: ' % (i+1))
2211 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2212 i, Naming.args_cname, i))
2213 code.putln('case 0: break;')
2214 if not self.star_arg:
2215 code.put('default: ') # more arguments than allowed
2216 code.put_goto(argtuple_error_label)
2219 # now fill up the required arguments with values from the kw dict
2220 if self.num_required_args:
2221 last_required_arg = -1
2222 for i, arg in enumerate(all_args):
2224 last_required_arg = i
2225 if max_positional_args > 0:
2226 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2227 for i, arg in enumerate(all_args[:last_required_arg+1]):
2228 if max_positional_args > 0 and i <= max_positional_args:
2229 if self.star_arg and i == max_positional_args:
2230 code.putln('default:')
2232 code.putln('case %2d:' % i)
2234 # handled in ParseOptionalKeywords() below
2236 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2237 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2238 code.putln('if (likely(values[%d])) kw_args--;' % i);
2239 if i < min_positional_args:
2241 # special case: we know arg 0 is missing
2243 code.put_goto(argtuple_error_label)
2245 # print the correct number of values (args or
2246 # kwargs) that were passed into positional
2247 # arguments up to this point
2248 code.putln('else {')
2249 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2250 self.name.utf8encode(), has_fixed_positional_count,
2251 min_positional_args, max_positional_args, i))
2252 code.putln(code.error_goto(self.pos))
2255 code.putln('else {')
2256 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2257 self.name.utf8encode(), arg.name_entry.pystring_cname))
2258 code.putln(code.error_goto(self.pos))
2260 if max_positional_args > 0:
2263 code.putln('if (unlikely(kw_args > 0)) {')
2264 # non-positional/-required kw args left in dict: default args, **kwargs or error
2265 if max_positional_args == 0:
2268 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2269 Naming.args_cname, max_positional_args,
2270 Naming.args_cname, max_positional_args))
2271 pos_arg_count = "used_pos_args"
2273 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2274 code.globalstate.use_utility_code(parse_keywords_utility_code)
2276 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2278 Naming.pykwdlist_cname,
2279 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2281 self.name.utf8encode()))
2282 code.putln(code.error_goto(self.pos))
2285 # convert arg values to their final type and assign them
2286 for i, arg in enumerate(all_args):
2287 if arg.default and not arg.type.is_pyobject:
2288 code.putln("if (values[%d]) {" % i)
2289 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2290 if arg.default and not arg.type.is_pyobject:
2291 code.putln('} else {')
2295 arg.default_result_code))
2298 def generate_argument_conversion_code(self, code):
2299 # Generate code to convert arguments from
2300 # signature type to declared type, if needed.
2301 for arg in self.args:
2302 if arg.needs_conversion:
2303 self.generate_arg_conversion(arg, code)
2305 def generate_arg_conversion(self, arg, code):
2306 # Generate conversion code for one argument.
2307 old_type = arg.hdr_type
2309 if old_type.is_pyobject:
2311 code.putln("if (%s) {" % arg.hdr_cname)
2313 code.putln("assert(%s); {" % arg.hdr_cname)
2314 self.generate_arg_conversion_from_pyobject(arg, code)
2316 elif new_type.is_pyobject:
2317 self.generate_arg_conversion_to_pyobject(arg, code)
2319 if new_type.assignable_from(old_type):
2321 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2324 "Cannot convert 1 argument from '%s' to '%s'" %
2325 (old_type, new_type))
2327 def generate_arg_conversion_from_pyobject(self, arg, code):
2329 func = new_type.from_py_function
2330 # copied from CoerceFromPyTypeNode
2332 code.putln("%s = %s(%s); %s" % (
2336 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2339 "Cannot convert Python object argument to type '%s'"
2342 def generate_arg_conversion_to_pyobject(self, arg, code):
2343 old_type = arg.hdr_type
2344 func = old_type.to_py_function
2346 code.putln("%s = %s(%s); %s" % (
2350 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2351 code.put_var_gotref(arg.entry)
2354 "Cannot convert argument of type '%s' to Python object"
2357 def generate_argument_type_tests(self, code):
2358 # Generate type tests for args whose signature
2359 # type is PyObject * and whose declared type is
2360 # a subtype thereof.
2361 for arg in self.args:
2362 if arg.needs_type_test:
2363 self.generate_arg_type_test(arg, code)
2365 def generate_arg_type_test(self, arg, code):
2366 # Generate type test for one argument.
2367 if arg.type.typeobj_is_available():
2368 typeptr_cname = arg.type.typeptr_cname
2369 arg_code = "((PyObject *)%s)" % arg.entry.cname
2371 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2376 arg.type.is_builtin_type,
2377 code.error_goto(arg.pos)))
2379 error(arg.pos, "Cannot test type of extern C class "
2380 "without type object name specification")
2382 def error_value(self):
2383 return self.entry.signature.error_value
2385 def caller_will_check_exceptions(self):
2388 class OverrideCheckNode(StatNode):
2389 # A Node for dispatching to the def method if it
2398 child_attrs = ['body']
2402 def analyse_expressions(self, env):
2403 self.args = env.arg_entries
2404 if self.py_func.is_module_scope:
2409 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2410 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2411 call_node = ExprNodes.SimpleCallNode(self.pos,
2412 function=self.func_node,
2413 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2414 self.body = ReturnStatNode(self.pos, value=call_node)
2415 self.body.analyse_expressions(env)
2417 def generate_execution_code(self, code):
2418 # Check to see if we are an extension type
2419 if self.py_func.is_module_scope:
2420 self_arg = "((PyObject *)%s)" % Naming.module_cname
2422 self_arg = "((PyObject *)%s)" % self.args[0].cname
2423 code.putln("/* Check if called by wrapper */")
2424 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2425 code.putln("/* Check if overriden in Python */")
2426 if self.py_func.is_module_scope:
2427 code.putln("else {")
2429 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2430 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2431 # need to get attribute manually--scope would return cdef method
2432 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2433 code.put_gotref(self.func_node.py_result())
2434 # It appears that this type is not anywhere exposed in the Python/C API
2435 is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result()
2436 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2437 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2438 self.body.generate_execution_code(code)
2440 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2443 class ClassDefNode(StatNode, BlockNode):
2446 class PyClassDefNode(ClassDefNode):
2447 # A Python class definition.
2449 # name EncodedString Name of the class
2450 # doc string or None
2451 # body StatNode Attribute definition code
2452 # entry Symtab.Entry
2453 # scope PyClassScope
2455 # The following subnodes are constructed internally:
2457 # dict DictNode Class dictionary
2458 # classobj ClassNode Class object
2459 # target NameNode Variable to assign class object to
2461 child_attrs = ["body", "dict", "classobj", "target"]
2463 def __init__(self, pos, name, bases, doc, body):
2464 StatNode.__init__(self, pos)
2469 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2470 if self.doc and Options.docstrings:
2471 doc = embed_position(self.pos, self.doc)
2472 doc_node = ExprNodes.StringNode(pos, value = doc)
2475 self.classobj = ExprNodes.ClassNode(pos, name = name,
2476 bases = bases, dict = self.dict, doc = doc_node)
2477 self.target = ExprNodes.NameNode(pos, name = name)
2479 def as_cclass(self):
2481 Return this node as if it were declared as an extension class
2483 bases = self.classobj.bases.args
2485 base_class_name = None
2486 base_class_module = None
2487 elif len(bases) == 1:
2490 from ExprNodes import AttributeNode, NameNode
2491 while isinstance(base, AttributeNode):
2492 path.insert(0, base.attribute)
2494 if isinstance(base, NameNode):
2495 path.insert(0, base.name)
2496 base_class_name = path[-1]
2498 base_class_module = u'.'.join(path[:-1])
2500 base_class_module = None
2502 error(self.classobj.bases.args.pos, "Invalid base class")
2504 error(self.classobj.bases.args.pos, "C class may only have one base class")
2507 return CClassDefNode(self.pos,
2508 visibility = 'private',
2510 class_name = self.name,
2511 base_class_module = base_class_module,
2512 base_class_name = base_class_name,
2517 def create_scope(self, env):
2519 while env.is_py_class_scope or env.is_c_class_scope:
2520 env = env.outer_scope
2521 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2524 def analyse_declarations(self, env):
2525 self.target.analyse_target_declaration(env)
2526 cenv = self.create_scope(env)
2527 cenv.class_obj_cname = self.target.entry.cname
2528 self.body.analyse_declarations(cenv)
2530 def analyse_expressions(self, env):
2531 self.dict.analyse_expressions(env)
2532 self.classobj.analyse_expressions(env)
2533 genv = env.global_scope()
2535 cenv.class_dict_cname = self.dict.result()
2536 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2537 self.body.analyse_expressions(cenv)
2538 self.target.analyse_target_expression(env, self.classobj)
2539 self.dict.release_temp(env)
2540 #self.classobj.release_temp(env)
2541 #self.target.release_target_temp(env)
2543 def generate_function_definitions(self, env, code):
2544 self.generate_py_string_decls(self.scope, code)
2545 self.body.generate_function_definitions(self.scope, code)
2547 def generate_execution_code(self, code):
2548 self.dict.generate_evaluation_code(code)
2549 self.classobj.generate_evaluation_code(code)
2550 self.body.generate_execution_code(code)
2551 self.target.generate_assignment_code(self.classobj, code)
2552 self.dict.generate_disposal_code(code)
2553 self.dict.free_temps(code)
2556 class CClassDefNode(ClassDefNode):
2557 # An extension type definition.
2559 # visibility 'private' or 'public' or 'extern'
2560 # typedef_flag boolean
2562 # module_name string or None For import of extern type objects
2563 # class_name string Unqualified name of class
2564 # as_name string or None Name to declare as in this scope
2565 # base_class_module string or None Module containing the base class
2566 # base_class_name string or None Name of the base class
2567 # objstruct_name string or None Specified C name of object struct
2568 # typeobj_name string or None Specified C name of type object
2569 # in_pxd boolean Is in a .pxd file
2570 # doc string or None
2571 # body StatNode or None
2572 # entry Symtab.Entry
2573 # base_type PyExtensionType or None
2574 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2575 # buffer_defaults_pos
2577 child_attrs = ["body"]
2578 buffer_defaults_node = None
2579 buffer_defaults_pos = None
2580 typedef_flag = False
2582 objstruct_name = None
2585 def analyse_declarations(self, env):
2586 #print "CClassDefNode.analyse_declarations:", self.class_name
2587 #print "...visibility =", self.visibility
2588 #print "...module_name =", self.module_name
2591 if self.buffer_defaults_node:
2592 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2593 env, [], self.buffer_defaults_node,
2594 need_complete=False)
2596 buffer_defaults = None
2598 if env.in_cinclude and not self.objstruct_name:
2599 error(self.pos, "Object struct name specification required for "
2600 "C class defined in 'extern from' block")
2601 self.base_type = None
2602 # Now that module imports are cached, we need to
2603 # import the modules for extern classes.
2604 if self.module_name:
2606 for module in env.cimported_modules:
2607 if module.name == self.module_name:
2608 self.module = module
2609 if self.module is None:
2610 self.module = ModuleScope(self.module_name, None, env.context)
2611 self.module.has_extern_class = 1
2612 env.add_imported_module(self.module)
2614 if self.base_class_name:
2615 if self.base_class_module:
2616 base_class_scope = env.find_module(self.base_class_module, self.pos)
2618 base_class_scope = env
2619 if self.base_class_name == 'object':
2620 # extension classes are special and don't need to inherit from object
2621 if base_class_scope is None or base_class_scope.lookup('object') is None:
2622 self.base_class_name = None
2623 self.base_class_module = None
2624 base_class_scope = None
2625 if base_class_scope:
2626 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2627 if base_class_entry:
2628 if not base_class_entry.is_type:
2629 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2630 elif not base_class_entry.type.is_extension_type:
2631 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2632 elif not base_class_entry.type.is_complete():
2633 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2635 self.base_type = base_class_entry.type
2636 has_body = self.body is not None
2637 if self.module_name and self.visibility != 'extern':
2638 module_path = self.module_name.split(".")
2639 home_scope = env.find_imported_module(module_path, self.pos)
2644 self.entry = home_scope.declare_c_class(
2645 name = self.class_name,
2647 defining = has_body and self.in_pxd,
2648 implementing = has_body and not self.in_pxd,
2649 module_name = self.module_name,
2650 base_type = self.base_type,
2651 objstruct_cname = self.objstruct_name,
2652 typeobj_cname = self.typeobj_name,
2653 visibility = self.visibility,
2654 typedef_flag = self.typedef_flag,
2656 buffer_defaults = buffer_defaults)
2657 if home_scope is not env and self.visibility == 'extern':
2658 env.add_imported_entry(self.class_name, self.entry, pos)
2659 scope = self.entry.type.scope
2661 if self.doc and Options.docstrings:
2662 scope.doc = embed_position(self.pos, self.doc)
2665 self.body.analyse_declarations(scope)
2669 scope.implemented = 1
2670 env.allocate_vtable_names(self.entry)
2672 def analyse_expressions(self, env):
2674 scope = self.entry.type.scope
2675 self.body.analyse_expressions(scope)
2677 def generate_function_definitions(self, env, code):
2678 self.generate_py_string_decls(self.entry.type.scope, code)
2680 self.body.generate_function_definitions(
2681 self.entry.type.scope, code)
2683 def generate_execution_code(self, code):
2684 # This is needed to generate evaluation code for
2685 # default values of method arguments.
2687 self.body.generate_execution_code(code)
2689 def annotate(self, code):
2691 self.body.annotate(code)
2694 class PropertyNode(StatNode):
2695 # Definition of a property in an extension type.
2698 # doc EncodedString or None Doc string
2701 child_attrs = ["body"]
2703 def analyse_declarations(self, env):
2704 entry = env.declare_property(self.name, self.doc, self.pos)
2706 if self.doc and Options.docstrings:
2707 doc_entry = env.get_string_const(
2708 self.doc, identifier = False)
2709 entry.doc_cname = doc_entry.cname
2710 self.body.analyse_declarations(entry.scope)
2712 def analyse_expressions(self, env):
2713 self.body.analyse_expressions(env)
2715 def generate_function_definitions(self, env, code):
2716 self.body.generate_function_definitions(env, code)
2718 def generate_execution_code(self, code):
2721 def annotate(self, code):
2722 self.body.annotate(code)
2725 class GlobalNode(StatNode):
2726 # Global variable declaration.
2732 def analyse_declarations(self, env):
2733 for name in self.names:
2734 env.declare_global(name, self.pos)
2736 def analyse_expressions(self, env):
2739 def generate_execution_code(self, code):
2743 class ExprStatNode(StatNode):
2744 # Expression used as a statement.
2748 child_attrs = ["expr"]
2750 def analyse_declarations(self, env):
2752 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2753 func = self.expr.function.as_cython_attribute()
2754 if func == u'declare':
2755 args, kwds = self.expr.explicit_args_kwds()
2757 error(self.expr.pos, "Variable names must be specified.")
2758 for var, type_node in kwds.key_value_pairs:
2759 type = type_node.analyse_as_type(env)
2761 error(type_node.pos, "Unknown type")
2763 env.declare_var(var.value, type, var.pos, is_cdef = True)
2764 self.__class__ = PassStatNode
2766 def analyse_expressions(self, env):
2767 self.expr.analyse_expressions(env)
2768 self.expr.release_temp(env)
2770 def generate_execution_code(self, code):
2771 self.expr.generate_evaluation_code(code)
2772 if not self.expr.is_temp and self.expr.result():
2773 code.putln("%s;" % self.expr.result())
2774 self.expr.generate_disposal_code(code)
2775 self.expr.free_temps(code)
2777 def annotate(self, code):
2778 self.expr.annotate(code)
2781 class AssignmentNode(StatNode):
2782 # Abstract base class for assignment nodes.
2784 # The analyse_expressions and generate_execution_code
2785 # phases of assignments are split into two sub-phases
2786 # each, to enable all the right hand sides of a
2787 # parallel assignment to be evaluated before assigning
2788 # to any of the left hand sides.
2790 def analyse_expressions(self, env):
2791 self.analyse_types(env)
2792 self.allocate_rhs_temps(env)
2793 self.allocate_lhs_temps(env)
2795 # def analyse_expressions(self, env):
2796 # self.analyse_expressions_1(env)
2797 # self.analyse_expressions_2(env)
2799 def generate_execution_code(self, code):
2800 self.generate_rhs_evaluation_code(code)
2801 self.generate_assignment_code(code)
2804 class SingleAssignmentNode(AssignmentNode):
2805 # The simplest case:
2809 # lhs ExprNode Left hand side
2810 # rhs ExprNode Right hand side
2811 # first bool Is this guaranteed the first assignment to lhs?
2813 child_attrs = ["lhs", "rhs"]
2815 declaration_only = False
2817 def analyse_declarations(self, env):
2820 # handle declarations of the form x = cython.foo()
2821 if isinstance(self.rhs, ExprNodes.CallNode):
2822 func_name = self.rhs.function.as_cython_attribute()
2824 args, kwds = self.rhs.explicit_args_kwds()
2826 if func_name in ['declare', 'typedef']:
2827 if len(args) > 2 or kwds is not None:
2828 error(rhs.pos, "Can only declare one type at a time.")
2830 type = args[0].analyse_as_type(env)
2832 error(args[0].pos, "Unknown type")
2835 if func_name == 'declare':
2836 if isinstance(lhs, ExprNodes.NameNode):
2837 vars = [(lhs.name, lhs.pos)]
2838 elif isinstance(lhs, ExprNodes.TupleNode):
2839 vars = [(var.name, var.pos) for var in lhs.args]
2841 error(lhs.pos, "Invalid declaration")
2843 for var, pos in vars:
2844 env.declare_var(var, type, pos, is_cdef = True)
2849 self.declaration_only = True
2851 self.declaration_only = True
2852 if not isinstance(lhs, ExprNodes.NameNode):
2853 error(lhs.pos, "Invalid declaration.")
2854 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2856 elif func_name in ['struct', 'union']:
2857 self.declaration_only = True
2858 if len(args) > 0 or kwds is None:
2859 error(rhs.pos, "Struct or union members must be given by name.")
2862 for member, type_node in kwds.key_value_pairs:
2863 type = type_node.analyse_as_type(env)
2865 error(type_node.pos, "Unknown type")
2867 members.append((member.value, type, member.pos))
2868 if len(members) < len(kwds.key_value_pairs):
2870 if not isinstance(self.lhs, ExprNodes.NameNode):
2871 error(self.lhs.pos, "Invalid declaration.")
2872 name = self.lhs.name
2873 scope = StructOrUnionScope(name)
2874 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2875 for member, type, pos in members:
2876 scope.declare_var(member, type, pos)
2878 if self.declaration_only:
2881 self.lhs.analyse_target_declaration(env)
2883 def analyse_types(self, env, use_temp = 0):
2884 self.rhs.analyse_types(env)
2885 self.lhs.analyse_target_types(env)
2886 self.lhs.gil_assignment_check(env)
2887 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2889 self.rhs = self.rhs.coerce_to_temp(env)
2891 def allocate_rhs_temps(self, env):
2892 self.rhs.allocate_temps(env)
2894 def allocate_lhs_temps(self, env):
2895 self.lhs.allocate_target_temps(env, self.rhs)
2896 #self.lhs.release_target_temp(env)
2897 #self.rhs.release_temp(env)
2899 def generate_rhs_evaluation_code(self, code):
2900 self.rhs.generate_evaluation_code(code)
2902 def generate_assignment_code(self, code):
2903 self.lhs.generate_assignment_code(self.rhs, code)
2905 def annotate(self, code):
2906 self.lhs.annotate(code)
2907 self.rhs.annotate(code)
2910 class CascadedAssignmentNode(AssignmentNode):
2911 # An assignment with multiple left hand sides:
2915 # lhs_list [ExprNode] Left hand sides
2916 # rhs ExprNode Right hand sides
2920 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2922 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2923 coerced_rhs_list = None
2925 def analyse_declarations(self, env):
2926 for lhs in self.lhs_list:
2927 lhs.analyse_target_declaration(env)
2929 def analyse_types(self, env, use_temp = 0):
2930 self.rhs.analyse_types(env)
2932 self.rhs = self.rhs.coerce_to_temp(env)
2934 self.rhs = self.rhs.coerce_to_simple(env)
2935 from ExprNodes import CloneNode
2936 self.coerced_rhs_list = []
2937 for lhs in self.lhs_list:
2938 lhs.analyse_target_types(env)
2939 lhs.gil_assignment_check(env)
2940 rhs = CloneNode(self.rhs)
2941 rhs = rhs.coerce_to(lhs.type, env)
2942 self.coerced_rhs_list.append(rhs)
2944 def allocate_rhs_temps(self, env):
2945 self.rhs.allocate_temps(env)
2947 def allocate_lhs_temps(self, env):
2948 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2949 rhs.allocate_temps(env)
2950 lhs.allocate_target_temps(env, rhs)
2951 #lhs.release_target_temp(env)
2952 #rhs.release_temp(env)
2953 self.rhs.release_temp(env)
2955 def generate_rhs_evaluation_code(self, code):
2956 self.rhs.generate_evaluation_code(code)
2958 def generate_assignment_code(self, code):
2959 for i in range(len(self.lhs_list)):
2960 lhs = self.lhs_list[i]
2961 rhs = self.coerced_rhs_list[i]
2962 rhs.generate_evaluation_code(code)
2963 lhs.generate_assignment_code(rhs, code)
2964 # Assignment has disposed of the cloned RHS
2965 self.rhs.generate_disposal_code(code)
2966 self.rhs.free_temps(code)
2968 def annotate(self, code):
2969 for i in range(len(self.lhs_list)):
2970 lhs = self.lhs_list[i].annotate(code)
2971 rhs = self.coerced_rhs_list[i].annotate(code)
2972 self.rhs.annotate(code)
2975 class ParallelAssignmentNode(AssignmentNode):
2976 # A combined packing/unpacking assignment:
2980 # This has been rearranged by the parser into
2982 # a = d ; b = e ; c = f
2984 # but we must evaluate all the right hand sides
2985 # before assigning to any of the left hand sides.
2987 # stats [AssignmentNode] The constituent assignments
2989 child_attrs = ["stats"]
2991 def analyse_declarations(self, env):
2992 for stat in self.stats:
2993 stat.analyse_declarations(env)
2995 def analyse_expressions(self, env):
2996 for stat in self.stats:
2997 stat.analyse_types(env, use_temp = 1)
2998 stat.allocate_rhs_temps(env)
2999 for stat in self.stats:
3000 stat.allocate_lhs_temps(env)
3002 # def analyse_expressions(self, env):
3003 # for stat in self.stats:
3004 # stat.analyse_expressions_1(env, use_temp = 1)
3005 # for stat in self.stats:
3006 # stat.analyse_expressions_2(env)
3008 def generate_execution_code(self, code):
3009 for stat in self.stats:
3010 stat.generate_rhs_evaluation_code(code)
3011 for stat in self.stats:
3012 stat.generate_assignment_code(code)
3014 def annotate(self, code):
3015 for stat in self.stats:
3019 class InPlaceAssignmentNode(AssignmentNode):
3020 # An in place arithmatic operand:
3026 # lhs ExprNode Left hand side
3027 # rhs ExprNode Right hand side
3028 # op char one of "+-*/%^&|"
3029 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3031 # This code is a bit tricky because in order to obey Python
3032 # semantics the sub-expressions (e.g. indices) of the lhs must
3033 # not be evaluated twice. So we must re-use the values calculated
3034 # in evaluation phase for the assignment phase as well.
3035 # Fortunately, the type of the lhs node is fairly constrained
3036 # (it must be a NameNode, AttributeNode, or IndexNode).
3038 child_attrs = ["lhs", "rhs"]
3041 def analyse_declarations(self, env):
3042 self.lhs.analyse_target_declaration(env)
3044 def analyse_types(self, env):
3045 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3046 self.rhs.analyse_types(env)
3047 self.lhs.analyse_target_types(env)
3048 if Options.incref_local_binop and self.dup.type.is_pyobject:
3049 self.dup = self.dup.coerce_to_temp(env)
3051 def allocate_rhs_temps(self, env):
3053 if self.lhs.type.is_pyobject:
3054 self.rhs = self.rhs.coerce_to_pyobject(env)
3055 elif self.rhs.type.is_pyobject:
3056 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3057 if self.lhs.type.is_pyobject:
3058 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3059 self.result_value.allocate_temps(env)
3061 # self.rhs = self.rhs.coerce_to_temp(env)
3062 self.rhs.allocate_temps(env)
3063 self.dup.allocate_subexpr_temps(env)
3064 self.dup.allocate_temp(env)
3066 def allocate_lhs_temps(self, env):
3067 self.lhs.allocate_target_temps(env, self.rhs)
3068 # self.lhs.release_target_temp(env)
3069 self.dup.release_temp(env)
3070 if self.dup.is_temp:
3071 self.dup.release_subexpr_temps(env)
3072 # self.rhs.release_temp(env)
3073 if self.lhs.type.is_pyobject:
3074 self.result_value.release_temp(env)
3076 def generate_execution_code(self, code):
3078 self.rhs.generate_evaluation_code(code)
3079 self.dup.generate_subexpr_evaluation_code(code)
3080 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3081 # This is because we're manually messing with subexpr nodes
3082 if self.dup.is_temp:
3083 self.dup.allocate_temp_result(code)
3084 # self.dup.generate_result_code is run only if it is not buffer access
3085 if self.operator == "**":
3089 if self.lhs.type.is_pyobject:
3090 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3091 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3092 self.dup.generate_result_code(code)
3094 "%s = %s(%s, %s%s); %s" % (
3095 self.result_value.result(),
3096 self.py_operation_function(),
3097 self.dup.py_result(),
3098 self.rhs.py_result(),
3100 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3101 code.put_gotref(self.result_value.py_result())
3102 self.result_value.generate_evaluation_code(code) # May be a type check...
3103 self.rhs.generate_disposal_code(code)
3104 self.rhs.free_temps(code)
3105 self.dup.generate_disposal_code(code)
3106 self.dup.free_temps(code)
3107 self.lhs.generate_assignment_code(self.result_value, code)
3109 c_op = self.operator
3113 if self.lhs.type.is_int and self.rhs.type.is_int:
3114 error(self.pos, "** with two C int types is ambiguous")
3116 error(self.pos, "No C inplace power operator")
3117 # have to do assignment directly to avoid side-effects
3118 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3119 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3121 self.dup.generate_result_code(code)
3122 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3123 self.rhs.generate_disposal_code(code)
3124 self.rhs.free_temps(code)
3125 if self.dup.is_temp:
3126 self.dup.generate_subexpr_disposal_code(code)
3127 self.dup.free_subexpr_temps(code)
3129 def create_dup_node(self, env):
3132 self.dup.analyse_types(env)
3133 if isinstance(self.lhs, ExprNodes.NameNode):
3134 target_lhs = ExprNodes.NameNode(self.dup.pos,
3135 name = self.dup.name,
3136 is_temp = self.dup.is_temp,
3137 entry = self.dup.entry)
3138 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3139 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3140 obj = ExprNodes.CloneNode(self.lhs.obj),
3141 attribute = self.dup.attribute,
3142 is_temp = self.dup.is_temp)
3143 elif isinstance(self.lhs, ExprNodes.IndexNode):
3145 index = ExprNodes.CloneNode(self.lhs.index)
3148 if self.lhs.indices:
3149 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3152 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3153 base = ExprNodes.CloneNode(self.dup.base),
3156 is_temp = self.dup.is_temp)
3159 self.lhs = target_lhs
3162 def py_operation_function(self):
3163 return self.py_functions[self.operator]
3166 "|": "PyNumber_InPlaceOr",
3167 "^": "PyNumber_InPlaceXor",
3168 "&": "PyNumber_InPlaceAnd",
3169 "+": "PyNumber_InPlaceAdd",
3170 "-": "PyNumber_InPlaceSubtract",
3171 "*": "PyNumber_InPlaceMultiply",
3172 "/": "PyNumber_InPlaceDivide",
3173 "%": "PyNumber_InPlaceRemainder",
3174 "<<": "PyNumber_InPlaceLshift",
3175 ">>": "PyNumber_InPlaceRshift",
3176 "**": "PyNumber_InPlacePower",
3177 "//": "PyNumber_InPlaceFloorDivide",
3180 def annotate(self, code):
3181 self.lhs.annotate(code)
3182 self.rhs.annotate(code)
3183 self.dup.annotate(code)
3186 class PrintStatNode(StatNode):
3189 # arg_tuple TupleNode
3190 # append_newline boolean
3192 child_attrs = ["arg_tuple"]
3194 def analyse_expressions(self, env):
3195 self.arg_tuple.analyse_expressions(env)
3196 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3197 self.arg_tuple.release_temp(env)
3198 env.use_utility_code(printing_utility_code)
3201 gil_message = "Python print statement"
3203 def generate_execution_code(self, code):
3204 self.arg_tuple.generate_evaluation_code(code)
3206 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3207 self.arg_tuple.py_result(),
3208 self.append_newline,
3209 code.error_goto(self.pos)))
3210 self.arg_tuple.generate_disposal_code(code)
3211 self.arg_tuple.free_temps(code)
3213 def annotate(self, code):
3214 self.arg_tuple.annotate(code)
3217 class ExecStatNode(StatNode):
3222 child_attrs = ["args"]
3224 def analyse_expressions(self, env):
3225 for i, arg in enumerate(self.args):
3226 arg.analyse_expressions(env)
3227 arg = arg.coerce_to_pyobject(env)
3228 arg.release_temp(env)
3230 self.temp_result = env.allocate_temp_pyobject()
3231 env.release_temp(self.temp_result)
3232 env.use_utility_code(Builtin.pyexec_utility_code)
3235 gil_message = "Python exec statement"
3237 def generate_execution_code(self, code):
3239 for arg in self.args:
3240 arg.generate_evaluation_code(code)
3241 args.append( arg.py_result() )
3242 args = tuple(args + ['0', '0'][:3-len(args)])
3243 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3244 (self.temp_result,) + args))
3245 for arg in self.args:
3246 arg.generate_disposal_code(code)
3247 arg.free_temps(code)
3249 code.error_goto_if_null(self.temp_result, self.pos))
3250 code.put_gotref(self.temp_result)
3251 code.put_decref_clear(self.temp_result, py_object_type)
3253 def annotate(self, code):
3254 for arg in self.args:
3258 class DelStatNode(StatNode):
3263 child_attrs = ["args"]
3265 def analyse_declarations(self, env):
3266 for arg in self.args:
3267 arg.analyse_target_declaration(env)
3269 def analyse_expressions(self, env):
3270 for arg in self.args:
3271 arg.analyse_target_expression(env, None)
3272 if arg.type.is_pyobject:
3275 error(arg.pos, "Deletion of non-Python object")
3276 #arg.release_target_temp(env)
3278 gil_message = "Deleting Python object"
3280 def generate_execution_code(self, code):
3281 for arg in self.args:
3282 if arg.type.is_pyobject:
3283 arg.generate_deletion_code(code)
3284 # else error reported earlier
3286 def annotate(self, code):
3287 for arg in self.args:
3291 class PassStatNode(StatNode):
3296 def analyse_expressions(self, env):
3299 def generate_execution_code(self, code):
3303 class BreakStatNode(StatNode):
3307 def analyse_expressions(self, env):
3310 def generate_execution_code(self, code):
3311 if not code.break_label:
3312 error(self.pos, "break statement not inside loop")
3314 code.put_goto(code.break_label)
3317 class ContinueStatNode(StatNode):
3321 def analyse_expressions(self, env):
3324 def generate_execution_code(self, code):
3325 if code.funcstate.in_try_finally:
3326 error(self.pos, "continue statement inside try of try...finally")
3327 elif not code.continue_label:
3328 error(self.pos, "continue statement not inside loop")
3330 code.put_goto(code.continue_label)
3333 class ReturnStatNode(StatNode):
3336 # value ExprNode or None
3337 # return_type PyrexType
3338 # temps_in_use [Entry] Temps in use at time of return
3340 child_attrs = ["value"]
3342 def analyse_expressions(self, env):
3343 return_type = env.return_type
3344 self.return_type = return_type
3345 self.temps_in_use = env.temps_in_use()
3347 error(self.pos, "Return not inside a function body")
3350 self.value.analyse_types(env)
3351 if return_type.is_void or return_type.is_returncode:
3352 error(self.value.pos,
3353 "Return with value in void function")
3355 self.value = self.value.coerce_to(env.return_type, env)
3356 self.value.allocate_temps(env)
3357 self.value.release_temp(env)
3359 if (not return_type.is_void
3360 and not return_type.is_pyobject
3361 and not return_type.is_returncode):
3362 error(self.pos, "Return value required")
3363 if return_type.is_pyobject:
3366 gil_message = "Returning Python object"
3368 def generate_execution_code(self, code):
3369 code.mark_pos(self.pos)
3370 if not self.return_type:
3371 # error reported earlier
3373 if self.return_type.is_pyobject:
3374 code.put_xdecref(Naming.retval_cname,
3377 self.value.generate_evaluation_code(code)
3378 self.value.make_owned_reference(code)
3381 Naming.retval_cname,
3382 self.value.result_as(self.return_type)))
3383 self.value.generate_post_assignment_code(code)
3384 self.value.free_temps(code)
3386 if self.return_type.is_pyobject:
3387 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3388 elif self.return_type.is_returncode:
3391 Naming.retval_cname,
3392 self.return_type.default_value))
3393 # free temps the old way
3394 for entry in self.temps_in_use:
3395 code.put_var_decref_clear(entry)
3396 # free temps the new way
3397 for cname, type in code.funcstate.temps_holding_reference():
3398 code.put_decref_clear(cname, type)
3401 # code.return_label)
3402 code.put_goto(code.return_label)
3404 def annotate(self, code):
3406 self.value.annotate(code)
3409 class RaiseStatNode(StatNode):
3412 # exc_type ExprNode or None
3413 # exc_value ExprNode or None
3414 # exc_tb ExprNode or None
3416 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3418 def analyse_expressions(self, env):
3420 self.exc_type.analyse_types(env)
3421 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3422 self.exc_type.allocate_temps(env)
3424 self.exc_value.analyse_types(env)
3425 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3426 self.exc_value.allocate_temps(env)
3428 self.exc_tb.analyse_types(env)
3429 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3430 self.exc_tb.allocate_temps(env)
3432 self.exc_type.release_temp(env)
3434 self.exc_value.release_temp(env)
3436 self.exc_tb.release_temp(env)
3437 env.use_utility_code(raise_utility_code)
3438 env.use_utility_code(restore_exception_utility_code)
3441 gil_message = "Raising exception"
3443 def generate_execution_code(self, code):
3445 self.exc_type.generate_evaluation_code(code)
3446 type_code = self.exc_type.py_result()
3450 self.exc_value.generate_evaluation_code(code)
3451 value_code = self.exc_value.py_result()
3455 self.exc_tb.generate_evaluation_code(code)
3456 tb_code = self.exc_tb.py_result()
3459 if self.exc_type or self.exc_value or self.exc_tb:
3461 "__Pyx_Raise(%s, %s, %s);" % (
3468 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3470 obj.generate_disposal_code(code)
3471 obj.free_temps(code)
3473 code.error_goto(self.pos))
3475 def annotate(self, code):
3477 self.exc_type.annotate(code)
3479 self.exc_value.annotate(code)
3481 self.exc_tb.annotate(code)
3484 class ReraiseStatNode(StatNode):
3488 def analyse_expressions(self, env):
3490 env.use_utility_code(raise_utility_code)
3491 env.use_utility_code(restore_exception_utility_code)
3493 gil_message = "Raising exception"
3495 def generate_execution_code(self, code):
3496 vars = code.funcstate.exc_vars
3498 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3499 code.putln(code.error_goto(self.pos))
3501 error(self.pos, "Reraise not inside except clause")
3504 class AssertStatNode(StatNode):
3508 # value ExprNode or None
3510 child_attrs = ["cond", "value"]
3512 def analyse_expressions(self, env):
3513 self.cond = self.cond.analyse_boolean_expression(env)
3515 self.value.analyse_types(env)
3516 self.value = self.value.coerce_to_pyobject(env)
3517 self.value.allocate_temps(env)
3518 self.cond.release_temp(env)
3520 self.value.release_temp(env)
3522 #env.recycle_pending_temps() # TEMPORARY
3524 gil_message = "Raising exception"
3526 def generate_execution_code(self, code):
3527 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3528 self.cond.generate_evaluation_code(code)
3530 "if (unlikely(!%s)) {" %
3533 self.value.generate_evaluation_code(code)
3535 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3536 self.value.py_result())
3537 self.value.generate_disposal_code(code)
3538 self.value.free_temps(code)
3541 "PyErr_SetNone(PyExc_AssertionError);")
3543 code.error_goto(self.pos))
3546 self.cond.generate_disposal_code(code)
3547 self.cond.free_temps(code)
3548 code.putln("#endif")
3550 def annotate(self, code):
3551 self.cond.annotate(code)
3553 self.value.annotate(code)
3556 class IfStatNode(StatNode):
3559 # if_clauses [IfClauseNode]
3560 # else_clause StatNode or None
3562 child_attrs = ["if_clauses", "else_clause"]
3564 def analyse_control_flow(self, env):
3565 env.start_branching(self.pos)
3566 for if_clause in self.if_clauses:
3567 if_clause.analyse_control_flow(env)
3568 env.next_branch(if_clause.end_pos())
3569 if self.else_clause:
3570 self.else_clause.analyse_control_flow(env)
3571 env.finish_branching(self.end_pos())
3573 def analyse_declarations(self, env):
3574 for if_clause in self.if_clauses:
3575 if_clause.analyse_declarations(env)
3576 if self.else_clause:
3577 self.else_clause.analyse_declarations(env)
3579 def analyse_expressions(self, env):
3580 for if_clause in self.if_clauses:
3581 if_clause.analyse_expressions(env)
3582 if self.else_clause:
3583 self.else_clause.analyse_expressions(env)
3585 def generate_execution_code(self, code):
3586 code.mark_pos(self.pos)
3587 end_label = code.new_label()
3588 for if_clause in self.if_clauses:
3589 if_clause.generate_execution_code(code, end_label)
3590 if self.else_clause:
3591 code.putln("/*else*/ {")
3592 self.else_clause.generate_execution_code(code)
3594 code.put_label(end_label)
3596 def annotate(self, code):
3597 for if_clause in self.if_clauses:
3598 if_clause.annotate(code)
3599 if self.else_clause:
3600 self.else_clause.annotate(code)
3603 class IfClauseNode(Node):
3604 # if or elif clause in an if statement
3606 # condition ExprNode
3609 child_attrs = ["condition", "body"]
3611 def analyse_control_flow(self, env):
3612 self.body.analyse_control_flow(env)
3614 def analyse_declarations(self, env):
3615 self.condition.analyse_declarations(env)
3616 self.body.analyse_declarations(env)
3618 def analyse_expressions(self, env):
3620 self.condition.analyse_temp_boolean_expression(env)
3621 self.condition.release_temp(env)
3622 self.body.analyse_expressions(env)
3624 def generate_execution_code(self, code, end_label):
3625 self.condition.generate_evaluation_code(code)
3628 self.condition.result())
3629 self.condition.generate_disposal_code(code)
3630 self.condition.free_temps(code)
3631 self.body.generate_execution_code(code)
3635 code.put_goto(end_label)
3638 def annotate(self, code):
3639 self.condition.annotate(code)
3640 self.body.annotate(code)
3643 class SwitchCaseNode(StatNode):
3644 # Generated in the optimization of an if-elif-else node
3646 # conditions [ExprNode]
3649 child_attrs = ['conditions', 'body']
3651 def generate_execution_code(self, code):
3652 for cond in self.conditions:
3653 code.putln("case %s:" % cond.calculate_result_code())
3654 self.body.generate_execution_code(code)
3655 code.putln("break;")
3657 def annotate(self, code):
3658 for cond in self.conditions:
3660 self.body.annotate(code)
3662 class SwitchStatNode(StatNode):
3663 # Generated in the optimization of an if-elif-else node
3666 # cases [SwitchCaseNode]
3667 # else_clause StatNode or None
3669 child_attrs = ['test', 'cases', 'else_clause']
3671 def generate_execution_code(self, code):
3672 code.putln("switch (%s) {" % self.test.calculate_result_code())
3673 for case in self.cases:
3674 case.generate_execution_code(code)
3675 if self.else_clause is not None:
3676 code.putln("default:")
3677 self.else_clause.generate_execution_code(code)
3678 code.putln("break;")
3681 def annotate(self, code):
3682 self.test.annotate(code)
3683 for case in self.cases:
3685 if self.else_clause is not None:
3686 self.else_clause.annotate(code)
3690 def analyse_control_flow(self, env):
3691 env.start_branching(self.pos)
3692 self.body.analyse_control_flow(env)
3693 env.next_branch(self.body.end_pos())
3694 if self.else_clause:
3695 self.else_clause.analyse_control_flow(env)
3696 env.finish_branching(self.end_pos())
3699 class WhileStatNode(LoopNode, StatNode):
3702 # condition ExprNode
3704 # else_clause StatNode
3706 child_attrs = ["condition", "body", "else_clause"]
3708 def analyse_declarations(self, env):
3709 self.body.analyse_declarations(env)
3710 if self.else_clause:
3711 self.else_clause.analyse_declarations(env)
3713 def analyse_expressions(self, env):
3715 self.condition.analyse_temp_boolean_expression(env)
3716 self.condition.release_temp(env)
3717 #env.recycle_pending_temps() # TEMPORARY
3718 self.body.analyse_expressions(env)
3719 if self.else_clause:
3720 self.else_clause.analyse_expressions(env)
3722 def generate_execution_code(self, code):
3723 old_loop_labels = code.new_loop_labels()
3726 self.condition.generate_evaluation_code(code)
3727 self.condition.generate_disposal_code(code)
3730 self.condition.result())
3731 self.condition.free_temps(code)
3732 self.body.generate_execution_code(code)
3733 code.put_label(code.continue_label)
3735 break_label = code.break_label
3736 code.set_loop_labels(old_loop_labels)
3737 if self.else_clause:
3738 code.putln("/*else*/ {")
3739 self.else_clause.generate_execution_code(code)
3741 code.put_label(break_label)
3743 def annotate(self, code):
3744 self.condition.annotate(code)
3745 self.body.annotate(code)
3746 if self.else_clause:
3747 self.else_clause.annotate(code)
3750 def ForStatNode(pos, **kw):
3751 if kw.has_key('iterator'):
3752 return ForInStatNode(pos, **kw)
3754 return ForFromStatNode(pos, **kw)
3756 class ForInStatNode(LoopNode, StatNode):
3760 # iterator IteratorNode
3762 # else_clause StatNode
3763 # item NextNode used internally
3765 child_attrs = ["target", "iterator", "body", "else_clause"]
3768 def analyse_declarations(self, env):
3769 self.target.analyse_target_declaration(env)
3770 self.body.analyse_declarations(env)
3771 if self.else_clause:
3772 self.else_clause.analyse_declarations(env)
3774 def analyse_expressions(self, env):
3776 self.target.analyse_target_types(env)
3777 self.iterator.analyse_expressions(env)
3778 self.item = ExprNodes.NextNode(self.iterator, env)
3779 self.item = self.item.coerce_to(self.target.type, env)
3780 self.item.allocate_temps(env)
3781 self.target.allocate_target_temps(env, self.item)
3782 #self.item.release_temp(env)
3783 #self.target.release_target_temp(env)
3784 self.body.analyse_expressions(env)
3785 if self.else_clause:
3786 self.else_clause.analyse_expressions(env)
3787 self.iterator.release_temp(env)
3789 def generate_execution_code(self, code):
3790 old_loop_labels = code.new_loop_labels()
3791 self.iterator.allocate_counter_temp(code)
3792 self.iterator.generate_evaluation_code(code)
3795 self.item.generate_evaluation_code(code)
3796 self.target.generate_assignment_code(self.item, code)
3797 self.body.generate_execution_code(code)
3798 code.put_label(code.continue_label)
3801 break_label = code.break_label
3802 code.set_loop_labels(old_loop_labels)
3803 if self.else_clause:
3804 code.putln("/*else*/ {")
3805 self.else_clause.generate_execution_code(code)
3807 code.put_label(break_label)
3808 self.iterator.release_counter_temp(code)
3809 self.iterator.generate_disposal_code(code)
3810 self.iterator.free_temps(code)
3812 def annotate(self, code):
3813 self.target.annotate(code)
3814 self.iterator.annotate(code)
3815 self.body.annotate(code)
3816 if self.else_clause:
3817 self.else_clause.annotate(code)
3818 self.item.annotate(code)
3821 class ForFromStatNode(LoopNode, StatNode):
3822 # for name from expr rel name rel expr
3829 # step ExprNode or None
3831 # else_clause StatNode or None
3836 # loopvar_node ExprNode (usually a NameNode or temp node)
3837 # py_loopvar_node PyTempNode or None
3838 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3840 is_py_target = False
3842 py_loopvar_node = None
3844 def analyse_declarations(self, env):
3845 self.target.analyse_target_declaration(env)
3846 self.body.analyse_declarations(env)
3847 if self.else_clause:
3848 self.else_clause.analyse_declarations(env)
3850 def analyse_expressions(self, env):
3852 self.target.analyse_target_types(env)
3853 self.bound1.analyse_types(env)
3854 self.bound2.analyse_types(env)
3855 if self.target.type.is_numeric:
3856 self.bound1 = self.bound1.coerce_to(self.target.type, env)
3857 self.bound2 = self.bound2.coerce_to(self.target.type, env)
3859 self.bound1 = self.bound1.coerce_to_integer(env)
3860 self.bound2 = self.bound2.coerce_to_integer(env)
3861 if self.step is not None:
3862 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3863 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3864 self.step.analyse_types(env)
3865 self.step = self.step.coerce_to_integer(env)
3866 if not (self.bound2.is_name or self.bound2.is_literal):
3867 self.bound2 = self.bound2.coerce_to_temp(env)
3868 target_type = self.target.type
3869 if not (target_type.is_pyobject or target_type.is_numeric):
3870 error(self.target.pos,
3871 "Integer for-loop variable must be of type int or Python object")
3872 #if not (target_type.is_pyobject
3873 # or target_type.assignable_from(PyrexTypes.c_int_type)):
3874 # error(self.target.pos,
3875 # "Cannot assign integer to variable of type '%s'" % target_type)
3876 if target_type.is_numeric:
3877 self.is_py_target = 0
3878 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3879 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3880 self.loopvar_node = self.target
3881 self.py_loopvar_node = None
3883 self.is_py_target = 1
3884 c_loopvar_node = ExprNodes.TempNode(self.pos,
3885 PyrexTypes.c_long_type, env)
3886 c_loopvar_node.allocate_temps(env)
3887 self.loopvar_node = c_loopvar_node
3888 self.py_loopvar_node = \
3889 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3890 self.bound1.allocate_temps(env)
3891 self.bound2.allocate_temps(env)
3892 if self.step is not None:
3893 self.step.allocate_temps(env)
3894 if self.is_py_target:
3895 self.py_loopvar_node.allocate_temps(env)
3896 self.target.allocate_target_temps(env, self.py_loopvar_node)
3897 #self.target.release_target_temp(env)
3898 #self.py_loopvar_node.release_temp(env)
3899 self.body.analyse_expressions(env)
3900 if self.is_py_target:
3901 c_loopvar_node.release_temp(env)
3902 if self.else_clause:
3903 self.else_clause.analyse_expressions(env)
3904 self.bound1.release_temp(env)
3905 self.bound2.release_temp(env)
3906 if self.step is not None:
3907 self.step.release_temp(env)
3909 def generate_execution_code(self, code):
3910 old_loop_labels = code.new_loop_labels()
3911 self.bound1.generate_evaluation_code(code)
3912 self.bound2.generate_evaluation_code(code)
3913 offset, incop = self.relation_table[self.relation1]
3918 if self.step is not None:
3919 self.step.generate_evaluation_code(code)
3920 step = self.step.result()
3921 incop = "%s=%s" % (incop[0], step)
3922 decop = "%s=%s" % (decop[0], step)
3923 loopvar_name = self.loopvar_node.result()
3925 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3927 self.bound1.result(), offset,
3928 loopvar_name, self.relation2, self.bound2.result(),
3929 loopvar_name, incop))
3930 if self.py_loopvar_node:
3931 self.py_loopvar_node.generate_evaluation_code(code)
3932 self.target.generate_assignment_code(self.py_loopvar_node, code)
3933 self.body.generate_execution_code(code)
3934 code.put_label(code.continue_label)
3935 if getattr(self, "from_range", False):
3936 # Undo last increment to maintain Python semantics:
3937 code.putln("} %s%s;" % (loopvar_name, decop))
3940 break_label = code.break_label
3941 code.set_loop_labels(old_loop_labels)
3942 if self.else_clause:
3943 code.putln("/*else*/ {")
3944 self.else_clause.generate_execution_code(code)
3946 code.put_label(break_label)
3947 self.bound1.generate_disposal_code(code)
3948 self.bound1.free_temps(code)
3949 self.bound2.generate_disposal_code(code)
3950 self.bound2.free_temps(code)
3951 if self.step is not None:
3952 self.step.generate_disposal_code(code)
3953 self.step.free_temps(code)
3956 # {relop : (initial offset, increment op)}
3963 def annotate(self, code):
3964 self.target.annotate(code)
3965 self.bound1.annotate(code)
3966 self.bound2.annotate(code)
3968 self.bound2.annotate(code)
3969 self.body.annotate(code)
3970 if self.else_clause:
3971 self.else_clause.annotate(code)
3974 class WithStatNode(StatNode):
3976 Represents a Python with statement.
3978 This is only used at parse tree level; and is not present in
3979 analysis or generation phases.
3981 # manager The with statement manager object
3982 # target Node (lhs expression)
3984 child_attrs = ["manager", "target", "body"]
3986 class TryExceptStatNode(StatNode):
3987 # try .. except statement
3990 # except_clauses [ExceptClauseNode]
3991 # else_clause StatNode or None
3992 # cleanup_list [Entry] old style temps to clean up on error
3994 child_attrs = ["body", "except_clauses", "else_clause"]
3996 def analyse_control_flow(self, env):
3997 env.start_branching(self.pos)
3998 self.body.analyse_control_flow(env)
3999 successful_try = env.control_flow # grab this for later
4000 env.next_branch(self.body.end_pos())
4001 env.finish_branching(self.body.end_pos())
4003 env.start_branching(self.except_clauses[0].pos)
4004 for except_clause in self.except_clauses:
4005 except_clause.analyse_control_flow(env)
4006 env.next_branch(except_clause.end_pos())
4008 # the else cause it executed only when the try clause finishes
4009 env.control_flow.incoming = successful_try
4010 if self.else_clause:
4011 self.else_clause.analyse_control_flow(env)
4012 env.finish_branching(self.end_pos())
4014 def analyse_declarations(self, env):
4015 self.body.analyse_declarations(env)
4016 for except_clause in self.except_clauses:
4017 except_clause.analyse_declarations(env)
4018 if self.else_clause:
4019 self.else_clause.analyse_declarations(env)
4021 env.use_utility_code(reset_exception_utility_code)
4023 def analyse_expressions(self, env):
4024 self.body.analyse_expressions(env)
4025 self.cleanup_list = env.free_temp_entries[:]
4026 default_clause_seen = 0
4027 for except_clause in self.except_clauses:
4028 except_clause.analyse_expressions(env)
4029 if default_clause_seen:
4030 error(except_clause.pos, "default 'except:' must be last")
4031 if not except_clause.pattern:
4032 default_clause_seen = 1
4033 self.has_default_clause = default_clause_seen
4034 if self.else_clause:
4035 self.else_clause.analyse_expressions(env)
4038 gil_message = "Try-except statement"
4040 def generate_execution_code(self, code):
4041 old_return_label = code.return_label
4042 old_break_label = code.break_label
4043 old_error_label = code.new_error_label()
4044 our_error_label = code.error_label
4045 except_end_label = code.new_label('exception_handled')
4046 except_error_label = code.new_label('except_error')
4047 except_return_label = code.new_label('except_return')
4048 try_return_label = code.new_label('try_return')
4049 try_break_label = code.new_label('try_break')
4050 try_end_label = code.new_label('try_end')
4053 code.putln("PyObject %s;" %
4054 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4055 code.putln("__Pyx_ExceptionSave(%s);" %
4056 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4057 for var in Naming.exc_save_vars:
4058 code.put_xgotref(var)
4061 code.return_label = try_return_label
4062 code.break_label = try_break_label
4063 self.body.generate_execution_code(code)
4066 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4067 code.error_label = except_error_label
4068 code.return_label = except_return_label
4069 if self.else_clause:
4072 self.else_clause.generate_execution_code(code)
4075 for var in Naming.exc_save_vars:
4076 code.put_xdecref_clear(var, py_object_type)
4077 code.put_goto(try_end_label)
4078 if code.label_used(try_return_label):
4079 code.put_label(try_return_label)
4080 for var in Naming.exc_save_vars:
4081 code.put_xdecref_clear(var, py_object_type)
4082 code.put_goto(old_return_label)
4083 code.put_label(our_error_label)
4084 code.put_var_xdecrefs_clear(self.cleanup_list)
4085 for temp_name, type in temps_to_clean_up:
4086 code.put_xdecref_clear(temp_name, type)
4087 for except_clause in self.except_clauses:
4088 except_clause.generate_handling_code(code, except_end_label)
4090 error_label_used = code.label_used(except_error_label)
4091 if error_label_used or not self.has_default_clause:
4092 if error_label_used:
4093 code.put_label(except_error_label)
4094 for var in Naming.exc_save_vars:
4095 code.put_xdecref(var, py_object_type)
4096 code.put_goto(old_error_label)
4098 if code.label_used(try_break_label):
4099 code.put_label(try_break_label)
4100 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4101 code.putln("__Pyx_ExceptionReset(%s);" %
4102 ', '.join(Naming.exc_save_vars))
4103 code.put_goto(old_break_label)
4105 if code.label_used(except_return_label):
4106 code.put_label(except_return_label)
4107 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4108 code.putln("__Pyx_ExceptionReset(%s);" %
4109 ', '.join(Naming.exc_save_vars))
4110 code.put_goto(old_return_label)
4112 if code.label_used(except_end_label):
4113 code.put_label(except_end_label)
4114 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4115 code.putln("__Pyx_ExceptionReset(%s);" %
4116 ', '.join(Naming.exc_save_vars))
4117 code.put_label(try_end_label)
4120 code.return_label = old_return_label
4121 code.break_label = old_break_label
4122 code.error_label = old_error_label
4124 def annotate(self, code):
4125 self.body.annotate(code)
4126 for except_node in self.except_clauses:
4127 except_node.annotate(code)
4128 if self.else_clause:
4129 self.else_clause.annotate(code)
4132 class ExceptClauseNode(Node):
4133 # Part of try ... except statement.
4136 # target ExprNode or None
4138 # excinfo_target NameNode or None optional target for exception info
4139 # match_flag string result of exception match
4140 # exc_value ExcValueNode used internally
4141 # function_name string qualified name of enclosing function
4142 # exc_vars (string * 3) local exception variables
4144 # excinfo_target is never set by the parser, but can be set by a transform
4145 # in order to extract more extensive information about the exception as a
4146 # sys.exc_info()-style tuple into a target variable
4148 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4151 excinfo_target = None
4153 def analyse_declarations(self, env):
4155 self.target.analyse_target_declaration(env)
4156 if self.excinfo_target is not None:
4157 self.excinfo_target.analyse_target_declaration(env)
4158 self.body.analyse_declarations(env)
4160 def analyse_expressions(self, env):
4162 genv = env.global_scope()
4163 self.function_name = env.qualified_name
4165 self.pattern.analyse_expressions(env)
4166 self.pattern = self.pattern.coerce_to_pyobject(env)
4167 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4168 self.pattern.release_temp(env)
4169 env.release_temp(self.match_flag)
4170 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4172 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4173 self.exc_value.allocate_temps(env)
4174 self.target.analyse_target_expression(env, self.exc_value)
4175 if self.excinfo_target is not None:
4177 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4178 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4179 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4180 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4182 self.excinfo_tuple.analyse_expressions(env)
4183 self.excinfo_tuple.allocate_temps(env)
4184 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4186 self.body.analyse_expressions(env)
4187 for var in self.exc_vars:
4188 env.release_temp(var)
4189 env.use_utility_code(get_exception_utility_code)
4190 env.use_utility_code(restore_exception_utility_code)
4192 def generate_handling_code(self, code, end_label):
4193 code.mark_pos(self.pos)
4195 self.pattern.generate_evaluation_code(code)
4197 "%s = PyErr_ExceptionMatches(%s);" % (
4199 self.pattern.py_result()))
4200 self.pattern.generate_disposal_code(code)
4201 self.pattern.free_temps(code)
4206 code.putln("/*except:*/ {")
4207 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4208 # We always have to fetch the exception value even if
4209 # there is no target, because this also normalises the
4210 # exception and stores it in the thread state.
4211 exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
4212 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4213 code.error_goto(self.pos)))
4214 for x in self.exc_vars:
4217 self.exc_value.generate_evaluation_code(code)
4218 self.target.generate_assignment_code(self.exc_value, code)
4219 if self.excinfo_target is not None:
4220 self.excinfo_tuple.generate_evaluation_code(code)
4221 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4223 old_exc_vars = code.funcstate.exc_vars
4224 code.funcstate.exc_vars = self.exc_vars
4225 self.body.generate_execution_code(code)
4226 code.funcstate.exc_vars = old_exc_vars
4227 for var in self.exc_vars:
4228 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4229 code.put_goto(end_label)
4233 def annotate(self, code):
4235 self.pattern.annotate(code)
4237 self.target.annotate(code)
4238 self.body.annotate(code)
4241 class TryFinallyStatNode(StatNode):
4242 # try ... finally statement
4245 # finally_clause StatNode
4247 # cleanup_list [Entry] old_style temps to clean up on error
4249 # The plan is that we funnel all continue, break
4250 # return and error gotos into the beginning of the
4251 # finally block, setting a variable to remember which
4252 # one we're doing. At the end of the finally block, we
4253 # switch on the variable to figure out where to go.
4254 # In addition, if we're doing an error, we save the
4255 # exception on entry to the finally block and restore
4258 child_attrs = ["body", "finally_clause"]
4260 preserve_exception = 1
4262 disallow_continue_in_try_finally = 0
4263 # There doesn't seem to be any point in disallowing
4264 # continue in the try block, since we have no problem
4267 def create_analysed(pos, env, body, finally_clause):
4268 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4269 node.cleanup_list = []
4271 create_analysed = staticmethod(create_analysed)
4273 def analyse_control_flow(self, env):
4274 env.start_branching(self.pos)
4275 self.body.analyse_control_flow(env)
4276 env.next_branch(self.body.end_pos())
4277 env.finish_branching(self.body.end_pos())
4278 self.finally_clause.analyse_control_flow(env)
4280 def analyse_declarations(self, env):
4281 self.body.analyse_declarations(env)
4282 self.finally_clause.analyse_declarations(env)
4284 def analyse_expressions(self, env):
4285 self.body.analyse_expressions(env)
4286 self.cleanup_list = env.free_temp_entries[:]
4287 self.finally_clause.analyse_expressions(env)
4290 gil_message = "Try-finally statement"
4292 def generate_execution_code(self, code):
4293 old_error_label = code.error_label
4294 old_labels = code.all_new_labels()
4295 new_labels = code.get_all_labels()
4296 new_error_label = code.error_label
4297 catch_label = code.new_label()
4300 if self.disallow_continue_in_try_finally:
4301 was_in_try_finally = code.funcstate.in_try_finally
4302 code.funcstate.in_try_finally = 1
4303 self.body.generate_execution_code(code)
4304 if self.disallow_continue_in_try_finally:
4305 code.funcstate.in_try_finally = was_in_try_finally
4308 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4312 error_label_used = 0
4313 for i, new_label in enumerate(new_labels):
4314 if new_label in code.labels_used:
4315 cases_used.append(i)
4316 if new_label == new_error_label:
4317 error_label_used = 1
4318 error_label_case = i
4322 if error_label_used and self.preserve_exception:
4324 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4326 "int %s;" % Naming.exc_lineno_name)
4327 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4328 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4329 code.putln(exc_var_init_zero)
4331 exc_var_init_zero = None
4332 code.use_label(catch_label)
4334 "__pyx_why = 0; goto %s;" % catch_label)
4335 for i in cases_used:
4336 new_label = new_labels[i]
4337 #if new_label and new_label != "<try>":
4338 if new_label == new_error_label and self.preserve_exception:
4339 self.put_error_catcher(code,
4340 new_error_label, i+1, catch_label, temps_to_clean_up)
4342 code.put('%s: ' % new_label)
4343 if exc_var_init_zero:
4344 code.putln(exc_var_init_zero)
4345 code.putln("__pyx_why = %s; goto %s;" % (
4348 code.put_label(catch_label)
4349 code.set_all_labels(old_labels)
4350 if error_label_used:
4351 code.new_error_label()
4352 finally_error_label = code.error_label
4353 self.finally_clause.generate_execution_code(code)
4354 if error_label_used:
4355 if finally_error_label in code.labels_used and self.preserve_exception:
4356 over_label = code.new_label()
4357 code.put_goto(over_label);
4358 code.put_label(finally_error_label)
4359 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4360 for var in Naming.exc_vars:
4361 code.putln("Py_XDECREF(%s);" % var)
4363 code.put_goto(old_error_label)
4364 code.put_label(over_label)
4365 code.error_label = old_error_label
4368 "switch (__pyx_why) {")
4369 for i in cases_used:
4370 old_label = old_labels[i]
4371 if old_label == old_error_label and self.preserve_exception:
4372 self.put_error_uncatcher(code, i+1, old_error_label)
4374 code.use_label(old_label)
4376 "case %s: goto %s;" % (
4384 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4385 code.globalstate.use_utility_code(restore_exception_utility_code)
4392 code.put_var_xdecrefs_clear(self.cleanup_list)
4393 for temp_name, type in temps_to_clean_up:
4394 code.put_xdecref_clear(temp_name, type)
4396 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4400 Naming.exc_lineno_name, Naming.lineno_cname))
4404 code.put_goto(catch_label)
4408 def put_error_uncatcher(self, code, i, error_label):
4409 code.globalstate.use_utility_code(restore_exception_utility_code)
4414 "__Pyx_ErrRestore(%s, %s, %s);" %
4418 Naming.lineno_cname, Naming.exc_lineno_name))
4419 for var in Naming.exc_vars:
4423 code.put_goto(error_label)
4427 def annotate(self, code):
4428 self.body.annotate(code)
4429 self.finally_clause.annotate(code)
4432 class GILStatNode(TryFinallyStatNode):
4433 # 'with gil' or 'with nogil' statement
4435 # state string 'gil' or 'nogil'
4439 preserve_exception = 0
4441 def __init__(self, pos, state, body):
4443 TryFinallyStatNode.__init__(self, pos,
4445 finally_clause = GILExitNode(pos, state = state))
4447 def analyse_expressions(self, env):
4448 was_nogil = env.nogil
4450 TryFinallyStatNode.analyse_expressions(self, env)
4451 env.nogil = was_nogil
4453 def gil_check(self, env):
4456 def generate_execution_code(self, code):
4457 code.putln("/*with %s:*/ {" % self.state)
4458 if self.state == 'gil':
4459 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
4461 code.putln("PyThreadState *_save;")
4462 code.putln("Py_UNBLOCK_THREADS")
4463 TryFinallyStatNode.generate_execution_code(self, code)
4467 class GILExitNode(StatNode):
4468 # Used as the 'finally' block in a GILStatNode
4470 # state string 'gil' or 'nogil'
4474 def analyse_expressions(self, env):
4477 def generate_execution_code(self, code):
4478 if self.state == 'gil':
4479 code.putln("PyGILState_Release();")
4481 code.putln("Py_BLOCK_THREADS")
4484 class CImportStatNode(StatNode):
4487 # module_name string Qualified name of module being imported
4488 # as_name string or None Name specified in "as" clause, if any
4492 def analyse_declarations(self, env):
4493 if not env.is_module_scope:
4494 error(self.pos, "cimport only allowed at module level")
4496 module_scope = env.find_module(self.module_name, self.pos)
4497 if "." in self.module_name:
4498 names = [EncodedString(name) for name in self.module_name.split(".")]
4500 top_module_scope = env.context.find_submodule(top_name)
4501 module_scope = top_module_scope
4502 for name in names[1:]:
4503 submodule_scope = module_scope.find_submodule(name)
4504 module_scope.declare_module(name, submodule_scope, self.pos)
4505 module_scope = submodule_scope
4507 env.declare_module(self.as_name, module_scope, self.pos)
4509 env.declare_module(top_name, top_module_scope, self.pos)
4511 name = self.as_name or self.module_name
4512 env.declare_module(name, module_scope, self.pos)
4514 def analyse_expressions(self, env):
4517 def generate_execution_code(self, code):
4521 class FromCImportStatNode(StatNode):
4522 # from ... cimport statement
4524 # module_name string Qualified name of module
4525 # imported_names [(pos, name, as_name, kind)] Names to be imported
4529 def analyse_declarations(self, env):
4530 if not env.is_module_scope:
4531 error(self.pos, "cimport only allowed at module level")
4533 module_scope = env.find_module(self.module_name, self.pos)
4534 env.add_imported_module(module_scope)
4535 for pos, name, as_name, kind in self.imported_names:
4537 for local_name, entry in module_scope.entries.items():
4538 env.add_imported_entry(local_name, entry, pos)
4540 entry = module_scope.lookup(name)
4542 if kind and not self.declaration_matches(entry, kind):
4543 entry.redeclared(pos)
4545 if kind == 'struct' or kind == 'union':
4546 entry = module_scope.declare_struct_or_union(name,
4547 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4548 elif kind == 'class':
4549 entry = module_scope.declare_c_class(name, pos = pos,
4550 module_name = self.module_name)
4552 error(pos, "Name '%s' not declared in module '%s'"
4553 % (name, self.module_name))
4556 local_name = as_name or name
4557 env.add_imported_entry(local_name, entry, pos)
4559 def declaration_matches(self, entry, kind):
4560 if not entry.is_type:
4564 if not type.is_extension_type:
4567 if not type.is_struct_or_union:
4569 if kind != type.kind:
4573 def analyse_expressions(self, env):
4576 def generate_execution_code(self, code):
4580 class FromImportStatNode(StatNode):
4581 # from ... import statement
4584 # items [(string, NameNode)]
4585 # interned_items [(string, NameNode)]
4586 # item PyTempNode used internally
4587 # import_star boolean used internally
4589 child_attrs = ["module"]
4592 def analyse_declarations(self, env):
4593 for name, target in self.items:
4595 if not env.is_module_scope:
4596 error(self.pos, "import * only allowed at module level")
4598 env.has_import_star = 1
4599 self.import_star = 1
4601 target.analyse_target_declaration(env)
4603 def analyse_expressions(self, env):
4605 self.module.analyse_expressions(env)
4606 self.item = ExprNodes.PyTempNode(self.pos, env)
4607 self.item.allocate_temp(env)
4608 self.interned_items = []
4609 for name, target in self.items:
4611 for _, entry in env.entries.items():
4612 if not entry.is_type and entry.type.is_extension_type:
4613 env.use_utility_code(ExprNodes.type_test_utility_code)
4616 entry = env.lookup(target.name)
4617 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4618 continue # already cimported
4619 self.interned_items.append(
4620 (env.intern_identifier(name), target))
4621 target.analyse_target_expression(env, None)
4622 #target.release_target_temp(env) # was release_temp ?!?
4623 self.module.release_temp(env)
4624 self.item.release_temp(env)
4626 def generate_execution_code(self, code):
4627 self.module.generate_evaluation_code(code)
4628 if self.import_star:
4630 'if (%s(%s) < 0) %s;' % (
4632 self.module.py_result(),
4633 code.error_goto(self.pos)))
4634 for cname, target in self.interned_items:
4636 '%s = PyObject_GetAttr(%s, %s); %s' % (
4638 self.module.py_result(),
4640 code.error_goto_if_null(self.item.result(), self.pos)))
4641 code.put_gotref(self.item.py_result())
4642 target.generate_assignment_code(self.item, code)
4643 self.module.generate_disposal_code(code)
4644 self.module.free_temps(code)
4648 #------------------------------------------------------------------------------------
4650 # Runtime support code
4652 #------------------------------------------------------------------------------------
4654 utility_function_predeclarations = \
4657 #define INLINE __inline__
4659 #define INLINE __inline
4664 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4668 static int %(skip_dispatch_cname)s = 0;
4670 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4672 if Options.gcc_branch_hints:
4673 branch_prediction_macros = \
4676 /* Test for GCC > 2.95 */
4677 #if __GNUC__ > 2 || \
4678 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4679 #define likely(x) __builtin_expect(!!(x), 1)
4680 #define unlikely(x) __builtin_expect(!!(x), 0)
4681 #else /* __GNUC__ > 2 ... */
4682 #define likely(x) (x)
4683 #define unlikely(x) (x)
4684 #endif /* __GNUC__ > 2 ... */
4685 #else /* __GNUC__ */
4686 #define likely(x) (x)
4687 #define unlikely(x) (x)
4688 #endif /* __GNUC__ */
4691 branch_prediction_macros = \
4693 #define likely(x) (x)
4694 #define unlikely(x) (x)
4697 #get_name_predeclaration = \
4698 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4700 #get_name_interned_predeclaration = \
4701 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4703 #------------------------------------------------------------------------------------
4705 printing_utility_code = UtilityCode(
4707 static int __Pyx_Print(PyObject *, int); /*proto*/
4708 #if PY_MAJOR_VERSION >= 3
4709 static PyObject* %s = 0;
4710 static PyObject* %s = 0;
4712 """ % (Naming.print_function, Naming.print_function_kwargs),
4714 #if PY_MAJOR_VERSION < 3
4715 static PyObject *__Pyx_GetStdout(void) {
4716 PyObject *f = PySys_GetObject((char *)"stdout");
4718 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4723 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4728 if (!(f = __Pyx_GetStdout()))
4730 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4731 if (PyFile_SoftSpace(f, 1)) {
4732 if (PyFile_WriteString(" ", f) < 0)
4735 v = PyTuple_GET_ITEM(arg_tuple, i);
4736 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4738 if (PyString_Check(v)) {
4739 char *s = PyString_AsString(v);
4740 Py_ssize_t len = PyString_Size(v);
4742 isspace(Py_CHARMASK(s[len-1])) &&
4744 PyFile_SoftSpace(f, 0);
4748 if (PyFile_WriteString("\n", f) < 0)
4750 PyFile_SoftSpace(f, 0);
4755 #else /* Python 3 has a print function */
4756 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4757 PyObject* kwargs = 0;
4758 PyObject* result = 0;
4759 PyObject* end_string;
4760 if (!%(PRINT_FUNCTION)s) {
4761 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4762 if (!%(PRINT_FUNCTION)s)
4766 if (!%(PRINT_KWARGS)s) {
4767 %(PRINT_KWARGS)s = PyDict_New();
4768 if (!%(PRINT_KWARGS)s)
4770 end_string = PyUnicode_FromStringAndSize(" ", 1);
4773 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4774 Py_DECREF(end_string);
4777 Py_DECREF(end_string);
4779 kwargs = %(PRINT_KWARGS)s;
4781 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4788 """ % {'BUILTINS' : Naming.builtins_cname,
4789 'PRINT_FUNCTION' : Naming.print_function,
4790 'PRINT_KWARGS' : Naming.print_function_kwargs}
4793 #------------------------------------------------------------------------------------
4795 # The following function is based on do_raise() from ceval.c.
4797 raise_utility_code = UtilityCode(
4799 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4802 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4806 /* First, check the traceback argument, replacing None with NULL. */
4807 if (tb == Py_None) {
4811 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4812 PyErr_SetString(PyExc_TypeError,
4813 "raise: arg 3 must be a traceback or None");
4816 /* Next, replace a missing value with None */
4817 if (value == NULL) {
4821 #if PY_VERSION_HEX < 0x02050000
4822 if (!PyClass_Check(type))
4824 if (!PyType_Check(type))
4827 /* Raising an instance. The value should be a dummy. */
4828 if (value != Py_None) {
4829 PyErr_SetString(PyExc_TypeError,
4830 "instance exception may not have a separate value");
4833 /* Normalize to raise <class>, <instance> */
4836 #if PY_VERSION_HEX < 0x02050000
4837 if (PyInstance_Check(type)) {
4838 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4843 PyErr_SetString(PyExc_TypeError,
4844 "raise: exception must be an old-style class or instance");
4848 type = (PyObject*) Py_TYPE(type);
4850 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4851 PyErr_SetString(PyExc_TypeError,
4852 "raise: exception class must be a subclass of BaseException");
4857 __Pyx_ErrRestore(type, value, tb);
4867 #------------------------------------------------------------------------------------
4869 reraise_utility_code = UtilityCode(
4871 static void __Pyx_ReRaise(void); /*proto*/
4874 static void __Pyx_ReRaise(void) {
4875 PyThreadState *tstate = PyThreadState_GET();
4876 PyObject* tmp_type = tstate->curexc_type;
4877 PyObject* tmp_value = tstate->curexc_value;
4878 PyObject* tmp_tb = tstate->curexc_traceback;
4879 tstate->curexc_type = tstate->exc_type;
4880 tstate->curexc_value = tstate->exc_value;
4881 tstate->curexc_traceback = tstate->exc_traceback;
4882 tstate->exc_type = 0;
4883 tstate->exc_value = 0;
4884 tstate->exc_traceback = 0;
4885 Py_XDECREF(tmp_type);
4886 Py_XDECREF(tmp_value);
4891 #------------------------------------------------------------------------------------
4893 arg_type_test_utility_code = UtilityCode(
4895 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4896 const char *name, int exact); /*proto*/
4899 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4900 const char *name, int exact)
4903 PyErr_Format(PyExc_SystemError, "Missing type object");
4906 if (none_allowed && obj == Py_None) return 1;
4908 if (Py_TYPE(obj) == type) return 1;
4911 if (PyObject_TypeCheck(obj, type)) return 1;
4913 PyErr_Format(PyExc_TypeError,
4914 "Argument '%s' has incorrect type (expected %s, got %s)",
4915 name, type->tp_name, Py_TYPE(obj)->tp_name);
4920 #------------------------------------------------------------------------------------
4922 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
4923 # many or too few positional arguments were found. This handles
4924 # Py_ssize_t formatting correctly.
4926 raise_argtuple_invalid_utility_code = UtilityCode(
4928 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
4929 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
4932 static void __Pyx_RaiseArgtupleInvalid(
4933 const char* func_name,
4937 Py_ssize_t num_found)
4939 Py_ssize_t num_expected;
4940 const char *number, *more_or_less;
4942 if (num_found < num_min) {
4943 num_expected = num_min;
4944 more_or_less = "at least";
4946 num_expected = num_max;
4947 more_or_less = "at most";
4950 more_or_less = "exactly";
4952 number = (num_expected == 1) ? "" : "s";
4953 PyErr_Format(PyExc_TypeError,
4954 #if PY_VERSION_HEX < 0x02050000
4955 "%s() takes %s %d positional argument%s (%d given)",
4957 "%s() takes %s %zd positional argument%s (%zd given)",
4959 func_name, more_or_less, num_expected, number, num_found);
4963 raise_keyword_required_utility_code = UtilityCode(
4965 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
4968 static INLINE void __Pyx_RaiseKeywordRequired(
4969 const char* func_name,
4972 PyErr_Format(PyExc_TypeError,
4973 #if PY_MAJOR_VERSION >= 3
4974 "%s() needs keyword-only argument %U", func_name, kw_name);
4976 "%s() needs keyword-only argument %s", func_name,
4977 PyString_AS_STRING(kw_name));
4982 raise_double_keywords_utility_code = UtilityCode(
4984 static void __Pyx_RaiseDoubleKeywordsError(
4985 const char* func_name, PyObject* kw_name); /*proto*/
4988 static void __Pyx_RaiseDoubleKeywordsError(
4989 const char* func_name,
4992 PyErr_Format(PyExc_TypeError,
4993 #if PY_MAJOR_VERSION >= 3
4994 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
4996 "%s() got multiple values for keyword argument '%s'", func_name,
4997 PyString_AS_STRING(kw_name));
5002 #------------------------------------------------------------------------------------
5004 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5005 # were passed to a function, or if any keywords were passed to a
5006 # function that does not accept them.
5008 keyword_string_check_utility_code = UtilityCode(
5010 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5011 const char* function_name, int kw_allowed); /*proto*/
5014 static INLINE int __Pyx_CheckKeywordStrings(
5016 const char* function_name,
5021 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5022 #if PY_MAJOR_VERSION < 3
5023 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5025 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5027 goto invalid_keyword_type;
5029 if ((!kw_allowed) && unlikely(key))
5030 goto invalid_keyword;
5032 invalid_keyword_type:
5033 PyErr_Format(PyExc_TypeError,
5034 "%s() keywords must be strings", function_name);
5037 PyErr_Format(PyExc_TypeError,
5038 #if PY_MAJOR_VERSION < 3
5039 "%s() got an unexpected keyword argument '%s'",
5040 function_name, PyString_AsString(key));
5042 "%s() got an unexpected keyword argument '%U'",
5043 function_name, key);
5049 #------------------------------------------------------------------------------------
5051 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5052 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5053 # keywords will raise an invalid keyword error.
5055 # Three kinds of errors are checked: 1) non-string keywords, 2)
5056 # unexpected keywords and 3) overlap with positional arguments.
5058 # If num_posargs is greater 0, it denotes the number of positional
5059 # arguments that were passed and that must therefore not appear
5060 # amongst the keywords as well.
5062 # This method does not check for required keyword arguments.
5065 parse_keywords_utility_code = UtilityCode(
5067 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5068 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5069 const char* function_name); /*proto*/
5072 static int __Pyx_ParseOptionalKeywords(
5074 PyObject **argnames[],
5077 Py_ssize_t num_pos_args,
5078 const char* function_name)
5080 PyObject *key = 0, *value = 0;
5083 PyObject*** first_kw_arg = argnames + num_pos_args;
5085 while (PyDict_Next(kwds, &pos, &key, &value)) {
5086 name = first_kw_arg;
5087 while (*name && (**name != key)) name++;
5089 values[name-argnames] = value;
5091 #if PY_MAJOR_VERSION < 3
5092 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5094 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5096 goto invalid_keyword_type;
5098 for (name = first_kw_arg; *name; name++) {
5099 #if PY_MAJOR_VERSION >= 3
5100 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5101 PyUnicode_Compare(**name, key) == 0) break;
5103 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5104 strcmp(PyString_AS_STRING(**name),
5105 PyString_AS_STRING(key)) == 0) break;
5109 values[name-argnames] = value;
5111 /* unexpected keyword found */
5112 for (name=argnames; name != first_kw_arg; name++) {
5113 if (**name == key) goto arg_passed_twice;
5114 #if PY_MAJOR_VERSION >= 3
5115 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5116 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5118 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5119 strcmp(PyString_AS_STRING(**name),
5120 PyString_AS_STRING(key)) == 0) goto arg_passed_twice;
5124 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5126 goto invalid_keyword;
5134 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5136 invalid_keyword_type:
5137 PyErr_Format(PyExc_TypeError,
5138 "%s() keywords must be strings", function_name);
5141 PyErr_Format(PyExc_TypeError,
5142 #if PY_MAJOR_VERSION < 3
5143 "%s() got an unexpected keyword argument '%s'",
5144 function_name, PyString_AsString(key));
5146 "%s() got an unexpected keyword argument '%U'",
5147 function_name, key);
5154 #------------------------------------------------------------------------------------
5156 unraisable_exception_utility_code = UtilityCode(
5158 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5161 static void __Pyx_WriteUnraisable(const char *name) {
5162 PyObject *old_exc, *old_val, *old_tb;
5164 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5165 #if PY_MAJOR_VERSION < 3
5166 ctx = PyString_FromString(name);
5168 ctx = PyUnicode_FromString(name);
5170 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5172 PyErr_WriteUnraisable(Py_None);
5174 PyErr_WriteUnraisable(ctx);
5180 #------------------------------------------------------------------------------------
5182 traceback_utility_code = UtilityCode(
5184 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5187 #include "compile.h"
5188 #include "frameobject.h"
5189 #include "traceback.h"
5191 static void __Pyx_AddTraceback(const char *funcname) {
5192 PyObject *py_srcfile = 0;
5193 PyObject *py_funcname = 0;
5194 PyObject *py_globals = 0;
5195 PyObject *empty_string = 0;
5196 PyCodeObject *py_code = 0;
5197 PyFrameObject *py_frame = 0;
5199 #if PY_MAJOR_VERSION < 3
5200 py_srcfile = PyString_FromString(%(FILENAME)s);
5202 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5204 if (!py_srcfile) goto bad;
5206 #if PY_MAJOR_VERSION < 3
5207 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5209 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5213 #if PY_MAJOR_VERSION < 3
5214 py_funcname = PyString_FromString(funcname);
5216 py_funcname = PyUnicode_FromString(funcname);
5219 if (!py_funcname) goto bad;
5220 py_globals = PyModule_GetDict(%(GLOBALS)s);
5221 if (!py_globals) goto bad;
5222 #if PY_MAJOR_VERSION < 3
5223 empty_string = PyString_FromStringAndSize("", 0);
5225 empty_string = PyBytes_FromStringAndSize("", 0);
5227 if (!empty_string) goto bad;
5228 py_code = PyCode_New(
5229 0, /*int argcount,*/
5230 #if PY_MAJOR_VERSION >= 3
5231 0, /*int kwonlyargcount,*/
5234 0, /*int stacksize,*/
5236 empty_string, /*PyObject *code,*/
5237 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5238 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5239 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5240 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5241 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5242 py_srcfile, /*PyObject *filename,*/
5243 py_funcname, /*PyObject *name,*/
5244 %(LINENO)s, /*int firstlineno,*/
5245 empty_string /*PyObject *lnotab*/
5247 if (!py_code) goto bad;
5248 py_frame = PyFrame_New(
5249 PyThreadState_GET(), /*PyThreadState *tstate,*/
5250 py_code, /*PyCodeObject *code,*/
5251 py_globals, /*PyObject *globals,*/
5252 0 /*PyObject *locals*/
5254 if (!py_frame) goto bad;
5255 py_frame->f_lineno = %(LINENO)s;
5256 PyTraceBack_Here(py_frame);
5258 Py_XDECREF(py_srcfile);
5259 Py_XDECREF(py_funcname);
5260 Py_XDECREF(empty_string);
5261 Py_XDECREF(py_code);
5262 Py_XDECREF(py_frame);
5265 'FILENAME': Naming.filename_cname,
5266 'LINENO': Naming.lineno_cname,
5267 'CFILENAME': Naming.cfilenm_cname,
5268 'CLINENO': Naming.clineno_cname,
5269 'GLOBALS': Naming.module_cname,
5270 'EMPTY_TUPLE' : Naming.empty_tuple,
5273 restore_exception_utility_code = UtilityCode(
5275 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5276 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5279 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5280 PyObject *tmp_type, *tmp_value, *tmp_tb;
5281 PyThreadState *tstate = PyThreadState_GET();
5283 tmp_type = tstate->exc_type;
5284 tmp_value = tstate->exc_value;
5285 tmp_tb = tstate->exc_traceback;
5286 tstate->exc_type = 0;
5287 tstate->exc_value = 0;
5288 tstate->exc_traceback = 0;
5289 Py_XDECREF(tmp_type);
5290 Py_XDECREF(tmp_value);
5293 tmp_type = tstate->curexc_type;
5294 tmp_value = tstate->curexc_value;
5295 tmp_tb = tstate->curexc_traceback;
5296 tstate->curexc_type = type;
5297 tstate->curexc_value = value;
5298 tstate->curexc_traceback = tb;
5299 Py_XDECREF(tmp_type);
5300 Py_XDECREF(tmp_value);
5304 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5305 PyThreadState *tstate = PyThreadState_GET();
5306 *type = tstate->curexc_type;
5307 *value = tstate->curexc_value;
5308 *tb = tstate->curexc_traceback;
5310 tstate->curexc_type = 0;
5311 tstate->curexc_value = 0;
5312 tstate->curexc_traceback = 0;
5317 #------------------------------------------------------------------------------------
5319 set_vtable_utility_code = UtilityCode(
5321 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5324 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5325 PyObject *pycobj = 0;
5328 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5331 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5344 #------------------------------------------------------------------------------------
5346 get_vtable_utility_code = UtilityCode(
5348 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5351 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5355 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5358 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5359 if (!*(void **)vtabptr)
5372 #------------------------------------------------------------------------------------
5374 init_string_tab_utility_code = UtilityCode(
5376 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5379 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5381 #if PY_MAJOR_VERSION < 3
5382 if (t->is_unicode && (!t->is_identifier)) {
5383 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5384 } else if (t->intern) {
5385 *t->p = PyString_InternFromString(t->s);
5387 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5389 #else /* Python 3+ has unicode identifiers */
5390 if (t->is_identifier || (t->is_unicode && t->intern)) {
5391 *t->p = PyUnicode_InternFromString(t->s);
5392 } else if (t->is_unicode) {
5393 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5395 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5406 #------------------------------------------------------------------------------------
5408 get_exception_utility_code = UtilityCode(
5410 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5413 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5414 PyObject *tmp_type, *tmp_value, *tmp_tb;
5415 PyThreadState *tstate = PyThreadState_GET();
5416 __Pyx_ErrFetch(type, value, tb);
5417 PyErr_NormalizeException(type, value, tb);
5418 if (PyErr_Occurred())
5423 tmp_type = tstate->exc_type;
5424 tmp_value = tstate->exc_value;
5425 tmp_tb = tstate->exc_traceback;
5426 tstate->exc_type = *type;
5427 tstate->exc_value = *value;
5428 tstate->exc_traceback = *tb;
5429 /* Make sure tstate is in a consistent state when we XDECREF
5430 these objects (XDECREF may run arbitrary code). */
5431 Py_XDECREF(tmp_type);
5432 Py_XDECREF(tmp_value);
5444 #------------------------------------------------------------------------------------
5446 reset_exception_utility_code = UtilityCode(
5448 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5449 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5452 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5453 PyThreadState *tstate = PyThreadState_GET();
5454 *type = tstate->exc_type;
5455 *value = tstate->exc_value;
5456 *tb = tstate->exc_traceback;
5462 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5463 PyObject *tmp_type, *tmp_value, *tmp_tb;
5464 PyThreadState *tstate = PyThreadState_GET();
5465 tmp_type = tstate->exc_type;
5466 tmp_value = tstate->exc_value;
5467 tmp_tb = tstate->exc_traceback;
5468 tstate->exc_type = type;
5469 tstate->exc_value = value;
5470 tstate->exc_traceback = tb;
5471 Py_XDECREF(tmp_type);
5472 Py_XDECREF(tmp_value);
5477 #------------------------------------------------------------------------------------