2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
136 def _gil_check(self, env):
141 error(self.pos, "%s not allowed without gil" % self.gil_message)
143 def clone_node(self):
144 """Clone the node. This is defined as a shallow copy, except for member lists
145 amongst the child attributes (from get_child_accessors) which are also
146 copied. Lists containing child nodes are thus seen as a way for the node
147 to hold multiple children directly; the list is not treated as a seperate
148 level in the tree."""
149 result = copy.copy(self)
150 for attrname in result.child_attrs:
151 value = getattr(result, attrname)
152 if isinstance(value, list):
153 setattr(result, attrname, [x for x in value])
158 # There are 4 phases of parse tree processing, applied in order to
159 # all the statements in a given scope-block:
161 # (0) analyse_control_flow
162 # Create the control flow tree into which state can be asserted and
165 # (1) analyse_declarations
166 # Make symbol table entries for all declarations at the current
167 # level, both explicit (def, cdef, etc.) and implicit (assignment
168 # to an otherwise undeclared name).
170 # (2) analyse_expressions
171 # Determine the result types of expressions and fill in the
172 # 'type' attribute of each ExprNode. Insert coercion nodes into the
173 # tree where needed to convert to and from Python objects.
174 # Allocate temporary locals for intermediate results. Fill
175 # in the 'result_code' attribute of each ExprNode with a C code
179 # Emit C code for all declarations, statements and expressions.
180 # Recursively applies the 3 processing phases to the bodies of
184 def analyse_control_flow(self, env):
187 def analyse_declarations(self, env):
190 def analyse_expressions(self, env):
191 raise InternalError("analyse_expressions not implemented for %s" % \
192 self.__class__.__name__)
194 def generate_code(self, code):
195 raise InternalError("generate_code not implemented for %s" % \
196 self.__class__.__name__)
198 def annotate(self, code):
199 # mro does the wrong thing
200 if isinstance(self, BlockNode):
201 self.body.annotate(code)
206 except AttributeError:
208 if not self.child_attrs:
211 for attr in self.child_attrs:
212 child = getattr(self, attr)
213 # Sometimes lists, sometimes nodes
216 elif isinstance(child, list):
218 pos = max(pos, c.end_pos())
220 pos = max(pos, child.end_pos())
224 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
226 return "<...nesting level cutoff...>"
227 if encountered is None:
229 if id(self) in encountered:
230 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
231 encountered.add(id(self))
233 def dump_child(x, level):
234 if isinstance(x, Node):
235 return x.dump(level, filter_out, cutoff-1, encountered)
236 elif isinstance(x, list):
237 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
242 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
244 return "<%s (%d)>" % (self.__class__.__name__, id(self))
247 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
248 for key, value in attrs:
249 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
250 res += "%s>" % indent
253 class CompilerDirectivesNode(Node):
255 Sets compiler directives for the children nodes
257 # directives {string:value} A dictionary holding the right value for
258 # *all* possible directives.
260 child_attrs = ["body"]
262 def analyse_control_flow(self, env):
264 env.directives = self.directives
265 self.body.analyse_control_flow(env)
268 def analyse_declarations(self, env):
270 env.directives = self.directives
271 self.body.analyse_declarations(env)
274 def analyse_expressions(self, env):
276 env.directives = self.directives
277 self.body.analyse_expressions(env)
280 def generate_function_definitions(self, env, code):
281 env_old = env.directives
282 code_old = code.globalstate.directives
283 code.globalstate.directives = self.directives
284 self.body.generate_function_definitions(env, code)
285 env.directives = env_old
286 code.globalstate.directives = code_old
288 def generate_execution_code(self, code):
289 old = code.globalstate.directives
290 code.globalstate.directives = self.directives
291 self.body.generate_execution_code(code)
292 code.globalstate.directives = old
294 def annotate(self, code):
295 old = code.globalstate.directives
296 code.globalstate.directives = self.directives
297 self.body.annotate(code)
298 code.globalstate.directives = old
300 class BlockNode(object):
301 # Mixin class for nodes representing a declaration block.
303 def generate_cached_builtins_decls(self, env, code):
304 entries = env.global_scope().undeclared_cached_builtins
305 for entry in entries:
306 code.globalstate.add_cached_builtin_decl(entry)
310 class StatListNode(Node):
311 # stats a list of StatNode
313 child_attrs = ["stats"]
315 def create_analysed(pos, env, *args, **kw):
316 node = StatListNode(pos, *args, **kw)
317 return node # No node-specific analysis necesarry
318 create_analysed = staticmethod(create_analysed)
320 def analyse_control_flow(self, env):
321 for stat in self.stats:
322 stat.analyse_control_flow(env)
324 def analyse_declarations(self, env):
325 #print "StatListNode.analyse_declarations" ###
326 for stat in self.stats:
327 stat.analyse_declarations(env)
329 def analyse_expressions(self, env):
330 #print "StatListNode.analyse_expressions" ###
331 for stat in self.stats:
332 stat.analyse_expressions(env)
334 def generate_function_definitions(self, env, code):
335 #print "StatListNode.generate_function_definitions" ###
336 for stat in self.stats:
337 stat.generate_function_definitions(env, code)
339 def generate_execution_code(self, code):
340 #print "StatListNode.generate_execution_code" ###
341 for stat in self.stats:
342 code.mark_pos(stat.pos)
343 stat.generate_execution_code(code)
345 def annotate(self, code):
346 for stat in self.stats:
350 class StatNode(Node):
352 # Code generation for statements is split into the following subphases:
354 # (1) generate_function_definitions
355 # Emit C code for the definitions of any structs,
356 # unions, enums and functions defined in the current
359 # (2) generate_execution_code
360 # Emit C code for executable statements.
363 def generate_function_definitions(self, env, code):
366 def generate_execution_code(self, code):
367 raise InternalError("generate_execution_code not implemented for %s" % \
368 self.__class__.__name__)
371 class CDefExternNode(StatNode):
372 # include_file string or None
375 child_attrs = ["body"]
377 def analyse_declarations(self, env):
378 if self.include_file:
379 env.add_include_file(self.include_file)
380 old_cinclude_flag = env.in_cinclude
382 self.body.analyse_declarations(env)
383 env.in_cinclude = old_cinclude_flag
385 def analyse_expressions(self, env):
388 def generate_execution_code(self, code):
391 def annotate(self, code):
392 self.body.annotate(code)
395 class CDeclaratorNode(Node):
396 # Part of a C declaration.
398 # Processing during analyse_declarations phase:
401 # Returns (name, type) pair where name is the
402 # CNameDeclaratorNode of the name being declared
403 # and type is the type it is being declared as.
405 # calling_convention string Calling convention of CFuncDeclaratorNode
406 # for which this is a base
410 calling_convention = ""
413 class CNameDeclaratorNode(CDeclaratorNode):
414 # name string The Pyrex name being declared
415 # cname string or None C name, if specified
416 # default ExprNode or None the value assigned on declaration
418 child_attrs = ['default']
422 def analyse(self, base_type, env, nonempty = 0):
423 if nonempty and self.name == '':
424 # May have mistaken the name for the type.
425 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
426 error(self.pos, "Missing argument name")
427 elif base_type.is_void:
428 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
430 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
431 base_type = py_object_type
432 self.type = base_type
433 return self, base_type
435 class CPtrDeclaratorNode(CDeclaratorNode):
436 # base CDeclaratorNode
438 child_attrs = ["base"]
440 def analyse(self, base_type, env, nonempty = 0):
441 if base_type.is_pyobject:
443 "Pointer base type cannot be a Python object")
444 ptr_type = PyrexTypes.c_ptr_type(base_type)
445 return self.base.analyse(ptr_type, env, nonempty = nonempty)
447 class CArrayDeclaratorNode(CDeclaratorNode):
448 # base CDeclaratorNode
451 child_attrs = ["base", "dimension"]
453 def analyse(self, base_type, env, nonempty = 0):
455 self.dimension.analyse_const_expression(env)
456 if not self.dimension.type.is_int:
457 error(self.dimension.pos, "Array dimension not integer")
458 size = self.dimension.get_constant_c_result_code()
467 if not base_type.is_complete():
469 "Array element type '%s' is incomplete" % base_type)
470 if base_type.is_pyobject:
472 "Array element cannot be a Python object")
473 if base_type.is_cfunction:
475 "Array element cannot be a function")
476 array_type = PyrexTypes.c_array_type(base_type, size)
477 return self.base.analyse(array_type, env, nonempty = nonempty)
480 class CFuncDeclaratorNode(CDeclaratorNode):
481 # base CDeclaratorNode
482 # args [CArgDeclNode]
483 # has_varargs boolean
484 # exception_value ConstNode
485 # exception_check boolean True if PyErr_Occurred check needed
486 # nogil boolean Can be called without gil
487 # with_gil boolean Acquire gil around function body
489 child_attrs = ["base", "args", "exception_value"]
492 optional_arg_count = 0
494 def analyse(self, return_type, env, nonempty = 0):
498 for arg_node in self.args:
499 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
500 name = name_declarator.name
501 if name_declarator.cname:
503 "Function argument cannot have C name specification")
504 # Turn *[] argument into **
506 type = PyrexTypes.c_ptr_type(type.base_type)
507 # Catch attempted C-style func(void) decl
509 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
510 func_type_args.append(
511 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
513 self.optional_arg_count += 1
514 elif self.optional_arg_count:
515 error(self.pos, "Non-default argument follows default argument")
517 if self.optional_arg_count:
518 scope = StructOrUnionScope()
519 arg_count_member = '%sn' % Naming.pyrex_prefix
520 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
521 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
522 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
523 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
524 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
529 cname = struct_cname)
530 self.op_args_struct.defined_in_pxd = 1
531 self.op_args_struct.used = 1
535 if self.exception_check == '+':
536 env.add_include_file('stdexcept')
537 if return_type.is_pyobject \
538 and (self.exception_value or self.exception_check) \
539 and self.exception_check != '+':
541 "Exception clause not allowed for function returning Python object")
543 if self.exception_value:
544 self.exception_value.analyse_const_expression(env)
545 exc_val = self.exception_value.get_constant_c_result_code()
546 if self.exception_check == '+':
547 exc_val_type = self.exception_value.type
548 if not exc_val_type.is_error and \
549 not exc_val_type.is_pyobject and \
550 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
551 error(self.exception_value.pos,
552 "Exception value must be a Python exception or cdef function with no arguments.")
554 if not return_type.assignable_from(self.exception_value.type):
555 error(self.exception_value.pos,
556 "Exception value incompatible with function return type")
557 exc_check = self.exception_check
558 if return_type.is_array:
560 "Function cannot return an array")
561 if return_type.is_cfunction:
563 "Function cannot return a function")
564 func_type = PyrexTypes.CFuncType(
565 return_type, func_type_args, self.has_varargs,
566 optional_arg_count = self.optional_arg_count,
567 exception_value = exc_val, exception_check = exc_check,
568 calling_convention = self.base.calling_convention,
569 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
570 if self.optional_arg_count:
571 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
572 return self.base.analyse(func_type, env)
575 class CArgDeclNode(Node):
576 # Item in a function declaration argument list.
578 # base_type CBaseTypeNode
579 # declarator CDeclaratorNode
580 # not_none boolean Tagged with 'not None'
581 # default ExprNode or None
582 # default_value PyObjectConst constant for default value
583 # is_self_arg boolean Is the "self" arg of an extension type method
584 # is_kw_only boolean Is a keyword-only argument
586 child_attrs = ["base_type", "declarator", "default"]
591 name_declarator = None
594 def analyse(self, env, nonempty = 0):
595 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
596 if self.type is None:
597 # The parser may missinterpret names as types...
599 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
601 self.declarator.name = self.base_type.name
602 self.base_type.name = None
603 self.base_type.is_basic_c_type = False
606 could_be_name = False
607 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
608 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
609 self.declarator.name = self.base_type.arg_name
610 return self.declarator.analyse(base_type, env, nonempty = nonempty)
612 return self.name_declarator, self.type
614 def calculate_default_value_code(self, code):
615 if self.default_value is None:
617 if self.default.is_literal:
618 # will not output any code, just assign the result_code
619 self.default.generate_evaluation_code(code)
620 return self.type.cast_code(self.default.result())
621 self.default_value = code.get_argument_default_const(self.type)
622 return self.default_value
624 def annotate(self, code):
626 self.default.annotate(code)
629 class CBaseTypeNode(Node):
630 # Abstract base class for C base type nodes.
632 # Processing during analyse_declarations phase:
639 class CAnalysedBaseTypeNode(Node):
644 def analyse(self, env, could_be_name = False):
647 class CSimpleBaseTypeNode(CBaseTypeNode):
649 # module_path [string] Qualifying name components
650 # is_basic_c_type boolean
653 # is_self_arg boolean Is self argument of C method
656 arg_name = None # in case the argument name was interpreted as a type
658 def analyse(self, env, could_be_name = False):
659 # Return type descriptor.
660 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
662 if self.is_basic_c_type:
663 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
665 error(self.pos, "Unrecognised type modifier combination")
666 elif self.name == "object" and not self.module_path:
667 type = py_object_type
668 elif self.name is None:
669 if self.is_self_arg and env.is_c_class_scope:
670 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
671 type = env.parent_type
673 type = py_object_type
676 scope = env.find_imported_module(self.module_path, self.pos)
680 if scope.is_c_class_scope:
681 scope = scope.global_scope()
682 entry = scope.lookup(self.name)
683 if entry and entry.is_type:
686 if self.is_self_arg and env.is_c_class_scope:
687 type = env.parent_type
689 type = py_object_type
690 self.arg_name = self.name
692 error(self.pos, "'%s' is not a type identifier" % self.name)
696 return PyrexTypes.error_type
698 class CBufferAccessTypeNode(CBaseTypeNode):
700 # positional_args [ExprNode] List of positional arguments
701 # keyword_args DictNode Keyword arguments
702 # base_type_node CBaseTypeNode
705 # type PyrexType.BufferType ...containing the right options
708 child_attrs = ["base_type_node", "positional_args",
709 "keyword_args", "dtype_node"]
715 def analyse(self, env, could_be_name = False):
716 base_type = self.base_type_node.analyse(env)
717 if base_type.is_error: return base_type
720 options = Buffer.analyse_buffer_options(
723 self.positional_args,
725 base_type.buffer_defaults)
727 self.type = PyrexTypes.BufferType(base_type, **options)
730 class CComplexBaseTypeNode(CBaseTypeNode):
731 # base_type CBaseTypeNode
732 # declarator CDeclaratorNode
734 child_attrs = ["base_type", "declarator"]
736 def analyse(self, env, could_be_name = False):
737 base = self.base_type.analyse(env, could_be_name)
738 _, type = self.declarator.analyse(base, env)
742 class CVarDefNode(StatNode):
743 # C variable definition or forward/extern function declaration.
745 # visibility 'private' or 'public' or 'extern'
746 # base_type CBaseTypeNode
747 # declarators [CDeclaratorNode]
750 # need_properties [entry]
752 # decorators [cython.locals(...)] or None
753 # directive_locals { string : NameNode } locals defined by cython.locals(...)
755 child_attrs = ["base_type", "declarators"]
759 directive_locals = {}
761 def analyse_declarations(self, env, dest_scope = None):
764 self.dest_scope = dest_scope
765 base_type = self.base_type.analyse(env)
766 if (dest_scope.is_c_class_scope
767 and self.visibility == 'public'
768 and base_type.is_pyobject
769 and (base_type.is_builtin_type or base_type.is_extension_type)):
770 self.need_properties = []
772 visibility = 'private'
774 need_property = False
775 visibility = self.visibility
777 for declarator in self.declarators:
778 name_declarator, type = declarator.analyse(base_type, env)
779 if not type.is_complete():
780 if not (self.visibility == 'extern' and type.is_array):
781 error(declarator.pos,
782 "Variable type '%s' is incomplete" % type)
783 if self.visibility == 'extern' and type.is_pyobject:
784 error(declarator.pos,
785 "Python object cannot be declared extern")
786 name = name_declarator.name
787 cname = name_declarator.cname
789 error(declarator.pos, "Missing name in declaration.")
791 if type.is_cfunction:
792 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
793 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
795 if entry is not None:
796 entry.directive_locals = self.directive_locals
798 if self.directive_locals:
799 s.error("Decorators can only be followed by functions")
800 if self.in_pxd and self.visibility != 'extern':
802 "Only 'extern' C variable declaration allowed in .pxd file")
803 entry = dest_scope.declare_var(name, type, declarator.pos,
804 cname = cname, visibility = visibility, is_cdef = 1)
806 self.need_properties.append(entry)
807 entry.needs_property = 1
810 class CStructOrUnionDefNode(StatNode):
812 # cname string or None
813 # kind "struct" or "union"
814 # typedef_flag boolean
815 # visibility "public" or "private"
817 # attributes [CVarDefNode] or None
821 child_attrs = ["attributes"]
823 def analyse_declarations(self, env):
825 if self.visibility == 'extern' and self.packed:
826 error(self.pos, "Cannot declare extern struct as 'packed'")
827 if self.attributes is not None:
828 scope = StructOrUnionScope(self.name)
829 self.entry = env.declare_struct_or_union(
830 self.name, self.kind, scope, self.typedef_flag, self.pos,
831 self.cname, visibility = self.visibility, packed = self.packed)
832 if self.attributes is not None:
833 if self.in_pxd and not env.in_cinclude:
834 self.entry.defined_in_pxd = 1
835 for attr in self.attributes:
836 attr.analyse_declarations(env, scope)
837 if self.visibility != 'extern':
838 need_typedef_indirection = False
839 for attr in scope.var_entries:
842 type = type.base_type
843 if type == self.entry.type:
844 error(attr.pos, "Struct cannot contain itself as a member.")
845 if self.typedef_flag:
847 type = type.base_type
848 if type == self.entry.type:
849 need_typedef_indirection = True
850 if need_typedef_indirection:
851 # C can't handle typedef structs that refer to themselves.
852 struct_entry = self.entry
853 self.entry = env.declare_typedef(
854 self.name, struct_entry.type, self.pos,
855 cname = self.cname, visibility='ignore')
856 struct_entry.type.typedef_flag = False
857 # FIXME: this might be considered a hack ;-)
858 struct_entry.cname = struct_entry.type.cname = \
859 '_' + self.entry.type.typedef_cname
861 def analyse_expressions(self, env):
864 def generate_execution_code(self, code):
868 class CEnumDefNode(StatNode):
869 # name string or None
870 # cname string or None
871 # items [CEnumDefItemNode]
872 # typedef_flag boolean
873 # visibility "public" or "private"
877 child_attrs = ["items"]
879 def analyse_declarations(self, env):
880 self.entry = env.declare_enum(self.name, self.pos,
881 cname = self.cname, typedef_flag = self.typedef_flag,
882 visibility = self.visibility)
883 if self.items is not None:
884 if self.in_pxd and not env.in_cinclude:
885 self.entry.defined_in_pxd = 1
886 for item in self.items:
887 item.analyse_declarations(env, self.entry)
889 def generate_execution_code(self, code):
890 if self.visibility == 'public':
891 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
892 for item in self.entry.enum_values:
893 code.putln("%s = PyInt_FromLong(%s); %s" % (
896 code.error_goto_if_null(temp, item.pos)))
897 code.put_gotref(temp)
898 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
902 code.error_goto(item.pos)))
903 code.put_decref_clear(temp, PyrexTypes.py_object_type)
904 code.funcstate.release_temp(temp)
907 class CEnumDefItemNode(StatNode):
909 # cname string or None
910 # value ExprNode or None
912 child_attrs = ["value"]
914 def analyse_declarations(self, env, enum_entry):
916 self.value.analyse_const_expression(env)
917 if not self.value.type.is_int:
918 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
919 self.value.analyse_const_expression(env)
920 entry = env.declare_const(self.name, enum_entry.type,
921 self.value, self.pos, cname = self.cname,
922 visibility = enum_entry.visibility)
923 enum_entry.enum_values.append(entry)
926 class CTypeDefNode(StatNode):
927 # base_type CBaseTypeNode
928 # declarator CDeclaratorNode
929 # visibility "public" or "private"
932 child_attrs = ["base_type", "declarator"]
934 def analyse_declarations(self, env):
935 base = self.base_type.analyse(env)
936 name_declarator, type = self.declarator.analyse(base, env)
937 name = name_declarator.name
938 cname = name_declarator.cname
939 entry = env.declare_typedef(name, type, self.pos,
940 cname = cname, visibility = self.visibility)
941 if self.in_pxd and not env.in_cinclude:
942 entry.defined_in_pxd = 1
944 def analyse_expressions(self, env):
946 def generate_execution_code(self, code):
950 class FuncDefNode(StatNode, BlockNode):
951 # Base class for function definition nodes.
953 # return_type PyrexType
954 # #filename string C name of filename string const
956 # needs_closure boolean Whether or not this function has inner functions/classes/yield
957 # directive_locals { string : NameNode } locals defined by cython.locals(...)
961 needs_closure = False
963 def analyse_default_values(self, env):
964 genv = env.global_scope()
965 for arg in self.args:
968 arg.default.analyse_types(env)
969 arg.default = arg.default.coerce_to(arg.type, genv)
972 "This argument cannot have a default value")
975 def need_gil_acquisition(self, lenv):
978 def create_local_scope(self, env):
980 while env.is_py_class_scope or env.is_c_class_scope:
981 env = env.outer_scope
982 if self.needs_closure:
983 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
985 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
986 lenv.return_type = self.return_type
987 type = self.entry.type
988 if type.is_cfunction:
989 lenv.nogil = type.nogil and not type.with_gil
990 self.local_scope = lenv
991 lenv.directives = env.directives
994 def generate_function_definitions(self, env, code):
997 lenv = self.local_scope
999 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1000 self.entry.scope.is_c_class_scope)
1002 # Generate C code for header and body of function
1003 code.enter_cfunc_scope()
1004 code.return_from_error_cleanup_label = code.new_label()
1006 # ----- Top-level constants used by this function
1007 code.mark_pos(self.pos)
1008 self.generate_cached_builtins_decls(lenv, code)
1009 # ----- Function header
1012 self.py_func.generate_function_header(code,
1013 with_pymethdef = env.is_py_class_scope,
1015 self.generate_function_header(code,
1016 with_pymethdef = env.is_py_class_scope)
1017 # ----- Local variable declarations
1018 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1019 self.generate_argument_declarations(lenv, code)
1020 if self.needs_closure:
1021 code.putln("/* TODO: declare and create scope object */")
1022 code.put_var_declarations(lenv.var_entries)
1024 if not self.return_type.is_void:
1025 if self.return_type.is_pyobject:
1029 (self.return_type.declaration_code(
1030 Naming.retval_cname),
1032 tempvardecl_code = code.insertion_point()
1033 self.generate_keyword_list(code)
1034 # ----- Extern library function declarations
1035 lenv.generate_library_function_declarations(code)
1036 # ----- GIL acquisition
1037 acquire_gil = self.need_gil_acquisition(lenv)
1039 env.use_utility_code(force_init_threads_utility_code)
1040 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1041 # ----- Automatic lead-ins for certain special functions
1043 code.put_setup_refcount_context(self.entry.name)
1044 if is_getbuffer_slot:
1045 self.getbuffer_init(code)
1046 # ----- Fetch arguments
1047 self.generate_argument_parsing_code(env, code)
1048 # If an argument is assigned to in the body, we must
1049 # incref it to properly keep track of refcounts.
1050 for entry in lenv.arg_entries:
1051 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1052 code.put_var_incref(entry)
1053 # ----- Initialise local variables
1054 for entry in lenv.var_entries:
1055 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1056 code.put_init_var_to_py_none(entry)
1057 # ----- Initialise local buffer auxiliary variables
1058 for entry in lenv.var_entries + lenv.arg_entries:
1059 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1060 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1061 # ----- Check and convert arguments
1062 self.generate_argument_type_tests(code)
1063 # ----- Acquire buffer arguments
1064 for entry in lenv.arg_entries:
1065 if entry.type.is_buffer:
1066 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1067 # ----- Function body
1068 self.body.generate_execution_code(code)
1069 # ----- Default return value
1071 if self.return_type.is_pyobject:
1072 #if self.return_type.is_extension_type:
1073 # lhs = "(PyObject *)%s" % Naming.retval_cname
1075 lhs = Naming.retval_cname
1076 code.put_init_to_py_none(lhs, self.return_type)
1078 val = self.return_type.default_value
1080 code.putln("%s = %s;" % (Naming.retval_cname, val))
1081 # ----- Error cleanup
1082 if code.error_label in code.labels_used:
1083 code.put_goto(code.return_label)
1084 code.put_label(code.error_label)
1085 for cname, type in code.funcstate.all_managed_temps():
1086 code.put_xdecref(cname, type)
1088 # Clean up buffers -- this calls a Python function
1089 # so need to save and restore error state
1090 buffers_present = len(lenv.buffer_entries) > 0
1092 code.globalstate.use_utility_code(restore_exception_utility_code)
1093 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1094 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1095 for entry in lenv.buffer_entries:
1096 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1097 #code.putln("%s = 0;" % entry.cname)
1098 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1100 err_val = self.error_value()
1101 exc_check = self.caller_will_check_exceptions()
1102 if err_val is not None or exc_check:
1103 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1105 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1106 % self.entry.qualified_name, 0)
1108 '__Pyx_WriteUnraisable("%s");' %
1109 self.entry.qualified_name)
1110 env.use_utility_code(unraisable_exception_utility_code)
1111 env.use_utility_code(restore_exception_utility_code)
1112 default_retval = self.return_type.default_value
1113 if err_val is None and default_retval:
1114 err_val = default_retval
1115 if err_val is not None:
1118 Naming.retval_cname,
1121 if is_getbuffer_slot:
1122 self.getbuffer_error_cleanup(code)
1124 # If we are using the non-error cleanup section we should
1125 # jump past it if we have an error. The if-test below determine
1126 # whether this section is used.
1127 if buffers_present or is_getbuffer_slot:
1128 code.put_goto(code.return_from_error_cleanup_label)
1131 # ----- Non-error return cleanup
1132 # If you add anything here, remember to add a condition to the
1133 # if-test above in the error block (so that it can jump past this
1135 code.put_label(code.return_label)
1136 for entry in lenv.buffer_entries:
1138 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1139 if is_getbuffer_slot:
1140 self.getbuffer_normal_cleanup(code)
1141 # ----- Return cleanup for both error and no-error return
1142 code.put_label(code.return_from_error_cleanup_label)
1143 if not Options.init_local_none:
1144 for entry in lenv.var_entries:
1145 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1146 entry.xdecref_cleanup = 1
1147 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1148 # Decref any increfed args
1149 for entry in lenv.arg_entries:
1150 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1151 code.put_var_decref(entry)
1153 # code.putln("/* TODO: decref scope object */")
1155 # This code is duplicated in ModuleNode.generate_module_init_func
1157 default_retval = self.return_type.default_value
1158 err_val = self.error_value()
1159 if err_val is None and default_retval:
1160 err_val = default_retval
1161 if self.return_type.is_pyobject:
1162 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1164 code.put_finish_refcount_context()
1167 code.putln("PyGILState_Release(_save);")
1169 if not self.return_type.is_void:
1170 code.putln("return %s;" % Naming.retval_cname)
1173 # ----- Go back and insert temp variable declarations
1174 tempvardecl_code.put_temp_declarations(code.funcstate)
1175 # ----- Python version
1176 code.exit_cfunc_scope()
1178 self.py_func.generate_function_definitions(env, code)
1179 self.generate_wrapper_functions(code)
1181 def declare_argument(self, env, arg):
1182 if arg.type.is_void:
1183 error(arg.pos, "Invalid use of 'void'")
1184 elif not arg.type.is_complete() and not arg.type.is_array:
1186 "Argument type '%s' is incomplete" % arg.type)
1187 return env.declare_arg(arg.name, arg.type, arg.pos)
1189 def generate_wrapper_functions(self, code):
1192 def generate_execution_code(self, code):
1193 # Evaluate and store argument default values
1194 for arg in self.args:
1195 default = arg.default
1197 if not default.is_literal:
1198 default.generate_evaluation_code(code)
1199 default.make_owned_reference(code)
1200 result = default.result_as(arg.type)
1203 arg.calculate_default_value_code(code),
1205 if arg.type.is_pyobject:
1206 code.put_giveref(default.result())
1207 default.generate_post_assignment_code(code)
1208 default.free_temps(code)
1209 # For Python class methods, create and store function object
1211 self.assmt.generate_execution_code(code)
1214 # Special code for the __getbuffer__ function
1216 def getbuffer_init(self, code):
1217 info = self.local_scope.arg_entries[1].cname
1218 # Python 3.0 betas have a bug in memoryview which makes it call
1219 # getbuffer with a NULL parameter. For now we work around this;
1220 # the following line should be removed when this bug is fixed.
1221 code.putln("if (%s == NULL) return 0;" % info)
1222 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1223 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1225 def getbuffer_error_cleanup(self, code):
1226 info = self.local_scope.arg_entries[1].cname
1227 code.put_gotref("%s->obj" % info)
1228 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1231 def getbuffer_normal_cleanup(self, code):
1232 info = self.local_scope.arg_entries[1].cname
1233 code.putln("if (%s->obj == Py_None) {" % info)
1234 code.put_gotref("Py_None")
1235 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1238 class CFuncDefNode(FuncDefNode):
1239 # C function definition.
1241 # modifiers ['inline']
1242 # visibility 'private' or 'public' or 'extern'
1243 # base_type CBaseTypeNode
1244 # declarator CDeclaratorNode
1247 # decorators [DecoratorNode] list of decorators
1249 # with_gil boolean Acquire GIL around body
1251 # py_func wrapper for calling from Python
1252 # overridable whether or not this is a cpdef function
1253 # inline_in_pxd whether this is an inline function in a pxd file
1255 child_attrs = ["base_type", "declarator", "body", "py_func"]
1257 inline_in_pxd = False
1259 directive_locals = {}
1261 def unqualified_name(self):
1262 return self.entry.name
1264 def analyse_declarations(self, env):
1265 directive_locals = self.directive_locals = env.directives['locals']
1266 base_type = self.base_type.analyse(env)
1267 # The 2 here is because we need both function and argument names.
1268 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1269 if not type.is_cfunction:
1271 "Suite attached to non-function declaration")
1272 # Remember the actual type according to the function header
1273 # written here, because the type in the symbol table entry
1274 # may be different if we're overriding a C method inherited
1275 # from the base type of an extension type.
1277 type.is_overridable = self.overridable
1278 declarator = self.declarator
1279 while not hasattr(declarator, 'args'):
1280 declarator = declarator.base
1281 self.args = declarator.args
1282 for formal_arg, type_arg in zip(self.args, type.args):
1283 formal_arg.type = type_arg.type
1284 formal_arg.name = type_arg.name
1285 formal_arg.cname = type_arg.cname
1286 name = name_declarator.name
1287 cname = name_declarator.cname
1288 self.entry = env.declare_cfunction(
1289 name, type, self.pos,
1290 cname = cname, visibility = self.visibility,
1291 defining = self.body is not None,
1292 api = self.api, modifiers = self.modifiers)
1293 self.entry.inline_func_in_pxd = self.inline_in_pxd
1294 self.return_type = type.return_type
1296 if self.overridable and not env.is_module_scope:
1297 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1298 # An error will be produced in the cdef function
1299 self.overridable = False
1301 if self.overridable:
1303 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1304 self.py_func = DefNode(pos = self.pos,
1305 name = self.entry.name,
1308 starstar_arg = None,
1310 body = py_func_body,
1312 self.py_func.is_module_scope = env.is_module_scope
1313 self.py_func.analyse_declarations(env)
1314 self.entry.as_variable = self.py_func.entry
1315 # Reset scope entry the above cfunction
1316 env.entries[name] = self.entry
1317 if not env.is_module_scope or Options.lookup_module_cpdef:
1318 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1319 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1321 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1323 args = self.type.args
1324 if omit_optional_args:
1325 args = args[:len(args) - self.type.optional_arg_count]
1326 arg_names = [arg.name for arg in args]
1328 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1330 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1331 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1332 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1333 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)
1334 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1336 def declare_arguments(self, env):
1337 for arg in self.type.args:
1339 error(arg.pos, "Missing argument name")
1340 self.declare_argument(env, arg)
1342 def need_gil_acquisition(self, lenv):
1343 return self.type.with_gil
1345 def gil_check(self, env):
1347 with_gil = type.with_gil
1348 if type.nogil and not with_gil:
1349 if type.return_type.is_pyobject:
1351 "Function with Python return type cannot be declared nogil")
1352 for entry in env.var_entries:
1353 if entry.type.is_pyobject:
1354 error(self.pos, "Function declared nogil has Python locals or temporaries")
1356 def analyse_expressions(self, env):
1357 self.local_scope.directives = env.directives
1358 if self.py_func is not None:
1359 # this will also analyse the default values
1360 self.py_func.analyse_expressions(env)
1362 self.analyse_default_values(env)
1364 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1367 visibility = self.entry.visibility
1368 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1369 arg_decls.append(arg.declaration_code())
1370 if with_dispatch and self.overridable:
1371 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1372 if type.optional_arg_count and with_opt_args:
1373 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1374 if type.has_varargs:
1375 arg_decls.append("...")
1377 arg_decls = ["void"]
1379 cname = self.entry.func_cname
1380 entity = type.function_header_code(cname, ', '.join(arg_decls))
1381 if visibility == 'public':
1382 dll_linkage = "DL_EXPORT"
1385 header = self.return_type.declaration_code(entity,
1386 dll_linkage = dll_linkage)
1387 if visibility == 'extern':
1388 storage_class = "%s " % Naming.extern_c_macro
1389 elif visibility == 'public':
1392 storage_class = "static "
1393 code.putln("%s%s %s {" % (
1395 ' '.join(self.modifiers).upper(), # macro forms
1398 def generate_argument_declarations(self, env, code):
1399 for arg in self.args:
1401 result = arg.calculate_default_value_code(code)
1402 code.putln('%s = %s;' % (
1403 arg.type.declaration_code(arg.cname), result))
1405 def generate_keyword_list(self, code):
1408 def generate_argument_parsing_code(self, env, code):
1410 if self.type.optional_arg_count:
1411 code.putln('if (%s) {' % Naming.optional_args_cname)
1412 for arg in self.args:
1414 # FIXME: simple name prefixing doesn't work when
1415 # argument name mangling is in place
1416 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1417 declarator = arg.declarator
1418 while not hasattr(declarator, 'name'):
1419 declarator = declarator.base
1420 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1422 for _ in range(self.type.optional_arg_count):
1426 def generate_argument_conversion_code(self, code):
1429 def generate_argument_type_tests(self, code):
1430 # Generate type tests for args whose type in a parent
1431 # class is a supertype of the declared type.
1432 for arg in self.type.args:
1433 if arg.needs_type_test:
1434 self.generate_arg_type_test(arg, code)
1436 def generate_arg_type_test(self, arg, code):
1437 # Generate type test for one argument.
1438 if arg.type.typeobj_is_available():
1439 typeptr_cname = arg.type.typeptr_cname
1440 arg_code = "((PyObject *)%s)" % arg.cname
1442 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1447 type.is_builtin_type,
1448 code.error_goto(arg.pos)))
1450 error(arg.pos, "Cannot test type of extern C class "
1451 "without type object name specification")
1453 def error_value(self):
1454 if self.return_type.is_pyobject:
1458 return self.entry.type.exception_value
1460 def caller_will_check_exceptions(self):
1461 return self.entry.type.exception_check
1463 def generate_wrapper_functions(self, code):
1464 # If the C signature of a function has changed, we need to generate
1465 # wrappers to put in the slots here.
1468 func_type = entry.type
1469 while entry.prev_entry is not None:
1471 entry = entry.prev_entry
1472 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1474 self.generate_function_header(code,
1476 with_dispatch = entry.type.is_overridable,
1477 with_opt_args = entry.type.optional_arg_count,
1478 cname = entry.func_cname)
1479 if not self.return_type.is_void:
1481 args = self.type.args
1482 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1483 if entry.type.is_overridable:
1484 arglist.append(Naming.skip_dispatch_cname)
1485 elif func_type.is_overridable:
1487 if entry.type.optional_arg_count:
1488 arglist.append(Naming.optional_args_cname)
1489 elif func_type.optional_arg_count:
1490 arglist.append('NULL')
1491 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1495 class PyArgDeclNode(Node):
1496 # Argument which must be a Python object (used
1497 # for * and ** arguments).
1500 # entry Symtab.Entry
1504 class DecoratorNode(Node):
1507 # decorator NameNode or CallNode
1508 child_attrs = ['decorator']
1511 class DefNode(FuncDefNode):
1512 # A Python function definition.
1514 # name string the Python name of the function
1515 # decorators [DecoratorNode] list of decorators
1516 # args [CArgDeclNode] formal arguments
1517 # star_arg PyArgDeclNode or None * argument
1518 # starstar_arg PyArgDeclNode or None ** argument
1519 # doc EncodedString or None
1522 # The following subnode is constructed internally
1523 # when the def statement is inside a Python class definition.
1525 # assmt AssignmentNode Function construction/assignment
1527 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1531 num_required_kw_args = 0
1532 reqd_kw_flags_cname = "0"
1538 def __init__(self, pos, **kwds):
1539 FuncDefNode.__init__(self, pos, **kwds)
1541 for arg in self.args:
1548 self.num_kwonly_args = k
1549 self.num_required_kw_args = rk
1550 self.num_required_args = r
1552 def as_cfunction(self, cfunc=None, scope=None):
1554 error(self.star_arg.pos, "cdef function cannot have star argument")
1555 if self.starstar_arg:
1556 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1559 for formal_arg in self.args:
1560 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1561 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1563 type = py_object_type,
1564 pos = formal_arg.pos))
1565 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1567 has_varargs = False,
1568 exception_value = None,
1569 exception_check = False,
1572 is_overridable = True)
1573 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1575 cfunc_type = cfunc.type
1576 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1577 error(self.pos, "wrong number of arguments")
1578 error(declarator.pos, "previous declaration here")
1579 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1580 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1581 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1582 formal_arg.type = type_arg.type
1583 formal_arg.name_declarator = name_declarator
1585 if cfunc_type.exception_value is None:
1586 exception_value = None
1588 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1589 declarator = CFuncDeclaratorNode(self.pos,
1590 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1592 has_varargs = False,
1593 exception_check = cfunc_type.exception_check,
1594 exception_value = exception_value,
1595 with_gil = cfunc_type.with_gil,
1596 nogil = cfunc_type.nogil)
1597 return CFuncDefNode(self.pos,
1599 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1600 declarator = declarator,
1603 overridable = cfunc_type.is_overridable,
1605 with_gil = cfunc_type.with_gil,
1606 nogil = cfunc_type.nogil,
1607 visibility = 'private',
1609 directive_locals = getattr(cfunc, 'directive_locals', {}))
1611 def analyse_declarations(self, env):
1612 directive_locals = self.directive_locals = env.directives['locals']
1613 for arg in self.args:
1614 if hasattr(arg, 'name'):
1616 name_declarator = None
1618 base_type = arg.base_type.analyse(env)
1619 name_declarator, type = \
1620 arg.declarator.analyse(base_type, env)
1621 arg.name = name_declarator.name
1622 if arg.name in directive_locals:
1623 type_node = directive_locals[arg.name]
1624 other_type = type_node.analyse_as_type(env)
1625 if other_type is None:
1626 error(type_node.pos, "Not a type")
1627 elif (type is not PyrexTypes.py_object_type
1628 and not type.same_as(other_type)):
1629 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1630 error(type_node.pos, "Previous declaration here")
1633 if name_declarator and name_declarator.cname:
1635 "Python function argument cannot have C name specification")
1636 arg.type = type.as_argument_type()
1638 arg.needs_conversion = 0
1639 arg.needs_type_test = 0
1641 if arg.not_none and not arg.type.is_extension_type:
1643 "Only extension type arguments can have 'not None'")
1644 self.declare_pyfunction(env)
1645 self.analyse_signature(env)
1646 self.return_type = self.entry.signature.return_type()
1648 def analyse_signature(self, env):
1649 any_type_tests_needed = 0
1650 if self.entry.is_special:
1651 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1652 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1653 # Use the simpler calling signature for zero- and one-argument functions.
1654 if self.entry.signature is TypeSlots.pyfunction_signature:
1655 if len(self.args) == 0:
1656 self.entry.signature = TypeSlots.pyfunction_noargs
1657 elif len(self.args) == 1:
1658 if self.args[0].default is None and not self.args[0].kw_only:
1659 self.entry.signature = TypeSlots.pyfunction_onearg
1660 elif self.entry.signature is TypeSlots.pymethod_signature:
1661 if len(self.args) == 1:
1662 self.entry.signature = TypeSlots.unaryfunc
1663 elif len(self.args) == 2:
1664 if self.args[1].default is None and not self.args[1].kw_only:
1665 self.entry.signature = TypeSlots.ibinaryfunc
1666 sig = self.entry.signature
1667 nfixed = sig.num_fixed_args()
1668 for i in range(nfixed):
1669 if i < len(self.args):
1672 if sig.is_self_arg(i):
1674 arg.hdr_type = arg.type = env.parent_type
1675 arg.needs_conversion = 0
1677 arg.hdr_type = sig.fixed_arg_type(i)
1678 if not arg.type.same_as(arg.hdr_type):
1679 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1680 arg.needs_type_test = 1
1681 any_type_tests_needed = 1
1683 arg.needs_conversion = 1
1684 if arg.needs_conversion:
1685 arg.hdr_cname = Naming.arg_prefix + arg.name
1687 arg.hdr_cname = Naming.var_prefix + arg.name
1689 self.bad_signature()
1691 if nfixed < len(self.args):
1692 if not sig.has_generic_args:
1693 self.bad_signature()
1694 for arg in self.args:
1695 if arg.is_generic and \
1696 (arg.type.is_extension_type or arg.type.is_builtin_type):
1697 arg.needs_type_test = 1
1698 any_type_tests_needed = 1
1699 if any_type_tests_needed:
1700 env.use_utility_code(arg_type_test_utility_code)
1702 def bad_signature(self):
1703 sig = self.entry.signature
1704 expected_str = "%d" % sig.num_fixed_args()
1705 if sig.has_generic_args:
1706 expected_str = expected_str + " or more"
1708 if name.startswith("__") and name.endswith("__"):
1709 desc = "Special method"
1713 "%s %s has wrong number of arguments "
1714 "(%d declared, %s expected)" % (
1715 desc, self.name, len(self.args), expected_str))
1717 def signature_has_nongeneric_args(self):
1718 argcount = len(self.args)
1719 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1723 def signature_has_generic_args(self):
1724 return self.entry.signature.has_generic_args
1726 def declare_pyfunction(self, env):
1727 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1729 entry = env.lookup_here(self.name)
1730 if entry and entry.type.is_cfunction and not self.is_wrapper:
1731 warning(self.pos, "Overriding cdef method with def method.", 5)
1732 entry = env.declare_pyfunction(self.name, self.pos)
1734 prefix = env.scope_prefix
1735 entry.func_cname = \
1736 Naming.pyfunc_prefix + prefix + name
1737 entry.pymethdef_cname = \
1738 Naming.pymethdef_prefix + prefix + name
1739 if Options.docstrings:
1740 entry.doc = embed_position(self.pos, self.doc)
1742 Naming.funcdoc_prefix + prefix + name
1746 def declare_arguments(self, env):
1747 for arg in self.args:
1749 error(arg.pos, "Missing argument name")
1750 if arg.needs_conversion:
1751 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1752 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1753 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1754 if arg.type.is_pyobject:
1755 arg.entry.init = "0"
1756 arg.entry.init_to_none = 0
1758 arg.entry = self.declare_argument(env, arg)
1760 arg.entry.is_self_arg = arg.is_self_arg
1762 if arg.is_self_arg or \
1763 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1764 arg.entry.is_declared_generic = 1
1765 self.declare_python_arg(env, self.star_arg)
1766 self.declare_python_arg(env, self.starstar_arg)
1768 def declare_python_arg(self, env, arg):
1770 entry = env.declare_var(arg.name,
1771 PyrexTypes.py_object_type, arg.pos)
1774 entry.init_to_none = 0
1775 entry.xdecref_cleanup = 1
1777 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1779 def analyse_expressions(self, env):
1780 self.local_scope.directives = env.directives
1781 self.analyse_default_values(env)
1782 if env.is_py_class_scope:
1783 self.synthesize_assignment_node(env)
1785 def synthesize_assignment_node(self, env):
1787 self.assmt = SingleAssignmentNode(self.pos,
1788 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1789 rhs = ExprNodes.UnboundMethodNode(self.pos,
1790 function = ExprNodes.PyCFunctionNode(self.pos,
1791 pymethdef_cname = self.entry.pymethdef_cname)))
1792 self.assmt.analyse_declarations(env)
1793 self.assmt.analyse_expressions(env)
1795 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1797 sig = self.entry.signature
1798 if sig.has_dummy_arg:
1799 arg_code_list.append(
1800 "PyObject *%s" % Naming.self_cname)
1801 for arg in self.args:
1802 if not arg.is_generic:
1804 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1806 arg_code_list.append(
1807 arg.hdr_type.declaration_code(arg.hdr_cname))
1808 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1809 arg_code_list.append("PyObject *unused")
1810 if sig.has_generic_args:
1811 arg_code_list.append(
1812 "PyObject *%s, PyObject *%s"
1813 % (Naming.args_cname, Naming.kwds_cname))
1814 arg_code = ", ".join(arg_code_list)
1815 dc = self.return_type.declaration_code(self.entry.func_cname)
1816 header = "static %s(%s)" % (dc, arg_code)
1817 code.putln("%s; /*proto*/" % header)
1820 if self.entry.doc and Options.docstrings:
1821 docstr = self.entry.doc
1822 if not isinstance(docstr, str):
1823 docstr = docstr.utf8encode()
1825 'static char %s[] = "%s";' % (
1826 self.entry.doc_cname,
1827 split_docstring(escape_byte_string(docstr))))
1830 "static PyMethodDef %s = " %
1831 self.entry.pymethdef_cname)
1832 code.put_pymethoddef(self.entry, ";")
1833 code.putln("%s {" % header)
1835 def generate_argument_declarations(self, env, code):
1836 for arg in self.args:
1837 if arg.is_generic: # or arg.needs_conversion:
1838 if arg.needs_conversion:
1839 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1841 code.put_var_declaration(arg.entry)
1843 def generate_keyword_list(self, code):
1844 if self.signature_has_generic_args() and \
1845 self.signature_has_nongeneric_args():
1847 "static PyObject **%s[] = {" %
1848 Naming.pykwdlist_cname)
1849 for arg in self.args:
1851 pystring_cname = code.intern_identifier(arg.name)
1852 code.put('&%s,' % pystring_cname)
1855 def generate_argument_parsing_code(self, env, code):
1856 # Generate PyArg_ParseTuple call for generic
1857 # arguments, if any.
1858 if self.entry.signature.has_dummy_arg:
1859 # get rid of unused argument warning
1860 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1862 old_error_label = code.new_error_label()
1863 our_error_label = code.error_label
1864 end_label = code.new_label("argument_unpacking_done")
1866 has_kwonly_args = self.num_kwonly_args > 0
1867 has_star_or_kw_args = self.star_arg is not None \
1868 or self.starstar_arg is not None or has_kwonly_args
1870 if not self.signature_has_generic_args():
1871 if has_star_or_kw_args:
1872 error(self.pos, "This method cannot have * or keyword arguments")
1873 self.generate_argument_conversion_code(code)
1875 elif not self.signature_has_nongeneric_args():
1876 # func(*args) or func(**kw) or func(*args, **kw)
1877 self.generate_stararg_copy_code(code)
1880 positional_args = []
1883 for arg in self.args:
1884 arg_entry = arg.entry
1888 if not arg.is_self_arg:
1890 kw_only_args.append(arg)
1892 positional_args.append(arg)
1894 kw_only_args.append(arg)
1897 error(arg.pos, "Non-default argument following default argument")
1898 elif not arg.is_self_arg:
1899 positional_args.append(arg)
1901 self.generate_tuple_and_keyword_parsing_code(
1902 positional_args, kw_only_args, end_label, code)
1904 code.error_label = old_error_label
1905 if code.label_used(our_error_label):
1906 if not code.label_used(end_label):
1907 code.put_goto(end_label)
1908 code.put_label(our_error_label)
1909 if has_star_or_kw_args:
1910 self.generate_arg_decref(self.star_arg, code)
1911 if self.starstar_arg:
1912 if self.starstar_arg.entry.xdecref_cleanup:
1913 code.put_var_xdecref(self.starstar_arg.entry)
1915 code.put_var_decref(self.starstar_arg.entry)
1916 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1917 code.putln("return %s;" % self.error_value())
1918 if code.label_used(end_label):
1919 code.put_label(end_label)
1921 def generate_arg_assignment(self, arg, item, code):
1922 if arg.type.is_pyobject:
1924 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1925 code.putln("%s = %s;" % (arg.entry.cname, item))
1927 func = arg.type.from_py_function
1929 code.putln("%s = %s(%s); %s" % (
1933 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1935 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1937 def generate_arg_xdecref(self, arg, code):
1939 code.put_var_xdecref(arg.entry)
1941 def generate_arg_decref(self, arg, code):
1943 code.put_var_decref(arg.entry)
1945 def generate_stararg_copy_code(self, code):
1946 if not self.star_arg:
1947 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1948 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1950 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1951 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1954 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1956 if self.starstar_arg:
1958 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1960 kwarg_check = "%s" % Naming.kwds_cname
1962 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1963 Naming.kwds_cname, Naming.kwds_cname)
1965 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1966 kwarg_check, Naming.kwds_cname, self.name,
1967 bool(self.starstar_arg), self.error_value()))
1969 if self.starstar_arg:
1970 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1971 self.starstar_arg.entry.cname,
1974 code.putln("if (unlikely(!%s)) return %s;" % (
1975 self.starstar_arg.entry.cname, self.error_value()))
1976 self.starstar_arg.entry.xdecref_cleanup = 0
1977 code.put_gotref(self.starstar_arg.entry.cname)
1981 code.put_incref(Naming.args_cname, py_object_type)
1982 code.putln("%s = %s;" % (
1983 self.star_arg.entry.cname,
1985 self.star_arg.entry.xdecref_cleanup = 0
1987 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1988 kw_only_args, success_label, code):
1989 argtuple_error_label = code.new_label("argtuple_error")
1991 min_positional_args = self.num_required_args - self.num_required_kw_args
1992 if len(self.args) > 0 and self.args[0].is_self_arg:
1993 min_positional_args -= 1
1994 max_positional_args = len(positional_args)
1995 has_fixed_positional_count = not self.star_arg and \
1996 min_positional_args == max_positional_args
1998 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
1999 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2000 if self.num_required_kw_args:
2001 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2003 if self.starstar_arg or self.star_arg:
2004 self.generate_stararg_init_code(max_positional_args, code)
2006 # --- optimised code when we receive keyword arguments
2007 if self.num_required_kw_args:
2008 likely_hint = "likely"
2010 likely_hint = "unlikely"
2011 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2012 self.generate_keyword_unpacking_code(
2013 min_positional_args, max_positional_args,
2014 has_fixed_positional_count,
2015 positional_args, kw_only_args, argtuple_error_label, code)
2017 # --- optimised code when we do not receive any keyword arguments
2018 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2019 # Python raises arg tuple related errors first, so we must
2020 # check the length here
2021 if min_positional_args == max_positional_args and not self.star_arg:
2025 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2026 Naming.args_cname, compare, min_positional_args))
2027 code.put_goto(argtuple_error_label)
2029 if self.num_required_kw_args:
2030 # pure error case: keywords required but not passed
2031 if max_positional_args > min_positional_args and not self.star_arg:
2032 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2033 Naming.args_cname, max_positional_args))
2034 code.put_goto(argtuple_error_label)
2035 code.putln('} else {')
2036 for i, arg in enumerate(kw_only_args):
2038 pystring_cname = code.intern_identifier(arg.name)
2039 # required keyword-only argument missing
2040 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2041 self.name.utf8encode(),
2043 code.putln(code.error_goto(self.pos))
2046 elif min_positional_args == max_positional_args:
2047 # parse the exact number of positional arguments from the
2049 code.putln('} else {')
2050 for i, arg in enumerate(positional_args):
2051 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2052 self.generate_arg_assignment(arg, item, code)
2053 self.generate_arg_default_assignments(code)
2056 # parse the positional arguments from the variable length
2058 code.putln('} else {')
2059 self.generate_arg_default_assignments(code)
2060 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2062 code.putln('default:')
2063 reversed_args = list(enumerate(positional_args))[::-1]
2064 for i, arg in reversed_args:
2065 if i >= min_positional_args-1:
2066 if min_positional_args > 1:
2067 code.putln('case %2d:' % (i+1)) # pure code beautification
2069 code.put('case %2d: ' % (i+1))
2070 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2071 self.generate_arg_assignment(arg, item, code)
2072 if min_positional_args == 0:
2073 code.put('case 0: ')
2074 code.putln('break;')
2076 if min_positional_args:
2077 for i in range(min_positional_args-1, -1, -1):
2078 code.putln('case %2d:' % i)
2079 code.put_goto(argtuple_error_label)
2081 code.put('default: ')
2082 code.put_goto(argtuple_error_label)
2087 if code.label_used(argtuple_error_label):
2088 code.put_goto(success_label)
2089 code.put_label(argtuple_error_label)
2090 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2091 self.name.utf8encode(), has_fixed_positional_count,
2092 min_positional_args, max_positional_args,
2094 code.putln(code.error_goto(self.pos))
2096 def generate_arg_default_assignments(self, code):
2097 for arg in self.args:
2098 if arg.is_generic and arg.default:
2102 arg.calculate_default_value_code(code)))
2104 def generate_stararg_init_code(self, max_positional_args, code):
2105 if self.starstar_arg:
2106 self.starstar_arg.entry.xdecref_cleanup = 0
2107 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2108 self.starstar_arg.entry.cname,
2109 self.starstar_arg.entry.cname,
2110 self.error_value()))
2111 code.put_gotref(self.starstar_arg.entry.cname)
2113 self.star_arg.entry.xdecref_cleanup = 0
2114 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2116 max_positional_args))
2117 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2118 self.star_arg.entry.cname, Naming.args_cname,
2119 max_positional_args, Naming.args_cname))
2120 code.put_gotref(self.star_arg.entry.cname)
2121 if self.starstar_arg:
2123 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2124 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2125 code.putln('return %s;' % self.error_value())
2128 code.putln("if (unlikely(!%s)) return %s;" % (
2129 self.star_arg.entry.cname, self.error_value()))
2130 code.putln('} else {')
2131 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2132 code.put_incref(Naming.empty_tuple, py_object_type)
2135 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2136 has_fixed_positional_count, positional_args,
2137 kw_only_args, argtuple_error_label, code):
2138 all_args = tuple(positional_args) + tuple(kw_only_args)
2139 max_args = len(all_args)
2142 for i, arg in enumerate(all_args):
2143 if arg.default and arg.type.is_pyobject:
2144 default_value = arg.calculate_default_value_code(code)
2145 if arg.type is not PyrexTypes.py_object_type:
2146 default_value = "(PyObject*)"+default_value
2147 default_args.append((i, default_value))
2149 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2151 # it looks funny to separate the init-to-0 from setting the
2152 # default value, but C89 needs this
2153 code.putln("PyObject* values[%d] = {%s};" % (
2154 max_args, ','.join(['0']*max_args)))
2155 for i, default_value in default_args:
2156 code.putln('values[%d] = %s;' % (i, default_value))
2158 # parse the tuple and check that it's not too long
2159 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2161 code.putln('default:')
2162 for i in range(max_positional_args-1, -1, -1):
2163 code.put('case %2d: ' % (i+1))
2164 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2165 i, Naming.args_cname, i))
2166 code.putln('case 0: break;')
2167 if not self.star_arg:
2168 code.put('default: ') # more arguments than allowed
2169 code.put_goto(argtuple_error_label)
2172 # now fill up the positional/required arguments with values
2174 if self.num_required_args or max_positional_args > 0:
2175 last_required_arg = -1
2176 for i, arg in enumerate(all_args):
2178 last_required_arg = i
2179 if last_required_arg < max_positional_args:
2180 last_required_arg = max_positional_args-1
2181 num_required_args = self.num_required_args
2182 if max_positional_args > 0:
2183 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2184 for i, arg in enumerate(all_args[:last_required_arg+1]):
2185 if max_positional_args > 0 and i <= max_positional_args:
2186 if self.star_arg and i == max_positional_args:
2187 code.putln('default:')
2189 code.putln('case %2d:' % i)
2190 pystring_cname = code.intern_identifier(arg.name)
2193 # handled separately below
2195 code.putln('if (kw_args > %d) {' % num_required_args)
2196 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2197 Naming.kwds_cname, pystring_cname))
2198 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2201 num_required_args -= 1
2202 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2203 i, Naming.kwds_cname, pystring_cname))
2204 code.putln('if (likely(values[%d])) kw_args--;' % i);
2205 if i < min_positional_args:
2207 # special case: we know arg 0 is missing
2209 code.put_goto(argtuple_error_label)
2211 # print the correct number of values (args or
2212 # kwargs) that were passed into positional
2213 # arguments up to this point
2214 code.putln('else {')
2215 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2216 self.name.utf8encode(), has_fixed_positional_count,
2217 min_positional_args, max_positional_args, i))
2218 code.putln(code.error_goto(self.pos))
2221 code.putln('else {')
2222 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2223 self.name.utf8encode(), pystring_cname))
2224 code.putln(code.error_goto(self.pos))
2226 if max_positional_args > 0:
2229 if kw_only_args and not self.starstar_arg:
2230 # unpack optional keyword-only arguments
2231 # checking for interned strings in a dict is faster than iterating
2232 # but it's too likely that we must iterate if we expect **kwargs
2234 for i, arg in enumerate(all_args[max_positional_args:]):
2235 if not arg.kw_only or not arg.default:
2237 optional_args.append((i+max_positional_args, arg))
2239 # this mimics an unrolled loop so that we can "break" out of it
2240 code.putln('while (kw_args > 0) {')
2241 code.putln('PyObject* value;')
2242 for i, arg in optional_args:
2243 pystring_cname = code.intern_identifier(arg.name)
2245 'value = PyDict_GetItem(%s, %s);' % (
2246 Naming.kwds_cname, pystring_cname))
2248 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2249 code.putln('break;')
2252 code.putln('if (unlikely(kw_args > 0)) {')
2253 # non-positional/-required kw args left in dict: default args,
2254 # kw-only args, **kwargs or error
2256 # This is sort of a catch-all: except for checking required
2257 # arguments, this will always do the right thing for unpacking
2258 # keyword arguments, so that we can concentrate on optimising
2259 # common cases above.
2260 if max_positional_args == 0:
2263 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2264 Naming.args_cname, max_positional_args,
2265 Naming.args_cname, max_positional_args))
2266 pos_arg_count = "used_pos_args"
2268 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2269 code.globalstate.use_utility_code(parse_keywords_utility_code)
2271 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2273 Naming.pykwdlist_cname,
2274 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2276 self.name.utf8encode()))
2277 code.putln(code.error_goto(self.pos))
2280 # convert arg values to their final type and assign them
2281 for i, arg in enumerate(all_args):
2282 if arg.default and not arg.type.is_pyobject:
2283 code.putln("if (values[%d]) {" % i)
2284 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2285 if arg.default and not arg.type.is_pyobject:
2286 code.putln('} else {')
2290 arg.calculate_default_value_code(code)))
2293 def generate_argument_conversion_code(self, code):
2294 # Generate code to convert arguments from
2295 # signature type to declared type, if needed.
2296 for arg in self.args:
2297 if arg.needs_conversion:
2298 self.generate_arg_conversion(arg, code)
2300 def generate_arg_conversion(self, arg, code):
2301 # Generate conversion code for one argument.
2302 old_type = arg.hdr_type
2304 if old_type.is_pyobject:
2306 code.putln("if (%s) {" % arg.hdr_cname)
2308 code.putln("assert(%s); {" % arg.hdr_cname)
2309 self.generate_arg_conversion_from_pyobject(arg, code)
2311 elif new_type.is_pyobject:
2312 self.generate_arg_conversion_to_pyobject(arg, code)
2314 if new_type.assignable_from(old_type):
2316 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2319 "Cannot convert 1 argument from '%s' to '%s'" %
2320 (old_type, new_type))
2322 def generate_arg_conversion_from_pyobject(self, arg, code):
2324 func = new_type.from_py_function
2325 # copied from CoerceFromPyTypeNode
2327 code.putln("%s = %s(%s); %s" % (
2331 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2334 "Cannot convert Python object argument to type '%s'"
2337 def generate_arg_conversion_to_pyobject(self, arg, code):
2338 old_type = arg.hdr_type
2339 func = old_type.to_py_function
2341 code.putln("%s = %s(%s); %s" % (
2345 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2346 code.put_var_gotref(arg.entry)
2349 "Cannot convert argument of type '%s' to Python object"
2352 def generate_argument_type_tests(self, code):
2353 # Generate type tests for args whose signature
2354 # type is PyObject * and whose declared type is
2355 # a subtype thereof.
2356 for arg in self.args:
2357 if arg.needs_type_test:
2358 self.generate_arg_type_test(arg, code)
2360 def generate_arg_type_test(self, arg, code):
2361 # Generate type test for one argument.
2362 if arg.type.typeobj_is_available():
2363 typeptr_cname = arg.type.typeptr_cname
2364 arg_code = "((PyObject *)%s)" % arg.entry.cname
2366 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2371 arg.type.is_builtin_type,
2372 code.error_goto(arg.pos)))
2374 error(arg.pos, "Cannot test type of extern C class "
2375 "without type object name specification")
2377 def error_value(self):
2378 return self.entry.signature.error_value
2380 def caller_will_check_exceptions(self):
2383 class OverrideCheckNode(StatNode):
2384 # A Node for dispatching to the def method if it
2393 child_attrs = ['body']
2397 def analyse_expressions(self, env):
2398 self.args = env.arg_entries
2399 if self.py_func.is_module_scope:
2404 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2405 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2406 call_node = ExprNodes.SimpleCallNode(self.pos,
2407 function=self.func_node,
2408 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2409 self.body = ReturnStatNode(self.pos, value=call_node)
2410 self.body.analyse_expressions(env)
2412 def generate_execution_code(self, code):
2413 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2414 # Check to see if we are an extension type
2415 if self.py_func.is_module_scope:
2416 self_arg = "((PyObject *)%s)" % Naming.module_cname
2418 self_arg = "((PyObject *)%s)" % self.args[0].cname
2419 code.putln("/* Check if called by wrapper */")
2420 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2421 code.putln("/* Check if overriden in Python */")
2422 if self.py_func.is_module_scope:
2423 code.putln("else {")
2425 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2426 self.func_node.allocate(code)
2427 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2428 # need to get attribute manually--scope would return cdef method
2429 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2430 self.func_node.result(), self_arg, interned_attr_cname, err))
2431 code.put_gotref(self.func_node.py_result())
2432 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2433 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2434 self.func_node.result(), self.py_func.entry.func_cname)
2435 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2436 self.body.generate_execution_code(code)
2438 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2440 self.func_node.release(code)
2442 class ClassDefNode(StatNode, BlockNode):
2445 class PyClassDefNode(ClassDefNode):
2446 # A Python class definition.
2448 # name EncodedString Name of the class
2449 # doc string or None
2450 # body StatNode Attribute definition code
2451 # entry Symtab.Entry
2452 # scope PyClassScope
2454 # The following subnodes are constructed internally:
2456 # dict DictNode Class dictionary
2457 # classobj ClassNode Class object
2458 # target NameNode Variable to assign class object to
2460 child_attrs = ["body", "dict", "classobj", "target"]
2462 def __init__(self, pos, name, bases, doc, body):
2463 StatNode.__init__(self, pos)
2468 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2469 if self.doc and Options.docstrings:
2470 doc = embed_position(self.pos, self.doc)
2471 doc_node = ExprNodes.StringNode(pos, value = doc)
2474 self.classobj = ExprNodes.ClassNode(pos, name = name,
2475 bases = bases, dict = self.dict, doc = doc_node)
2476 self.target = ExprNodes.NameNode(pos, name = name)
2478 def as_cclass(self):
2480 Return this node as if it were declared as an extension class
2482 bases = self.classobj.bases.args
2484 base_class_name = None
2485 base_class_module = None
2486 elif len(bases) == 1:
2489 from ExprNodes import AttributeNode, NameNode
2490 while isinstance(base, AttributeNode):
2491 path.insert(0, base.attribute)
2493 if isinstance(base, NameNode):
2494 path.insert(0, base.name)
2495 base_class_name = path[-1]
2497 base_class_module = u'.'.join(path[:-1])
2499 base_class_module = None
2501 error(self.classobj.bases.args.pos, "Invalid base class")
2503 error(self.classobj.bases.args.pos, "C class may only have one base class")
2506 return CClassDefNode(self.pos,
2507 visibility = 'private',
2509 class_name = self.name,
2510 base_class_module = base_class_module,
2511 base_class_name = base_class_name,
2516 def create_scope(self, env):
2518 while env.is_py_class_scope or env.is_c_class_scope:
2519 env = env.outer_scope
2520 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2523 def analyse_declarations(self, env):
2524 self.target.analyse_target_declaration(env)
2525 cenv = self.create_scope(env)
2526 cenv.directives = env.directives
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 self.body.analyse_expressions(cenv)
2536 self.target.analyse_target_expression(env, self.classobj)
2538 def generate_function_definitions(self, env, code):
2539 self.body.generate_function_definitions(self.scope, code)
2541 def generate_execution_code(self, code):
2542 code.pyclass_stack.append(self)
2544 self.dict.generate_evaluation_code(code)
2545 self.classobj.generate_evaluation_code(code)
2546 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2547 self.body.generate_execution_code(code)
2548 self.target.generate_assignment_code(self.classobj, code)
2549 self.dict.generate_disposal_code(code)
2550 self.dict.free_temps(code)
2551 code.pyclass_stack.pop()
2554 class CClassDefNode(ClassDefNode):
2555 # An extension type definition.
2557 # visibility 'private' or 'public' or 'extern'
2558 # typedef_flag boolean
2560 # module_name string or None For import of extern type objects
2561 # class_name string Unqualified name of class
2562 # as_name string or None Name to declare as in this scope
2563 # base_class_module string or None Module containing the base class
2564 # base_class_name string or None Name of the base class
2565 # objstruct_name string or None Specified C name of object struct
2566 # typeobj_name string or None Specified C name of type object
2567 # in_pxd boolean Is in a .pxd file
2568 # doc string or None
2569 # body StatNode or None
2570 # entry Symtab.Entry
2571 # base_type PyExtensionType or None
2572 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2573 # buffer_defaults_pos
2575 child_attrs = ["body"]
2576 buffer_defaults_node = None
2577 buffer_defaults_pos = None
2578 typedef_flag = False
2580 objstruct_name = None
2583 def analyse_declarations(self, env):
2584 #print "CClassDefNode.analyse_declarations:", self.class_name
2585 #print "...visibility =", self.visibility
2586 #print "...module_name =", self.module_name
2589 if self.buffer_defaults_node:
2590 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2591 env, [], self.buffer_defaults_node,
2592 need_complete=False)
2594 buffer_defaults = None
2596 if env.in_cinclude and not self.objstruct_name:
2597 error(self.pos, "Object struct name specification required for "
2598 "C class defined in 'extern from' block")
2599 self.base_type = None
2600 # Now that module imports are cached, we need to
2601 # import the modules for extern classes.
2602 if self.module_name:
2604 for module in env.cimported_modules:
2605 if module.name == self.module_name:
2606 self.module = module
2607 if self.module is None:
2608 self.module = ModuleScope(self.module_name, None, env.context)
2609 self.module.has_extern_class = 1
2610 env.add_imported_module(self.module)
2612 if self.base_class_name:
2613 if self.base_class_module:
2614 base_class_scope = env.find_module(self.base_class_module, self.pos)
2616 base_class_scope = env
2617 if self.base_class_name == 'object':
2618 # extension classes are special and don't need to inherit from object
2619 if base_class_scope is None or base_class_scope.lookup('object') is None:
2620 self.base_class_name = None
2621 self.base_class_module = None
2622 base_class_scope = None
2623 if base_class_scope:
2624 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2625 if base_class_entry:
2626 if not base_class_entry.is_type:
2627 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2628 elif not base_class_entry.type.is_extension_type:
2629 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2630 elif not base_class_entry.type.is_complete():
2631 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2633 self.base_type = base_class_entry.type
2634 has_body = self.body is not None
2635 if self.module_name and self.visibility != 'extern':
2636 module_path = self.module_name.split(".")
2637 home_scope = env.find_imported_module(module_path, self.pos)
2643 if self.visibility == 'extern':
2644 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2645 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2647 self.entry = home_scope.declare_c_class(
2648 name = self.class_name,
2650 defining = has_body and self.in_pxd,
2651 implementing = has_body and not self.in_pxd,
2652 module_name = self.module_name,
2653 base_type = self.base_type,
2654 objstruct_cname = self.objstruct_name,
2655 typeobj_cname = self.typeobj_name,
2656 visibility = self.visibility,
2657 typedef_flag = self.typedef_flag,
2659 buffer_defaults = buffer_defaults)
2660 if home_scope is not env and self.visibility == 'extern':
2661 env.add_imported_entry(self.class_name, self.entry, pos)
2662 scope = self.entry.type.scope
2663 if scope is not None:
2664 scope.directives = env.directives
2666 if self.doc and Options.docstrings:
2667 scope.doc = embed_position(self.pos, self.doc)
2670 self.body.analyse_declarations(scope)
2674 scope.implemented = 1
2675 env.allocate_vtable_names(self.entry)
2677 def analyse_expressions(self, env):
2679 scope = self.entry.type.scope
2680 self.body.analyse_expressions(scope)
2682 def generate_function_definitions(self, env, code):
2684 self.body.generate_function_definitions(
2685 self.entry.type.scope, code)
2687 def generate_execution_code(self, code):
2688 # This is needed to generate evaluation code for
2689 # default values of method arguments.
2691 self.body.generate_execution_code(code)
2693 def annotate(self, code):
2695 self.body.annotate(code)
2698 class PropertyNode(StatNode):
2699 # Definition of a property in an extension type.
2702 # doc EncodedString or None Doc string
2705 child_attrs = ["body"]
2707 def analyse_declarations(self, env):
2708 entry = env.declare_property(self.name, self.doc, self.pos)
2710 entry.scope.directives = env.directives
2711 self.body.analyse_declarations(entry.scope)
2713 def analyse_expressions(self, env):
2714 self.body.analyse_expressions(env)
2716 def generate_function_definitions(self, env, code):
2717 self.body.generate_function_definitions(env, code)
2719 def generate_execution_code(self, code):
2722 def annotate(self, code):
2723 self.body.annotate(code)
2726 class GlobalNode(StatNode):
2727 # Global variable declaration.
2733 def analyse_declarations(self, env):
2734 for name in self.names:
2735 env.declare_global(name, self.pos)
2737 def analyse_expressions(self, env):
2740 def generate_execution_code(self, code):
2744 class ExprStatNode(StatNode):
2745 # Expression used as a statement.
2749 child_attrs = ["expr"]
2751 def analyse_declarations(self, env):
2753 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2754 func = self.expr.function.as_cython_attribute()
2755 if func == u'declare':
2756 args, kwds = self.expr.explicit_args_kwds()
2758 error(self.expr.pos, "Variable names must be specified.")
2759 for var, type_node in kwds.key_value_pairs:
2760 type = type_node.analyse_as_type(env)
2762 error(type_node.pos, "Unknown type")
2764 env.declare_var(var.value, type, var.pos, is_cdef = True)
2765 self.__class__ = PassStatNode
2767 def analyse_expressions(self, env):
2768 self.expr.analyse_expressions(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)
2793 # def analyse_expressions(self, env):
2794 # self.analyse_expressions_1(env)
2795 # self.analyse_expressions_2(env)
2797 def generate_execution_code(self, code):
2798 self.generate_rhs_evaluation_code(code)
2799 self.generate_assignment_code(code)
2802 class SingleAssignmentNode(AssignmentNode):
2803 # The simplest case:
2807 # lhs ExprNode Left hand side
2808 # rhs ExprNode Right hand side
2809 # first bool Is this guaranteed the first assignment to lhs?
2811 child_attrs = ["lhs", "rhs"]
2813 declaration_only = False
2815 def analyse_declarations(self, env):
2818 # handle declarations of the form x = cython.foo()
2819 if isinstance(self.rhs, ExprNodes.CallNode):
2820 func_name = self.rhs.function.as_cython_attribute()
2822 args, kwds = self.rhs.explicit_args_kwds()
2824 if func_name in ['declare', 'typedef']:
2825 if len(args) > 2 or kwds is not None:
2826 error(rhs.pos, "Can only declare one type at a time.")
2828 type = args[0].analyse_as_type(env)
2830 error(args[0].pos, "Unknown type")
2833 if func_name == 'declare':
2834 if isinstance(lhs, ExprNodes.NameNode):
2835 vars = [(lhs.name, lhs.pos)]
2836 elif isinstance(lhs, ExprNodes.TupleNode):
2837 vars = [(var.name, var.pos) for var in lhs.args]
2839 error(lhs.pos, "Invalid declaration")
2841 for var, pos in vars:
2842 env.declare_var(var, type, pos, is_cdef = True)
2847 self.declaration_only = True
2849 self.declaration_only = True
2850 if not isinstance(lhs, ExprNodes.NameNode):
2851 error(lhs.pos, "Invalid declaration.")
2852 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2854 elif func_name in ['struct', 'union']:
2855 self.declaration_only = True
2856 if len(args) > 0 or kwds is None:
2857 error(rhs.pos, "Struct or union members must be given by name.")
2860 for member, type_node in kwds.key_value_pairs:
2861 type = type_node.analyse_as_type(env)
2863 error(type_node.pos, "Unknown type")
2865 members.append((member.value, type, member.pos))
2866 if len(members) < len(kwds.key_value_pairs):
2868 if not isinstance(self.lhs, ExprNodes.NameNode):
2869 error(self.lhs.pos, "Invalid declaration.")
2870 name = self.lhs.name
2871 scope = StructOrUnionScope(name)
2872 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2873 for member, type, pos in members:
2874 scope.declare_var(member, type, pos)
2876 if self.declaration_only:
2879 self.lhs.analyse_target_declaration(env)
2881 def analyse_types(self, env, use_temp = 0):
2882 self.rhs.analyse_types(env)
2883 self.lhs.analyse_target_types(env)
2884 self.lhs.gil_assignment_check(env)
2885 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2887 self.rhs = self.rhs.coerce_to_temp(env)
2889 def generate_rhs_evaluation_code(self, code):
2890 self.rhs.generate_evaluation_code(code)
2892 def generate_assignment_code(self, code):
2893 self.lhs.generate_assignment_code(self.rhs, code)
2895 def annotate(self, code):
2896 self.lhs.annotate(code)
2897 self.rhs.annotate(code)
2900 class CascadedAssignmentNode(AssignmentNode):
2901 # An assignment with multiple left hand sides:
2905 # lhs_list [ExprNode] Left hand sides
2906 # rhs ExprNode Right hand sides
2910 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2912 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2913 coerced_rhs_list = None
2915 def analyse_declarations(self, env):
2916 for lhs in self.lhs_list:
2917 lhs.analyse_target_declaration(env)
2919 def analyse_types(self, env, use_temp = 0):
2920 self.rhs.analyse_types(env)
2922 self.rhs = self.rhs.coerce_to_temp(env)
2924 self.rhs = self.rhs.coerce_to_simple(env)
2925 from ExprNodes import CloneNode
2926 self.coerced_rhs_list = []
2927 for lhs in self.lhs_list:
2928 lhs.analyse_target_types(env)
2929 lhs.gil_assignment_check(env)
2930 rhs = CloneNode(self.rhs)
2931 rhs = rhs.coerce_to(lhs.type, env)
2932 self.coerced_rhs_list.append(rhs)
2934 def generate_rhs_evaluation_code(self, code):
2935 self.rhs.generate_evaluation_code(code)
2937 def generate_assignment_code(self, code):
2938 for i in range(len(self.lhs_list)):
2939 lhs = self.lhs_list[i]
2940 rhs = self.coerced_rhs_list[i]
2941 rhs.generate_evaluation_code(code)
2942 lhs.generate_assignment_code(rhs, code)
2943 # Assignment has disposed of the cloned RHS
2944 self.rhs.generate_disposal_code(code)
2945 self.rhs.free_temps(code)
2947 def annotate(self, code):
2948 for i in range(len(self.lhs_list)):
2949 lhs = self.lhs_list[i].annotate(code)
2950 rhs = self.coerced_rhs_list[i].annotate(code)
2951 self.rhs.annotate(code)
2954 class ParallelAssignmentNode(AssignmentNode):
2955 # A combined packing/unpacking assignment:
2959 # This has been rearranged by the parser into
2961 # a = d ; b = e ; c = f
2963 # but we must evaluate all the right hand sides
2964 # before assigning to any of the left hand sides.
2966 # stats [AssignmentNode] The constituent assignments
2968 child_attrs = ["stats"]
2970 def analyse_declarations(self, env):
2971 for stat in self.stats:
2972 stat.analyse_declarations(env)
2974 def analyse_expressions(self, env):
2975 for stat in self.stats:
2976 stat.analyse_types(env, use_temp = 1)
2978 # def analyse_expressions(self, env):
2979 # for stat in self.stats:
2980 # stat.analyse_expressions_1(env, use_temp = 1)
2981 # for stat in self.stats:
2982 # stat.analyse_expressions_2(env)
2984 def generate_execution_code(self, code):
2985 for stat in self.stats:
2986 stat.generate_rhs_evaluation_code(code)
2987 for stat in self.stats:
2988 stat.generate_assignment_code(code)
2990 def annotate(self, code):
2991 for stat in self.stats:
2995 class InPlaceAssignmentNode(AssignmentNode):
2996 # An in place arithmatic operand:
3002 # lhs ExprNode Left hand side
3003 # rhs ExprNode Right hand side
3004 # op char one of "+-*/%^&|"
3005 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3007 # This code is a bit tricky because in order to obey Python
3008 # semantics the sub-expressions (e.g. indices) of the lhs must
3009 # not be evaluated twice. So we must re-use the values calculated
3010 # in evaluation phase for the assignment phase as well.
3011 # Fortunately, the type of the lhs node is fairly constrained
3012 # (it must be a NameNode, AttributeNode, or IndexNode).
3014 child_attrs = ["lhs", "rhs"]
3017 def analyse_declarations(self, env):
3018 self.lhs.analyse_target_declaration(env)
3020 def analyse_types(self, env):
3021 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3022 self.rhs.analyse_types(env)
3023 self.lhs.analyse_target_types(env)
3024 if Options.incref_local_binop and self.dup.type.is_pyobject:
3025 self.dup = self.dup.coerce_to_temp(env)
3027 if self.lhs.type.is_pyobject:
3028 self.rhs = self.rhs.coerce_to_pyobject(env)
3029 elif self.rhs.type.is_pyobject:
3030 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3031 if self.lhs.type.is_pyobject:
3032 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3033 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3035 def generate_execution_code(self, code):
3037 self.rhs.generate_evaluation_code(code)
3038 self.dup.generate_subexpr_evaluation_code(code)
3039 if self.dup.is_temp:
3040 self.dup.allocate_temp_result(code)
3041 # self.dup.generate_result_code is run only if it is not buffer access
3042 if self.operator == "**":
3046 if self.lhs.type.is_pyobject:
3047 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3048 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3049 self.dup.generate_result_code(code)
3050 self.result_value_temp.allocate(code)
3052 "%s = %s(%s, %s%s); %s" % (
3053 self.result_value.result(),
3054 self.py_operation_function(),
3055 self.dup.py_result(),
3056 self.rhs.py_result(),
3058 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3059 code.put_gotref(self.result_value.py_result())
3060 self.result_value.generate_evaluation_code(code) # May be a type check...
3061 self.rhs.generate_disposal_code(code)
3062 self.rhs.free_temps(code)
3063 self.dup.generate_disposal_code(code)
3064 self.dup.free_temps(code)
3065 self.lhs.generate_assignment_code(self.result_value, code)
3066 self.result_value_temp.release(code)
3068 c_op = self.operator
3072 if self.lhs.type.is_int and self.rhs.type.is_int:
3073 error(self.pos, "** with two C int types is ambiguous")
3075 error(self.pos, "No C inplace power operator")
3076 # have to do assignment directly to avoid side-effects
3077 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3078 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3080 self.dup.generate_result_code(code)
3081 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3082 self.rhs.generate_disposal_code(code)
3083 self.rhs.free_temps(code)
3084 if self.dup.is_temp:
3085 self.dup.generate_subexpr_disposal_code(code)
3086 self.dup.free_subexpr_temps(code)
3088 def create_dup_node(self, env):
3091 self.dup.analyse_types(env)
3092 if isinstance(self.lhs, ExprNodes.NameNode):
3093 target_lhs = ExprNodes.NameNode(self.dup.pos,
3094 name = self.dup.name,
3095 is_temp = self.dup.is_temp,
3096 entry = self.dup.entry)
3097 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3098 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3099 obj = ExprNodes.CloneNode(self.lhs.obj),
3100 attribute = self.dup.attribute,
3101 is_temp = self.dup.is_temp)
3102 elif isinstance(self.lhs, ExprNodes.IndexNode):
3104 index = ExprNodes.CloneNode(self.lhs.index)
3107 if self.lhs.indices:
3108 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3111 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3112 base = ExprNodes.CloneNode(self.dup.base),
3115 is_temp = self.dup.is_temp)
3118 self.lhs = target_lhs
3121 def py_operation_function(self):
3122 return self.py_functions[self.operator]
3125 "|": "PyNumber_InPlaceOr",
3126 "^": "PyNumber_InPlaceXor",
3127 "&": "PyNumber_InPlaceAnd",
3128 "+": "PyNumber_InPlaceAdd",
3129 "-": "PyNumber_InPlaceSubtract",
3130 "*": "PyNumber_InPlaceMultiply",
3131 "/": "PyNumber_InPlaceDivide",
3132 "%": "PyNumber_InPlaceRemainder",
3133 "<<": "PyNumber_InPlaceLshift",
3134 ">>": "PyNumber_InPlaceRshift",
3135 "**": "PyNumber_InPlacePower",
3136 "//": "PyNumber_InPlaceFloorDivide",
3139 def annotate(self, code):
3140 self.lhs.annotate(code)
3141 self.rhs.annotate(code)
3142 self.dup.annotate(code)
3145 class PrintStatNode(StatNode):
3148 # arg_tuple TupleNode
3149 # append_newline boolean
3151 child_attrs = ["arg_tuple"]
3153 def analyse_expressions(self, env):
3154 self.arg_tuple.analyse_expressions(env)
3155 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3156 env.use_utility_code(printing_utility_code)
3157 if len(self.arg_tuple.args) == 1 and self.append_newline:
3158 env.use_utility_code(printing_one_utility_code)
3160 gil_check = StatNode._gil_check
3161 gil_message = "Python print statement"
3163 def generate_execution_code(self, code):
3164 if len(self.arg_tuple.args) == 1 and self.append_newline:
3165 arg = self.arg_tuple.args[0]
3166 arg.generate_evaluation_code(code)
3169 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3171 code.error_goto(self.pos)))
3172 arg.generate_disposal_code(code)
3173 arg.free_temps(code)
3175 self.arg_tuple.generate_evaluation_code(code)
3177 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3178 self.arg_tuple.py_result(),
3179 self.append_newline,
3180 code.error_goto(self.pos)))
3181 self.arg_tuple.generate_disposal_code(code)
3182 self.arg_tuple.free_temps(code)
3184 def annotate(self, code):
3185 self.arg_tuple.annotate(code)
3188 class ExecStatNode(StatNode):
3193 child_attrs = ["args"]
3195 def analyse_expressions(self, env):
3196 for i, arg in enumerate(self.args):
3197 arg.analyse_expressions(env)
3198 arg = arg.coerce_to_pyobject(env)
3200 env.use_utility_code(Builtin.pyexec_utility_code)
3202 gil_check = StatNode._gil_check
3203 gil_message = "Python exec statement"
3205 def generate_execution_code(self, code):
3207 for arg in self.args:
3208 arg.generate_evaluation_code(code)
3209 args.append( arg.py_result() )
3210 args = tuple(args + ['0', '0'][:3-len(args)])
3211 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3212 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3213 (temp_result,) + args))
3214 for arg in self.args:
3215 arg.generate_disposal_code(code)
3216 arg.free_temps(code)
3218 code.error_goto_if_null(temp_result, self.pos))
3219 code.put_gotref(temp_result)
3220 code.put_decref_clear(temp_result, py_object_type)
3221 code.funcstate.release_temp(temp_result)
3223 def annotate(self, code):
3224 for arg in self.args:
3228 class DelStatNode(StatNode):
3233 child_attrs = ["args"]
3235 def analyse_declarations(self, env):
3236 for arg in self.args:
3237 arg.analyse_target_declaration(env)
3239 def analyse_expressions(self, env):
3240 for arg in self.args:
3241 arg.analyse_target_expression(env, None)
3242 if not arg.type.is_pyobject:
3243 error(arg.pos, "Deletion of non-Python object")
3244 #arg.release_target_temp(env)
3246 def gil_check(self, env):
3247 for arg in self.args:
3248 if arg.type.is_pyobject:
3249 self._gil_check(env)
3251 gil_message = "Deleting Python object"
3253 def generate_execution_code(self, code):
3254 for arg in self.args:
3255 if arg.type.is_pyobject:
3256 arg.generate_deletion_code(code)
3257 # else error reported earlier
3259 def annotate(self, code):
3260 for arg in self.args:
3264 class PassStatNode(StatNode):
3269 def analyse_expressions(self, env):
3272 def generate_execution_code(self, code):
3276 class BreakStatNode(StatNode):
3280 def analyse_expressions(self, env):
3283 def generate_execution_code(self, code):
3284 if not code.break_label:
3285 error(self.pos, "break statement not inside loop")
3287 code.put_goto(code.break_label)
3290 class ContinueStatNode(StatNode):
3294 def analyse_expressions(self, env):
3297 def generate_execution_code(self, code):
3298 if code.funcstate.in_try_finally:
3299 error(self.pos, "continue statement inside try of try...finally")
3300 elif not code.continue_label:
3301 error(self.pos, "continue statement not inside loop")
3303 code.put_goto(code.continue_label)
3306 class ReturnStatNode(StatNode):
3309 # value ExprNode or None
3310 # return_type PyrexType
3312 child_attrs = ["value"]
3314 def analyse_expressions(self, env):
3315 return_type = env.return_type
3316 self.return_type = return_type
3318 error(self.pos, "Return not inside a function body")
3321 self.value.analyse_types(env)
3322 if return_type.is_void or return_type.is_returncode:
3323 error(self.value.pos,
3324 "Return with value in void function")
3326 self.value = self.value.coerce_to(env.return_type, env)
3328 if (not return_type.is_void
3329 and not return_type.is_pyobject
3330 and not return_type.is_returncode):
3331 error(self.pos, "Return value required")
3333 def gil_check(self, env):
3334 if self.return_type.is_pyobject:
3335 self._gil_check(env)
3337 gil_message = "Returning Python object"
3339 def generate_execution_code(self, code):
3340 code.mark_pos(self.pos)
3341 if not self.return_type:
3342 # error reported earlier
3344 if self.return_type.is_pyobject:
3345 code.put_xdecref(Naming.retval_cname,
3348 self.value.generate_evaluation_code(code)
3349 self.value.make_owned_reference(code)
3352 Naming.retval_cname,
3353 self.value.result_as(self.return_type)))
3354 self.value.generate_post_assignment_code(code)
3355 self.value.free_temps(code)
3357 if self.return_type.is_pyobject:
3358 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3359 elif self.return_type.is_returncode:
3362 Naming.retval_cname,
3363 self.return_type.default_value))
3364 for cname, type in code.funcstate.temps_holding_reference():
3365 code.put_decref_clear(cname, type)
3366 code.put_goto(code.return_label)
3368 def annotate(self, code):
3370 self.value.annotate(code)
3373 class RaiseStatNode(StatNode):
3376 # exc_type ExprNode or None
3377 # exc_value ExprNode or None
3378 # exc_tb ExprNode or None
3380 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3382 def analyse_expressions(self, env):
3384 self.exc_type.analyse_types(env)
3385 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3387 self.exc_value.analyse_types(env)
3388 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3390 self.exc_tb.analyse_types(env)
3391 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3392 env.use_utility_code(raise_utility_code)
3393 env.use_utility_code(restore_exception_utility_code)
3395 gil_check = StatNode._gil_check
3396 gil_message = "Raising exception"
3398 def generate_execution_code(self, code):
3400 self.exc_type.generate_evaluation_code(code)
3401 type_code = self.exc_type.py_result()
3405 self.exc_value.generate_evaluation_code(code)
3406 value_code = self.exc_value.py_result()
3410 self.exc_tb.generate_evaluation_code(code)
3411 tb_code = self.exc_tb.py_result()
3414 if self.exc_type or self.exc_value or self.exc_tb:
3416 "__Pyx_Raise(%s, %s, %s);" % (
3423 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3425 obj.generate_disposal_code(code)
3426 obj.free_temps(code)
3428 code.error_goto(self.pos))
3430 def annotate(self, code):
3432 self.exc_type.annotate(code)
3434 self.exc_value.annotate(code)
3436 self.exc_tb.annotate(code)
3439 class ReraiseStatNode(StatNode):
3443 def analyse_expressions(self, env):
3444 env.use_utility_code(raise_utility_code)
3445 env.use_utility_code(restore_exception_utility_code)
3447 gil_check = StatNode._gil_check
3448 gil_message = "Raising exception"
3450 def generate_execution_code(self, code):
3451 vars = code.funcstate.exc_vars
3453 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3454 code.putln(code.error_goto(self.pos))
3456 error(self.pos, "Reraise not inside except clause")
3459 class AssertStatNode(StatNode):
3463 # value ExprNode or None
3465 child_attrs = ["cond", "value"]
3467 def analyse_expressions(self, env):
3468 self.cond = self.cond.analyse_boolean_expression(env)
3470 self.value.analyse_types(env)
3471 self.value = self.value.coerce_to_pyobject(env)
3473 gil_check = StatNode._gil_check
3474 gil_message = "Raising exception"
3476 def generate_execution_code(self, code):
3477 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3478 self.cond.generate_evaluation_code(code)
3480 "if (unlikely(!%s)) {" %
3483 self.value.generate_evaluation_code(code)
3485 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3486 self.value.py_result())
3487 self.value.generate_disposal_code(code)
3488 self.value.free_temps(code)
3491 "PyErr_SetNone(PyExc_AssertionError);")
3493 code.error_goto(self.pos))
3496 self.cond.generate_disposal_code(code)
3497 self.cond.free_temps(code)
3498 code.putln("#endif")
3500 def annotate(self, code):
3501 self.cond.annotate(code)
3503 self.value.annotate(code)
3506 class IfStatNode(StatNode):
3509 # if_clauses [IfClauseNode]
3510 # else_clause StatNode or None
3512 child_attrs = ["if_clauses", "else_clause"]
3514 def analyse_control_flow(self, env):
3515 env.start_branching(self.pos)
3516 for if_clause in self.if_clauses:
3517 if_clause.analyse_control_flow(env)
3518 env.next_branch(if_clause.end_pos())
3519 if self.else_clause:
3520 self.else_clause.analyse_control_flow(env)
3521 env.finish_branching(self.end_pos())
3523 def analyse_declarations(self, env):
3524 for if_clause in self.if_clauses:
3525 if_clause.analyse_declarations(env)
3526 if self.else_clause:
3527 self.else_clause.analyse_declarations(env)
3529 def analyse_expressions(self, env):
3530 for if_clause in self.if_clauses:
3531 if_clause.analyse_expressions(env)
3532 if self.else_clause:
3533 self.else_clause.analyse_expressions(env)
3535 def generate_execution_code(self, code):
3536 code.mark_pos(self.pos)
3537 end_label = code.new_label()
3538 for if_clause in self.if_clauses:
3539 if_clause.generate_execution_code(code, end_label)
3540 if self.else_clause:
3541 code.putln("/*else*/ {")
3542 self.else_clause.generate_execution_code(code)
3544 code.put_label(end_label)
3546 def annotate(self, code):
3547 for if_clause in self.if_clauses:
3548 if_clause.annotate(code)
3549 if self.else_clause:
3550 self.else_clause.annotate(code)
3553 class IfClauseNode(Node):
3554 # if or elif clause in an if statement
3556 # condition ExprNode
3559 child_attrs = ["condition", "body"]
3561 def analyse_control_flow(self, env):
3562 self.body.analyse_control_flow(env)
3564 def analyse_declarations(self, env):
3565 self.condition.analyse_declarations(env)
3566 self.body.analyse_declarations(env)
3568 def analyse_expressions(self, env):
3570 self.condition.analyse_temp_boolean_expression(env)
3571 self.body.analyse_expressions(env)
3573 def generate_execution_code(self, code, end_label):
3574 self.condition.generate_evaluation_code(code)
3577 self.condition.result())
3578 self.condition.generate_disposal_code(code)
3579 self.condition.free_temps(code)
3580 self.body.generate_execution_code(code)
3584 code.put_goto(end_label)
3587 def annotate(self, code):
3588 self.condition.annotate(code)
3589 self.body.annotate(code)
3592 class SwitchCaseNode(StatNode):
3593 # Generated in the optimization of an if-elif-else node
3595 # conditions [ExprNode]
3598 child_attrs = ['conditions', 'body']
3600 def generate_execution_code(self, code):
3601 for cond in self.conditions:
3602 code.mark_pos(cond.pos)
3603 cond.generate_evaluation_code(code)
3604 code.putln("case %s:" % cond.result())
3605 self.body.generate_execution_code(code)
3606 code.putln("break;")
3608 def annotate(self, code):
3609 for cond in self.conditions:
3611 self.body.annotate(code)
3613 class SwitchStatNode(StatNode):
3614 # Generated in the optimization of an if-elif-else node
3617 # cases [SwitchCaseNode]
3618 # else_clause StatNode or None
3620 child_attrs = ['test', 'cases', 'else_clause']
3622 def generate_execution_code(self, code):
3623 code.putln("switch (%s) {" % self.test.result())
3624 for case in self.cases:
3625 case.generate_execution_code(code)
3626 if self.else_clause is not None:
3627 code.putln("default:")
3628 self.else_clause.generate_execution_code(code)
3629 code.putln("break;")
3632 def annotate(self, code):
3633 self.test.annotate(code)
3634 for case in self.cases:
3636 if self.else_clause is not None:
3637 self.else_clause.annotate(code)
3639 class LoopNode(object):
3641 def analyse_control_flow(self, env):
3642 env.start_branching(self.pos)
3643 self.body.analyse_control_flow(env)
3644 env.next_branch(self.body.end_pos())
3645 if self.else_clause:
3646 self.else_clause.analyse_control_flow(env)
3647 env.finish_branching(self.end_pos())
3650 class WhileStatNode(LoopNode, StatNode):
3653 # condition ExprNode
3655 # else_clause StatNode
3657 child_attrs = ["condition", "body", "else_clause"]
3659 def analyse_declarations(self, env):
3660 self.body.analyse_declarations(env)
3661 if self.else_clause:
3662 self.else_clause.analyse_declarations(env)
3664 def analyse_expressions(self, env):
3666 self.condition.analyse_temp_boolean_expression(env)
3667 self.body.analyse_expressions(env)
3668 if self.else_clause:
3669 self.else_clause.analyse_expressions(env)
3671 def generate_execution_code(self, code):
3672 old_loop_labels = code.new_loop_labels()
3675 self.condition.generate_evaluation_code(code)
3676 self.condition.generate_disposal_code(code)
3679 self.condition.result())
3680 self.condition.free_temps(code)
3681 self.body.generate_execution_code(code)
3682 code.put_label(code.continue_label)
3684 break_label = code.break_label
3685 code.set_loop_labels(old_loop_labels)
3686 if self.else_clause:
3687 code.putln("/*else*/ {")
3688 self.else_clause.generate_execution_code(code)
3690 code.put_label(break_label)
3692 def annotate(self, code):
3693 self.condition.annotate(code)
3694 self.body.annotate(code)
3695 if self.else_clause:
3696 self.else_clause.annotate(code)
3699 def ForStatNode(pos, **kw):
3700 if 'iterator' in kw:
3701 return ForInStatNode(pos, **kw)
3703 return ForFromStatNode(pos, **kw)
3705 class ForInStatNode(LoopNode, StatNode):
3709 # iterator IteratorNode
3711 # else_clause StatNode
3712 # item NextNode used internally
3714 child_attrs = ["target", "iterator", "body", "else_clause"]
3717 def analyse_declarations(self, env):
3718 self.target.analyse_target_declaration(env)
3719 self.body.analyse_declarations(env)
3720 if self.else_clause:
3721 self.else_clause.analyse_declarations(env)
3723 def analyse_expressions(self, env):
3725 self.target.analyse_target_types(env)
3726 self.iterator.analyse_expressions(env)
3727 self.item = ExprNodes.NextNode(self.iterator, env)
3728 self.item = self.item.coerce_to(self.target.type, env)
3729 self.body.analyse_expressions(env)
3730 if self.else_clause:
3731 self.else_clause.analyse_expressions(env)
3733 def generate_execution_code(self, code):
3734 old_loop_labels = code.new_loop_labels()
3735 self.iterator.allocate_counter_temp(code)
3736 self.iterator.generate_evaluation_code(code)
3739 self.item.generate_evaluation_code(code)
3740 self.target.generate_assignment_code(self.item, code)
3741 self.body.generate_execution_code(code)
3742 code.put_label(code.continue_label)
3745 break_label = code.break_label
3746 code.set_loop_labels(old_loop_labels)
3747 if self.else_clause:
3748 code.putln("/*else*/ {")
3749 self.else_clause.generate_execution_code(code)
3751 code.put_label(break_label)
3752 self.iterator.release_counter_temp(code)
3753 self.iterator.generate_disposal_code(code)
3754 self.iterator.free_temps(code)
3756 def annotate(self, code):
3757 self.target.annotate(code)
3758 self.iterator.annotate(code)
3759 self.body.annotate(code)
3760 if self.else_clause:
3761 self.else_clause.annotate(code)
3762 self.item.annotate(code)
3765 class ForFromStatNode(LoopNode, StatNode):
3766 # for name from expr rel name rel expr
3773 # step ExprNode or None
3775 # else_clause StatNode or None
3781 # loopvar_node ExprNode (usually a NameNode or temp node)
3782 # py_loopvar_node PyTempNode or None
3783 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3785 is_py_target = False
3787 py_loopvar_node = None
3790 def analyse_declarations(self, env):
3791 self.target.analyse_target_declaration(env)
3792 self.body.analyse_declarations(env)
3793 if self.else_clause:
3794 self.else_clause.analyse_declarations(env)
3796 def analyse_expressions(self, env):
3798 self.target.analyse_target_types(env)
3799 self.bound1.analyse_types(env)
3800 self.bound2.analyse_types(env)
3801 if self.step is not None:
3802 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3803 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3804 self.step.analyse_types(env)
3806 target_type = self.target.type
3807 if self.target.type.is_numeric:
3808 loop_type = self.target.type
3810 loop_type = PyrexTypes.c_int_type
3811 if not self.bound1.type.is_pyobject:
3812 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3813 if not self.bound2.type.is_pyobject:
3814 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3815 if self.step is not None and not self.step.type.is_pyobject:
3816 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3817 self.bound1 = self.bound1.coerce_to(loop_type, env)
3818 self.bound2 = self.bound2.coerce_to(loop_type, env)
3819 if not self.bound2.is_literal:
3820 self.bound2 = self.bound2.coerce_to_temp(env)
3821 if self.step is not None:
3822 self.step = self.step.coerce_to(loop_type, env)
3823 if not self.step.is_literal:
3824 self.step = self.step.coerce_to_temp(env)
3826 target_type = self.target.type
3827 if not (target_type.is_pyobject or target_type.is_numeric):
3828 error(self.target.pos,
3829 "for-from loop variable must be c numeric type or Python object")
3830 if target_type.is_numeric:
3831 self.is_py_target = False
3832 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3833 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3834 self.loopvar_node = self.target
3835 self.py_loopvar_node = None
3837 self.is_py_target = True
3838 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3839 self.loopvar_node = c_loopvar_node
3840 self.py_loopvar_node = \
3841 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3842 self.body.analyse_expressions(env)
3843 if self.else_clause:
3844 self.else_clause.analyse_expressions(env)
3846 def generate_execution_code(self, code):
3847 old_loop_labels = code.new_loop_labels()
3848 from_range = self.from_range
3849 self.bound1.generate_evaluation_code(code)
3850 self.bound2.generate_evaluation_code(code)
3851 offset, incop = self.relation_table[self.relation1]
3852 if self.step is not None:
3853 self.step.generate_evaluation_code(code)
3854 step = self.step.result()
3855 incop = "%s=%s" % (incop[0], step)
3857 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3858 self.loopvar_node.allocate(code)
3859 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3860 self.py_loopvar_node.allocate(code)
3862 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3864 loopvar_name = self.loopvar_node.result()
3866 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3868 self.bound1.result(), offset,
3869 loopvar_name, self.relation2, self.bound2.result(),
3870 loopvar_name, incop))
3871 if self.py_loopvar_node:
3872 self.py_loopvar_node.generate_evaluation_code(code)
3873 self.target.generate_assignment_code(self.py_loopvar_node, code)
3875 code.putln("%s = %s;" % (
3876 self.target.result(), loopvar_name))
3877 self.body.generate_execution_code(code)
3878 code.put_label(code.continue_label)
3879 if self.py_loopvar_node:
3880 # This mess is to make for..from loops with python targets behave
3881 # exactly like those with C targets with regards to re-assignment
3882 # of the loop variable.
3884 if self.target.entry.is_pyglobal:
3885 # We know target is a NameNode, this is the only ugly case.
3886 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3887 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
3888 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3889 target_node.result_code,
3890 Naming.module_cname,
3891 self.target.entry.interned_cname,
3892 code.error_goto_if_null(target_node.result_code, self.target.pos)))
3893 code.put_gotref(target_node.result_code)
3895 target_node = self.target
3896 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3897 from_py_node.temp_code = loopvar_name
3898 from_py_node.generate_result_code(code)
3899 if self.target.entry.is_pyglobal:
3900 code.put_decref_clear(target_node.result_code, py_object_type)
3901 code.funcstate.release_temp(target_node.result_code)
3903 if self.py_loopvar_node:
3904 # This is potentially wasteful, but we don't want the semantics to
3905 # depend on whether or not the loop is a python type.
3906 self.py_loopvar_node.generate_evaluation_code(code)
3907 self.target.generate_assignment_code(self.py_loopvar_node, code)
3908 break_label = code.break_label
3909 code.set_loop_labels(old_loop_labels)
3910 if self.else_clause:
3911 code.putln("/*else*/ {")
3912 self.else_clause.generate_execution_code(code)
3914 code.put_label(break_label)
3915 self.bound1.generate_disposal_code(code)
3916 self.bound1.free_temps(code)
3917 self.bound2.generate_disposal_code(code)
3918 self.bound2.free_temps(code)
3919 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3920 self.loopvar_node.release(code)
3921 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3922 self.py_loopvar_node.release(code)
3923 if self.step is not None:
3924 self.step.generate_disposal_code(code)
3925 self.step.free_temps(code)
3928 # {relop : (initial offset, increment op)}
3935 def annotate(self, code):
3936 self.target.annotate(code)
3937 self.bound1.annotate(code)
3938 self.bound2.annotate(code)
3940 self.bound2.annotate(code)
3941 self.body.annotate(code)
3942 if self.else_clause:
3943 self.else_clause.annotate(code)
3946 class WithStatNode(StatNode):
3948 Represents a Python with statement.
3950 This is only used at parse tree level; and is not present in
3951 analysis or generation phases.
3953 # manager The with statement manager object
3954 # target Node (lhs expression)
3956 child_attrs = ["manager", "target", "body"]
3958 class TryExceptStatNode(StatNode):
3959 # try .. except statement
3962 # except_clauses [ExceptClauseNode]
3963 # else_clause StatNode or None
3965 child_attrs = ["body", "except_clauses", "else_clause"]
3967 def analyse_control_flow(self, env):
3968 env.start_branching(self.pos)
3969 self.body.analyse_control_flow(env)
3970 successful_try = env.control_flow # grab this for later
3971 env.next_branch(self.body.end_pos())
3972 env.finish_branching(self.body.end_pos())
3974 env.start_branching(self.except_clauses[0].pos)
3975 for except_clause in self.except_clauses:
3976 except_clause.analyse_control_flow(env)
3977 env.next_branch(except_clause.end_pos())
3979 # the else cause it executed only when the try clause finishes
3980 env.control_flow.incoming = successful_try
3981 if self.else_clause:
3982 self.else_clause.analyse_control_flow(env)
3983 env.finish_branching(self.end_pos())
3985 def analyse_declarations(self, env):
3986 self.body.analyse_declarations(env)
3987 for except_clause in self.except_clauses:
3988 except_clause.analyse_declarations(env)
3989 if self.else_clause:
3990 self.else_clause.analyse_declarations(env)
3991 env.use_utility_code(reset_exception_utility_code)
3993 def analyse_expressions(self, env):
3994 self.body.analyse_expressions(env)
3995 default_clause_seen = 0
3996 for except_clause in self.except_clauses:
3997 except_clause.analyse_expressions(env)
3998 if default_clause_seen:
3999 error(except_clause.pos, "default 'except:' must be last")
4000 if not except_clause.pattern:
4001 default_clause_seen = 1
4002 self.has_default_clause = default_clause_seen
4003 if self.else_clause:
4004 self.else_clause.analyse_expressions(env)
4006 gil_check = StatNode._gil_check
4007 gil_message = "Try-except statement"
4009 def generate_execution_code(self, code):
4010 old_return_label = code.return_label
4011 old_break_label = code.break_label
4012 old_continue_label = code.continue_label
4013 old_error_label = code.new_error_label()
4014 our_error_label = code.error_label
4015 except_end_label = code.new_label('exception_handled')
4016 except_error_label = code.new_label('except_error')
4017 except_return_label = code.new_label('except_return')
4018 try_return_label = code.new_label('try_return')
4019 try_break_label = code.new_label('try_break')
4020 try_continue_label = code.new_label('try_continue')
4021 try_end_label = code.new_label('try_end')
4024 code.putln("PyObject %s;" %
4025 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4026 code.putln("__Pyx_ExceptionSave(%s);" %
4027 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4028 for var in Naming.exc_save_vars:
4029 code.put_xgotref(var)
4032 code.return_label = try_return_label
4033 code.break_label = try_break_label
4034 code.continue_label = try_continue_label
4035 self.body.generate_execution_code(code)
4038 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4039 code.error_label = except_error_label
4040 code.return_label = except_return_label
4041 if self.else_clause:
4044 self.else_clause.generate_execution_code(code)
4047 for var in Naming.exc_save_vars:
4048 code.put_xdecref_clear(var, py_object_type)
4049 code.put_goto(try_end_label)
4050 if code.label_used(try_return_label):
4051 code.put_label(try_return_label)
4052 for var in Naming.exc_save_vars:
4053 code.put_xdecref_clear(var, py_object_type)
4054 code.put_goto(old_return_label)
4055 code.put_label(our_error_label)
4056 for temp_name, type in temps_to_clean_up:
4057 code.put_xdecref_clear(temp_name, type)
4058 for except_clause in self.except_clauses:
4059 except_clause.generate_handling_code(code, except_end_label)
4061 error_label_used = code.label_used(except_error_label)
4062 if error_label_used or not self.has_default_clause:
4063 if error_label_used:
4064 code.put_label(except_error_label)
4065 for var in Naming.exc_save_vars:
4066 code.put_xdecref(var, py_object_type)
4067 code.put_goto(old_error_label)
4069 if code.label_used(try_break_label):
4070 code.put_label(try_break_label)
4071 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4072 code.putln("__Pyx_ExceptionReset(%s);" %
4073 ', '.join(Naming.exc_save_vars))
4074 code.put_goto(old_break_label)
4076 if code.label_used(try_continue_label):
4077 code.put_label(try_continue_label)
4078 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4079 code.putln("__Pyx_ExceptionReset(%s);" %
4080 ', '.join(Naming.exc_save_vars))
4081 code.put_goto(old_continue_label)
4083 if code.label_used(except_return_label):
4084 code.put_label(except_return_label)
4085 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4086 code.putln("__Pyx_ExceptionReset(%s);" %
4087 ', '.join(Naming.exc_save_vars))
4088 code.put_goto(old_return_label)
4090 if code.label_used(except_end_label):
4091 code.put_label(except_end_label)
4092 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4093 code.putln("__Pyx_ExceptionReset(%s);" %
4094 ', '.join(Naming.exc_save_vars))
4095 code.put_label(try_end_label)
4098 code.return_label = old_return_label
4099 code.break_label = old_break_label
4100 code.continue_label = old_continue_label
4101 code.error_label = old_error_label
4103 def annotate(self, code):
4104 self.body.annotate(code)
4105 for except_node in self.except_clauses:
4106 except_node.annotate(code)
4107 if self.else_clause:
4108 self.else_clause.annotate(code)
4111 class ExceptClauseNode(Node):
4112 # Part of try ... except statement.
4115 # target ExprNode or None
4117 # excinfo_target NameNode or None optional target for exception info
4118 # match_flag string result of exception match
4119 # exc_value ExcValueNode used internally
4120 # function_name string qualified name of enclosing function
4121 # exc_vars (string * 3) local exception variables
4123 # excinfo_target is never set by the parser, but can be set by a transform
4124 # in order to extract more extensive information about the exception as a
4125 # sys.exc_info()-style tuple into a target variable
4127 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4130 excinfo_target = None
4132 def analyse_declarations(self, env):
4134 self.target.analyse_target_declaration(env)
4135 if self.excinfo_target is not None:
4136 self.excinfo_target.analyse_target_declaration(env)
4137 self.body.analyse_declarations(env)
4139 def analyse_expressions(self, env):
4141 genv = env.global_scope()
4142 self.function_name = env.qualified_name
4144 self.pattern.analyse_expressions(env)
4145 self.pattern = self.pattern.coerce_to_pyobject(env)
4148 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4149 self.target.analyse_target_expression(env, self.exc_value)
4150 if self.excinfo_target is not None:
4152 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4153 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4154 self.excinfo_tuple.analyse_expressions(env)
4155 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4157 self.body.analyse_expressions(env)
4159 def generate_handling_code(self, code, end_label):
4160 code.mark_pos(self.pos)
4162 self.pattern.generate_evaluation_code(code)
4164 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4166 "%s = PyErr_ExceptionMatches(%s);" % (
4168 self.pattern.py_result()))
4169 self.pattern.generate_disposal_code(code)
4170 self.pattern.free_temps(code)
4174 code.funcstate.release_temp(match_flag)
4176 code.putln("/*except:*/ {")
4178 if not getattr(self.body, 'stats', True):
4179 # most simple case: no exception variable, empty body (pass)
4180 # => reset the exception state, done
4181 code.putln("PyErr_Restore(0,0,0);")
4182 code.put_goto(end_label)
4186 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4189 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4190 # We always have to fetch the exception value even if
4191 # there is no target, because this also normalises the
4192 # exception and stores it in the thread state.
4193 code.globalstate.use_utility_code(get_exception_utility_code)
4194 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4195 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4196 code.error_goto(self.pos)))
4200 self.exc_value.set_var(exc_vars[1])
4201 self.exc_value.generate_evaluation_code(code)
4202 self.target.generate_assignment_code(self.exc_value, code)
4203 if self.excinfo_target is not None:
4204 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4205 node.set_var(tempvar)
4206 self.excinfo_tuple.generate_evaluation_code(code)
4207 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4209 old_break_label, old_continue_label = code.break_label, code.continue_label
4210 code.break_label = code.new_label('except_break')
4211 code.continue_label = code.new_label('except_continue')
4213 old_exc_vars = code.funcstate.exc_vars
4214 code.funcstate.exc_vars = exc_vars
4215 self.body.generate_execution_code(code)
4216 code.funcstate.exc_vars = old_exc_vars
4217 for var in exc_vars:
4218 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4219 code.put_goto(end_label)
4221 if code.label_used(code.break_label):
4222 code.put_label(code.break_label)
4223 for var in exc_vars:
4224 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4225 code.put_goto(old_break_label)
4226 code.break_label = old_break_label
4228 if code.label_used(code.continue_label):
4229 code.put_label(code.continue_label)
4230 for var in exc_vars:
4231 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4232 code.put_goto(old_continue_label)
4233 code.continue_label = old_continue_label
4235 for temp in exc_vars:
4236 code.funcstate.release_temp(temp)
4241 def annotate(self, code):
4243 self.pattern.annotate(code)
4245 self.target.annotate(code)
4246 self.body.annotate(code)
4249 class TryFinallyStatNode(StatNode):
4250 # try ... finally statement
4253 # finally_clause StatNode
4255 # The plan is that we funnel all continue, break
4256 # return and error gotos into the beginning of the
4257 # finally block, setting a variable to remember which
4258 # one we're doing. At the end of the finally block, we
4259 # switch on the variable to figure out where to go.
4260 # In addition, if we're doing an error, we save the
4261 # exception on entry to the finally block and restore
4264 child_attrs = ["body", "finally_clause"]
4266 preserve_exception = 1
4268 disallow_continue_in_try_finally = 0
4269 # There doesn't seem to be any point in disallowing
4270 # continue in the try block, since we have no problem
4273 def create_analysed(pos, env, body, finally_clause):
4274 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4276 create_analysed = staticmethod(create_analysed)
4278 def analyse_control_flow(self, env):
4279 env.start_branching(self.pos)
4280 self.body.analyse_control_flow(env)
4281 env.next_branch(self.body.end_pos())
4282 env.finish_branching(self.body.end_pos())
4283 self.finally_clause.analyse_control_flow(env)
4285 def analyse_declarations(self, env):
4286 self.body.analyse_declarations(env)
4287 self.finally_clause.analyse_declarations(env)
4289 def analyse_expressions(self, env):
4290 self.body.analyse_expressions(env)
4291 self.finally_clause.analyse_expressions(env)
4293 gil_check = StatNode._gil_check
4294 gil_message = "Try-finally statement"
4296 def generate_execution_code(self, code):
4297 old_error_label = code.error_label
4298 old_labels = code.all_new_labels()
4299 new_labels = code.get_all_labels()
4300 new_error_label = code.error_label
4301 catch_label = code.new_label()
4304 if self.disallow_continue_in_try_finally:
4305 was_in_try_finally = code.funcstate.in_try_finally
4306 code.funcstate.in_try_finally = 1
4307 self.body.generate_execution_code(code)
4308 if self.disallow_continue_in_try_finally:
4309 code.funcstate.in_try_finally = was_in_try_finally
4312 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4316 error_label_used = 0
4317 for i, new_label in enumerate(new_labels):
4318 if new_label in code.labels_used:
4319 cases_used.append(i)
4320 if new_label == new_error_label:
4321 error_label_used = 1
4322 error_label_case = i
4326 if error_label_used and self.preserve_exception:
4328 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4330 "int %s;" % Naming.exc_lineno_name)
4331 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4332 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4333 code.putln(exc_var_init_zero)
4335 exc_var_init_zero = None
4336 code.use_label(catch_label)
4338 "__pyx_why = 0; goto %s;" % catch_label)
4339 for i in cases_used:
4340 new_label = new_labels[i]
4341 #if new_label and new_label != "<try>":
4342 if new_label == new_error_label and self.preserve_exception:
4343 self.put_error_catcher(code,
4344 new_error_label, i+1, catch_label, temps_to_clean_up)
4346 code.put('%s: ' % new_label)
4347 if exc_var_init_zero:
4348 code.putln(exc_var_init_zero)
4349 code.putln("__pyx_why = %s; goto %s;" % (
4352 code.put_label(catch_label)
4353 code.set_all_labels(old_labels)
4354 if error_label_used:
4355 code.new_error_label()
4356 finally_error_label = code.error_label
4357 self.finally_clause.generate_execution_code(code)
4358 if error_label_used:
4359 if finally_error_label in code.labels_used and self.preserve_exception:
4360 over_label = code.new_label()
4361 code.put_goto(over_label);
4362 code.put_label(finally_error_label)
4363 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4364 for var in Naming.exc_vars:
4365 code.putln("Py_XDECREF(%s);" % var)
4367 code.put_goto(old_error_label)
4368 code.put_label(over_label)
4369 code.error_label = old_error_label
4372 "switch (__pyx_why) {")
4373 for i in cases_used:
4374 old_label = old_labels[i]
4375 if old_label == old_error_label and self.preserve_exception:
4376 self.put_error_uncatcher(code, i+1, old_error_label)
4378 code.use_label(old_label)
4380 "case %s: goto %s;" % (
4388 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4389 code.globalstate.use_utility_code(restore_exception_utility_code)
4396 for temp_name, type in temps_to_clean_up:
4397 code.put_xdecref_clear(temp_name, type)
4399 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4403 Naming.exc_lineno_name, Naming.lineno_cname))
4407 code.put_goto(catch_label)
4411 def put_error_uncatcher(self, code, i, error_label):
4412 code.globalstate.use_utility_code(restore_exception_utility_code)
4417 "__Pyx_ErrRestore(%s, %s, %s);" %
4421 Naming.lineno_cname, Naming.exc_lineno_name))
4422 for var in Naming.exc_vars:
4426 code.put_goto(error_label)
4430 def annotate(self, code):
4431 self.body.annotate(code)
4432 self.finally_clause.annotate(code)
4435 class GILStatNode(TryFinallyStatNode):
4436 # 'with gil' or 'with nogil' statement
4438 # state string 'gil' or 'nogil'
4442 preserve_exception = 0
4444 def __init__(self, pos, state, body):
4446 TryFinallyStatNode.__init__(self, pos,
4448 finally_clause = GILExitNode(pos, state = state))
4450 def analyse_expressions(self, env):
4451 env.use_utility_code(force_init_threads_utility_code)
4452 was_nogil = env.nogil
4454 TryFinallyStatNode.analyse_expressions(self, env)
4455 env.nogil = was_nogil
4457 def gil_check(self, env):
4460 def generate_execution_code(self, code):
4461 code.mark_pos(self.pos)
4462 if self.state == 'gil':
4463 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4465 code.putln("{ PyThreadState *_save;")
4466 code.putln("Py_UNBLOCK_THREADS")
4467 TryFinallyStatNode.generate_execution_code(self, code)
4471 class GILExitNode(StatNode):
4472 # Used as the 'finally' block in a GILStatNode
4474 # state string 'gil' or 'nogil'
4478 def analyse_expressions(self, env):
4481 def generate_execution_code(self, code):
4482 if self.state == 'gil':
4483 code.putln("PyGILState_Release();")
4485 code.putln("Py_BLOCK_THREADS")
4488 class CImportStatNode(StatNode):
4491 # module_name string Qualified name of module being imported
4492 # as_name string or None Name specified in "as" clause, if any
4496 def analyse_declarations(self, env):
4497 if not env.is_module_scope:
4498 error(self.pos, "cimport only allowed at module level")
4500 module_scope = env.find_module(self.module_name, self.pos)
4501 if "." in self.module_name:
4502 names = [EncodedString(name) for name in self.module_name.split(".")]
4504 top_module_scope = env.context.find_submodule(top_name)
4505 module_scope = top_module_scope
4506 for name in names[1:]:
4507 submodule_scope = module_scope.find_submodule(name)
4508 module_scope.declare_module(name, submodule_scope, self.pos)
4509 module_scope = submodule_scope
4511 env.declare_module(self.as_name, module_scope, self.pos)
4513 env.declare_module(top_name, top_module_scope, self.pos)
4515 name = self.as_name or self.module_name
4516 env.declare_module(name, module_scope, self.pos)
4518 def analyse_expressions(self, env):
4521 def generate_execution_code(self, code):
4525 class FromCImportStatNode(StatNode):
4526 # from ... cimport statement
4528 # module_name string Qualified name of module
4529 # imported_names [(pos, name, as_name, kind)] Names to be imported
4533 def analyse_declarations(self, env):
4534 if not env.is_module_scope:
4535 error(self.pos, "cimport only allowed at module level")
4537 module_scope = env.find_module(self.module_name, self.pos)
4538 env.add_imported_module(module_scope)
4539 for pos, name, as_name, kind in self.imported_names:
4541 for local_name, entry in module_scope.entries.items():
4542 env.add_imported_entry(local_name, entry, pos)
4544 entry = module_scope.lookup(name)
4546 if kind and not self.declaration_matches(entry, kind):
4547 entry.redeclared(pos)
4549 if kind == 'struct' or kind == 'union':
4550 entry = module_scope.declare_struct_or_union(name,
4551 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4552 elif kind == 'class':
4553 entry = module_scope.declare_c_class(name, pos = pos,
4554 module_name = self.module_name)
4556 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4557 if submodule_scope.parent_module is module_scope:
4558 env.declare_module(as_name or name, submodule_scope, self.pos)
4560 error(pos, "Name '%s' not declared in module '%s'"
4561 % (name, self.module_name))
4564 local_name = as_name or name
4565 env.add_imported_entry(local_name, entry, pos)
4567 def declaration_matches(self, entry, kind):
4568 if not entry.is_type:
4572 if not type.is_extension_type:
4575 if not type.is_struct_or_union:
4577 if kind != type.kind:
4581 def analyse_expressions(self, env):
4584 def generate_execution_code(self, code):
4588 class FromImportStatNode(StatNode):
4589 # from ... import statement
4592 # items [(string, NameNode)]
4593 # interned_items [(string, NameNode, ExprNode)]
4594 # item PyTempNode used internally
4595 # import_star boolean used internally
4597 child_attrs = ["module"]
4600 def analyse_declarations(self, env):
4601 for name, target in self.items:
4603 if not env.is_module_scope:
4604 error(self.pos, "import * only allowed at module level")
4606 env.has_import_star = 1
4607 self.import_star = 1
4609 target.analyse_target_declaration(env)
4611 def analyse_expressions(self, env):
4613 self.module.analyse_expressions(env)
4614 self.item = ExprNodes.PyTempNode(self.pos, env)
4615 self.interned_items = []
4616 for name, target in self.items:
4618 for _, entry in env.entries.items():
4619 if not entry.is_type and entry.type.is_extension_type:
4620 env.use_utility_code(ExprNodes.type_test_utility_code)
4623 entry = env.lookup(target.name)
4624 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4625 continue # already cimported
4626 target.analyse_target_expression(env, None)
4627 if target.type is py_object_type:
4630 coerced_item = self.item.coerce_to(target.type, env)
4631 self.interned_items.append(
4632 (name, target, coerced_item))
4634 def generate_execution_code(self, code):
4635 self.module.generate_evaluation_code(code)
4636 if self.import_star:
4638 'if (%s(%s) < 0) %s;' % (
4640 self.module.py_result(),
4641 code.error_goto(self.pos)))
4642 self.item.allocate(code)
4643 for name, target, coerced_item in self.interned_items:
4644 cname = code.intern_identifier(name)
4646 '%s = PyObject_GetAttr(%s, %s); %s' % (
4648 self.module.py_result(),
4650 code.error_goto_if_null(self.item.result(), self.pos)))
4651 code.put_gotref(self.item.py_result())
4652 if coerced_item is None:
4653 target.generate_assignment_code(self.item, code)
4655 coerced_item.allocate_temp_result(code)
4656 coerced_item.generate_result_code(code)
4657 target.generate_assignment_code(coerced_item, code)
4658 if self.item.result() != coerced_item.result():
4659 code.put_decref_clear(self.item.result(), self.item.type)
4660 self.item.release(code)
4661 self.module.generate_disposal_code(code)
4662 self.module.free_temps(code)
4666 #------------------------------------------------------------------------------------
4668 # Runtime support code
4670 #------------------------------------------------------------------------------------
4672 utility_function_predeclarations = \
4675 #define INLINE __inline__
4677 #define INLINE __inline
4682 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4686 static int %(skip_dispatch_cname)s = 0;
4688 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4690 if Options.gcc_branch_hints:
4691 branch_prediction_macros = \
4694 /* Test for GCC > 2.95 */
4695 #if __GNUC__ > 2 || \
4696 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4697 #define likely(x) __builtin_expect(!!(x), 1)
4698 #define unlikely(x) __builtin_expect(!!(x), 0)
4699 #else /* __GNUC__ > 2 ... */
4700 #define likely(x) (x)
4701 #define unlikely(x) (x)
4702 #endif /* __GNUC__ > 2 ... */
4703 #else /* __GNUC__ */
4704 #define likely(x) (x)
4705 #define unlikely(x) (x)
4706 #endif /* __GNUC__ */
4709 branch_prediction_macros = \
4711 #define likely(x) (x)
4712 #define unlikely(x) (x)
4715 #get_name_predeclaration = \
4716 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4718 #get_name_interned_predeclaration = \
4719 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4721 #------------------------------------------------------------------------------------
4723 printing_utility_code = UtilityCode(
4725 static int __Pyx_Print(PyObject *, int); /*proto*/
4726 #if PY_MAJOR_VERSION >= 3
4727 static PyObject* %s = 0;
4728 static PyObject* %s = 0;
4730 """ % (Naming.print_function, Naming.print_function_kwargs),
4732 #if PY_MAJOR_VERSION < 3
4733 static PyObject *__Pyx_GetStdout(void) {
4734 PyObject *f = PySys_GetObject((char *)"stdout");
4736 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4741 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4746 if (!(f = __Pyx_GetStdout()))
4748 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4749 if (PyFile_SoftSpace(f, 1)) {
4750 if (PyFile_WriteString(" ", f) < 0)
4753 v = PyTuple_GET_ITEM(arg_tuple, i);
4754 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4756 if (PyString_Check(v)) {
4757 char *s = PyString_AsString(v);
4758 Py_ssize_t len = PyString_Size(v);
4760 isspace(Py_CHARMASK(s[len-1])) &&
4762 PyFile_SoftSpace(f, 0);
4766 if (PyFile_WriteString("\n", f) < 0)
4768 PyFile_SoftSpace(f, 0);
4773 #else /* Python 3 has a print function */
4775 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4776 PyObject* kwargs = 0;
4777 PyObject* result = 0;
4778 PyObject* end_string;
4779 if (!%(PRINT_FUNCTION)s) {
4780 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4781 if (!%(PRINT_FUNCTION)s)
4785 if (!%(PRINT_KWARGS)s) {
4786 %(PRINT_KWARGS)s = PyDict_New();
4787 if (!%(PRINT_KWARGS)s)
4789 end_string = PyUnicode_FromStringAndSize(" ", 1);
4792 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4793 Py_DECREF(end_string);
4796 Py_DECREF(end_string);
4798 kwargs = %(PRINT_KWARGS)s;
4800 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4808 """ % {'BUILTINS' : Naming.builtins_cname,
4809 'PRINT_FUNCTION' : Naming.print_function,
4810 'PRINT_KWARGS' : Naming.print_function_kwargs}
4814 printing_one_utility_code = UtilityCode(
4816 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4819 #if PY_MAJOR_VERSION < 3
4821 static int __Pyx_PrintOne(PyObject *o) {
4823 if (!(f = __Pyx_GetStdout()))
4825 if (PyFile_SoftSpace(f, 0)) {
4826 if (PyFile_WriteString(" ", f) < 0)
4829 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4831 if (PyFile_WriteString("\n", f) < 0)
4834 /* the line below is just to avoid compiler
4835 * compiler warnings about unused functions */
4836 return __Pyx_Print(NULL, 0);
4839 #else /* Python 3 has a print function */
4841 static int __Pyx_PrintOne(PyObject *o) {
4843 PyObject* arg_tuple = PyTuple_New(1);
4844 if (unlikely(!arg_tuple))
4847 PyTuple_SET_ITEM(arg_tuple, 0, o);
4848 res = __Pyx_Print(arg_tuple, 1);
4849 Py_DECREF(arg_tuple);
4855 requires=[printing_utility_code])
4859 #------------------------------------------------------------------------------------
4861 # The following function is based on do_raise() from ceval.c.
4863 raise_utility_code = UtilityCode(
4865 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4868 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4872 /* First, check the traceback argument, replacing None with NULL. */
4873 if (tb == Py_None) {
4877 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4878 PyErr_SetString(PyExc_TypeError,
4879 "raise: arg 3 must be a traceback or None");
4882 /* Next, replace a missing value with None */
4883 if (value == NULL) {
4887 #if PY_VERSION_HEX < 0x02050000
4888 if (!PyClass_Check(type))
4890 if (!PyType_Check(type))
4893 /* Raising an instance. The value should be a dummy. */
4894 if (value != Py_None) {
4895 PyErr_SetString(PyExc_TypeError,
4896 "instance exception may not have a separate value");
4899 /* Normalize to raise <class>, <instance> */
4902 #if PY_VERSION_HEX < 0x02050000
4903 if (PyInstance_Check(type)) {
4904 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4909 PyErr_SetString(PyExc_TypeError,
4910 "raise: exception must be an old-style class or instance");
4914 type = (PyObject*) Py_TYPE(type);
4916 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4917 PyErr_SetString(PyExc_TypeError,
4918 "raise: exception class must be a subclass of BaseException");
4923 __Pyx_ErrRestore(type, value, tb);
4933 #------------------------------------------------------------------------------------
4935 reraise_utility_code = UtilityCode(
4937 static void __Pyx_ReRaise(void); /*proto*/
4940 static void __Pyx_ReRaise(void) {
4941 PyThreadState *tstate = PyThreadState_GET();
4942 PyObject* tmp_type = tstate->curexc_type;
4943 PyObject* tmp_value = tstate->curexc_value;
4944 PyObject* tmp_tb = tstate->curexc_traceback;
4945 tstate->curexc_type = tstate->exc_type;
4946 tstate->curexc_value = tstate->exc_value;
4947 tstate->curexc_traceback = tstate->exc_traceback;
4948 tstate->exc_type = 0;
4949 tstate->exc_value = 0;
4950 tstate->exc_traceback = 0;
4951 Py_XDECREF(tmp_type);
4952 Py_XDECREF(tmp_value);
4957 #------------------------------------------------------------------------------------
4959 arg_type_test_utility_code = UtilityCode(
4961 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4962 const char *name, int exact); /*proto*/
4965 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4966 const char *name, int exact)
4969 PyErr_Format(PyExc_SystemError, "Missing type object");
4972 if (none_allowed && obj == Py_None) return 1;
4974 if (Py_TYPE(obj) == type) return 1;
4977 if (PyObject_TypeCheck(obj, type)) return 1;
4979 PyErr_Format(PyExc_TypeError,
4980 "Argument '%s' has incorrect type (expected %s, got %s)",
4981 name, type->tp_name, Py_TYPE(obj)->tp_name);
4986 #------------------------------------------------------------------------------------
4988 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
4989 # many or too few positional arguments were found. This handles
4990 # Py_ssize_t formatting correctly.
4992 raise_argtuple_invalid_utility_code = UtilityCode(
4994 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
4995 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
4998 static void __Pyx_RaiseArgtupleInvalid(
4999 const char* func_name,
5003 Py_ssize_t num_found)
5005 Py_ssize_t num_expected;
5006 const char *number, *more_or_less;
5008 if (num_found < num_min) {
5009 num_expected = num_min;
5010 more_or_less = "at least";
5012 num_expected = num_max;
5013 more_or_less = "at most";
5016 more_or_less = "exactly";
5018 number = (num_expected == 1) ? "" : "s";
5019 PyErr_Format(PyExc_TypeError,
5020 #if PY_VERSION_HEX < 0x02050000
5021 "%s() takes %s %d positional argument%s (%d given)",
5023 "%s() takes %s %zd positional argument%s (%zd given)",
5025 func_name, more_or_less, num_expected, number, num_found);
5029 raise_keyword_required_utility_code = UtilityCode(
5031 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5034 static INLINE void __Pyx_RaiseKeywordRequired(
5035 const char* func_name,
5038 PyErr_Format(PyExc_TypeError,
5039 #if PY_MAJOR_VERSION >= 3
5040 "%s() needs keyword-only argument %U", func_name, kw_name);
5042 "%s() needs keyword-only argument %s", func_name,
5043 PyString_AS_STRING(kw_name));
5048 raise_double_keywords_utility_code = UtilityCode(
5050 static void __Pyx_RaiseDoubleKeywordsError(
5051 const char* func_name, PyObject* kw_name); /*proto*/
5054 static void __Pyx_RaiseDoubleKeywordsError(
5055 const char* func_name,
5058 PyErr_Format(PyExc_TypeError,
5059 #if PY_MAJOR_VERSION >= 3
5060 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5062 "%s() got multiple values for keyword argument '%s'", func_name,
5063 PyString_AS_STRING(kw_name));
5068 #------------------------------------------------------------------------------------
5070 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5071 # were passed to a function, or if any keywords were passed to a
5072 # function that does not accept them.
5074 keyword_string_check_utility_code = UtilityCode(
5076 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5077 const char* function_name, int kw_allowed); /*proto*/
5080 static INLINE int __Pyx_CheckKeywordStrings(
5082 const char* function_name,
5087 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5088 #if PY_MAJOR_VERSION < 3
5089 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5091 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5093 goto invalid_keyword_type;
5095 if ((!kw_allowed) && unlikely(key))
5096 goto invalid_keyword;
5098 invalid_keyword_type:
5099 PyErr_Format(PyExc_TypeError,
5100 "%s() keywords must be strings", function_name);
5103 PyErr_Format(PyExc_TypeError,
5104 #if PY_MAJOR_VERSION < 3
5105 "%s() got an unexpected keyword argument '%s'",
5106 function_name, PyString_AsString(key));
5108 "%s() got an unexpected keyword argument '%U'",
5109 function_name, key);
5115 #------------------------------------------------------------------------------------
5117 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5118 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5119 # keywords will raise an invalid keyword error.
5121 # Three kinds of errors are checked: 1) non-string keywords, 2)
5122 # unexpected keywords and 3) overlap with positional arguments.
5124 # If num_posargs is greater 0, it denotes the number of positional
5125 # arguments that were passed and that must therefore not appear
5126 # amongst the keywords as well.
5128 # This method does not check for required keyword arguments.
5131 parse_keywords_utility_code = UtilityCode(
5133 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5134 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5135 const char* function_name); /*proto*/
5138 static int __Pyx_ParseOptionalKeywords(
5140 PyObject **argnames[],
5143 Py_ssize_t num_pos_args,
5144 const char* function_name)
5146 PyObject *key = 0, *value = 0;
5149 PyObject*** first_kw_arg = argnames + num_pos_args;
5151 while (PyDict_Next(kwds, &pos, &key, &value)) {
5152 name = first_kw_arg;
5153 while (*name && (**name != key)) name++;
5155 values[name-argnames] = value;
5157 #if PY_MAJOR_VERSION < 3
5158 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5160 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5162 goto invalid_keyword_type;
5164 for (name = first_kw_arg; *name; name++) {
5165 #if PY_MAJOR_VERSION >= 3
5166 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5167 PyUnicode_Compare(**name, key) == 0) break;
5169 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5170 _PyString_Eq(**name, key)) break;
5174 values[name-argnames] = value;
5176 /* unexpected keyword found */
5177 for (name=argnames; name != first_kw_arg; name++) {
5178 if (**name == key) goto arg_passed_twice;
5179 #if PY_MAJOR_VERSION >= 3
5180 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5181 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5183 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5184 _PyString_Eq(**name, key)) goto arg_passed_twice;
5188 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5190 goto invalid_keyword;
5198 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5200 invalid_keyword_type:
5201 PyErr_Format(PyExc_TypeError,
5202 "%s() keywords must be strings", function_name);
5205 PyErr_Format(PyExc_TypeError,
5206 #if PY_MAJOR_VERSION < 3
5207 "%s() got an unexpected keyword argument '%s'",
5208 function_name, PyString_AsString(key));
5210 "%s() got an unexpected keyword argument '%U'",
5211 function_name, key);
5218 #------------------------------------------------------------------------------------
5220 traceback_utility_code = UtilityCode(
5222 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5225 #include "compile.h"
5226 #include "frameobject.h"
5227 #include "traceback.h"
5229 static void __Pyx_AddTraceback(const char *funcname) {
5230 PyObject *py_srcfile = 0;
5231 PyObject *py_funcname = 0;
5232 PyObject *py_globals = 0;
5233 PyObject *empty_string = 0;
5234 PyCodeObject *py_code = 0;
5235 PyFrameObject *py_frame = 0;
5237 #if PY_MAJOR_VERSION < 3
5238 py_srcfile = PyString_FromString(%(FILENAME)s);
5240 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5242 if (!py_srcfile) goto bad;
5244 #if PY_MAJOR_VERSION < 3
5245 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5247 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5251 #if PY_MAJOR_VERSION < 3
5252 py_funcname = PyString_FromString(funcname);
5254 py_funcname = PyUnicode_FromString(funcname);
5257 if (!py_funcname) goto bad;
5258 py_globals = PyModule_GetDict(%(GLOBALS)s);
5259 if (!py_globals) goto bad;
5260 #if PY_MAJOR_VERSION < 3
5261 empty_string = PyString_FromStringAndSize("", 0);
5263 empty_string = PyBytes_FromStringAndSize("", 0);
5265 if (!empty_string) goto bad;
5266 py_code = PyCode_New(
5267 0, /*int argcount,*/
5268 #if PY_MAJOR_VERSION >= 3
5269 0, /*int kwonlyargcount,*/
5272 0, /*int stacksize,*/
5274 empty_string, /*PyObject *code,*/
5275 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5276 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5277 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5278 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5279 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5280 py_srcfile, /*PyObject *filename,*/
5281 py_funcname, /*PyObject *name,*/
5282 %(LINENO)s, /*int firstlineno,*/
5283 empty_string /*PyObject *lnotab*/
5285 if (!py_code) goto bad;
5286 py_frame = PyFrame_New(
5287 PyThreadState_GET(), /*PyThreadState *tstate,*/
5288 py_code, /*PyCodeObject *code,*/
5289 py_globals, /*PyObject *globals,*/
5290 0 /*PyObject *locals*/
5292 if (!py_frame) goto bad;
5293 py_frame->f_lineno = %(LINENO)s;
5294 PyTraceBack_Here(py_frame);
5296 Py_XDECREF(py_srcfile);
5297 Py_XDECREF(py_funcname);
5298 Py_XDECREF(empty_string);
5299 Py_XDECREF(py_code);
5300 Py_XDECREF(py_frame);
5303 'FILENAME': Naming.filename_cname,
5304 'LINENO': Naming.lineno_cname,
5305 'CFILENAME': Naming.cfilenm_cname,
5306 'CLINENO': Naming.clineno_cname,
5307 'GLOBALS': Naming.module_cname,
5308 'EMPTY_TUPLE' : Naming.empty_tuple,
5311 restore_exception_utility_code = UtilityCode(
5313 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5314 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5317 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5318 PyObject *tmp_type, *tmp_value, *tmp_tb;
5319 PyThreadState *tstate = PyThreadState_GET();
5321 #if PY_MAJOR_VERSION >= 3
5322 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5323 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5324 tmp_type = tstate->exc_type;
5325 tmp_value = tstate->exc_value;
5326 tmp_tb = tstate->exc_traceback;
5327 PyErr_NormalizeException(&type, &value, &tb);
5328 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5329 tstate->exc_type = 0;
5330 tstate->exc_value = 0;
5331 tstate->exc_traceback = 0;
5332 PyException_SetContext(value, tmp_value);
5333 Py_DECREF(tmp_type);
5338 tmp_type = tstate->curexc_type;
5339 tmp_value = tstate->curexc_value;
5340 tmp_tb = tstate->curexc_traceback;
5341 tstate->curexc_type = type;
5342 tstate->curexc_value = value;
5343 tstate->curexc_traceback = tb;
5344 Py_XDECREF(tmp_type);
5345 Py_XDECREF(tmp_value);
5349 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5350 PyThreadState *tstate = PyThreadState_GET();
5351 *type = tstate->curexc_type;
5352 *value = tstate->curexc_value;
5353 *tb = tstate->curexc_traceback;
5355 tstate->curexc_type = 0;
5356 tstate->curexc_value = 0;
5357 tstate->curexc_traceback = 0;
5362 #------------------------------------------------------------------------------------
5364 unraisable_exception_utility_code = UtilityCode(
5366 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5369 static void __Pyx_WriteUnraisable(const char *name) {
5370 PyObject *old_exc, *old_val, *old_tb;
5372 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5373 #if PY_MAJOR_VERSION < 3
5374 ctx = PyString_FromString(name);
5376 ctx = PyUnicode_FromString(name);
5378 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5380 PyErr_WriteUnraisable(Py_None);
5382 PyErr_WriteUnraisable(ctx);
5387 requires=[restore_exception_utility_code])
5389 #------------------------------------------------------------------------------------
5391 set_vtable_utility_code = UtilityCode(
5393 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5396 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5397 PyObject *pycobj = 0;
5400 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5403 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5416 #------------------------------------------------------------------------------------
5418 get_vtable_utility_code = UtilityCode(
5420 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5423 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5427 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5430 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5431 if (!*(void **)vtabptr)
5444 #------------------------------------------------------------------------------------
5446 init_string_tab_utility_code = UtilityCode(
5448 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5451 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5453 #if PY_MAJOR_VERSION < 3
5454 if (t->is_unicode && (!t->is_identifier)) {
5455 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5456 } else if (t->intern) {
5457 *t->p = PyString_InternFromString(t->s);
5459 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5461 #else /* Python 3+ has unicode identifiers */
5462 if (t->is_identifier || (t->is_unicode && t->intern)) {
5463 *t->p = PyUnicode_InternFromString(t->s);
5464 } else if (t->is_unicode) {
5465 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5467 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5478 #------------------------------------------------------------------------------------
5480 get_exception_utility_code = UtilityCode(
5482 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5485 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5486 PyObject *tmp_type, *tmp_value, *tmp_tb;
5487 PyThreadState *tstate = PyThreadState_GET();
5488 *type = tstate->curexc_type;
5489 *value = tstate->curexc_value;
5490 *tb = tstate->curexc_traceback;
5491 tstate->curexc_type = 0;
5492 tstate->curexc_value = 0;
5493 tstate->curexc_traceback = 0;
5494 PyErr_NormalizeException(type, value, tb);
5495 if (PyErr_Occurred())
5500 tmp_type = tstate->exc_type;
5501 tmp_value = tstate->exc_value;
5502 tmp_tb = tstate->exc_traceback;
5503 tstate->exc_type = *type;
5504 tstate->exc_value = *value;
5505 tstate->exc_traceback = *tb;
5506 /* Make sure tstate is in a consistent state when we XDECREF
5507 these objects (XDECREF may run arbitrary code). */
5508 Py_XDECREF(tmp_type);
5509 Py_XDECREF(tmp_value);
5521 #------------------------------------------------------------------------------------
5523 reset_exception_utility_code = UtilityCode(
5525 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5526 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5529 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5530 PyThreadState *tstate = PyThreadState_GET();
5531 *type = tstate->exc_type;
5532 *value = tstate->exc_value;
5533 *tb = tstate->exc_traceback;
5539 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5540 PyObject *tmp_type, *tmp_value, *tmp_tb;
5541 PyThreadState *tstate = PyThreadState_GET();
5542 tmp_type = tstate->exc_type;
5543 tmp_value = tstate->exc_value;
5544 tmp_tb = tstate->exc_traceback;
5545 tstate->exc_type = type;
5546 tstate->exc_value = value;
5547 tstate->exc_traceback = tb;
5548 Py_XDECREF(tmp_type);
5549 Py_XDECREF(tmp_value);
5554 #------------------------------------------------------------------------------------
5556 force_init_threads_utility_code = UtilityCode(
5558 #ifndef __PYX_FORCE_INIT_THREADS
5559 #if PY_VERSION_HEX < 0x02040200
5560 #define __PYX_FORCE_INIT_THREADS 1
5562 #define __PYX_FORCE_INIT_THREADS 0
5567 #------------------------------------------------------------------------------------