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
17 from Code import UtilityCode
18 from StringEncoding import EncodedString, escape_byte_string, split_docstring
23 absolute_path_length = 0
25 def relative_position(pos):
27 We embed the relative filename in the generated C file, since we
28 don't want to have to regnerate and compile all the source code
29 whenever the Python install directory moves (which could happen,
30 e.g,. when distributing binaries.)
33 a position tuple -- (absolute filename, line number column position)
41 global absolute_path_length
42 if absolute_path_length==0:
43 absolute_path_length = len(os.path.abspath(os.getcwd()))
44 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
46 def embed_position(pos, docstring):
47 if not Options.embed_pos_in_docstring:
49 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
52 return EncodedString(pos_line)
54 # make sure we can encode the filename in the docstring encoding
55 # otherwise make the docstring a unicode string
56 encoding = docstring.encoding
57 if encoding is not None:
59 encoded_bytes = pos_line.encode(encoding)
60 except UnicodeEncodeError:
64 # reuse the string encoding of the original docstring
65 doc = EncodedString(pos_line)
67 doc = EncodedString(pos_line + u'\n' + docstring)
68 doc.encoding = encoding
72 from Code import CCodeWriter
73 from types import FunctionType
75 def write_func_call(func):
77 if len(args) > 1 and isinstance(args[1], CCodeWriter):
78 # here we annotate the code with this function call
79 # but only if new code is generated
81 marker = ' /* %s -> %s.%s %s */' % (
82 ' ' * code.call_level,
83 node.__class__.__name__,
86 pristine = code.buffer.stream.tell()
88 start = code.buffer.stream.tell()
90 res = func(*args, **kwds)
92 if start == code.buffer.stream.tell():
93 code.buffer.stream.seek(pristine)
95 marker = marker.replace('->', '<-')
99 return func(*args, **kwds)
102 class VerboseCodeWriter(type):
103 # Set this as a metaclass to trace function calls in code.
104 # This slows down code generation and makes much larger files.
105 def __new__(cls, name, bases, attrs):
107 for mname, m in attrs.items():
108 if isinstance(m, FunctionType):
109 attrs[mname] = write_func_call(m)
110 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
114 # pos (string, int, int) Source file position
115 # is_name boolean Is a NameNode
116 # is_literal boolean Is a ConstNode
118 if DebugFlags.debug_trace_code_generation:
119 __metaclass__ = VerboseCodeWriter
125 # All descandants should set child_attrs to a list of the attributes
126 # containing nodes considered "children" in the tree. Each such attribute
127 # can either contain a single node or a list of nodes. See Visitor.py.
130 def __init__(self, pos, **kw):
132 self.__dict__.update(kw)
134 gil_message = "Operation"
138 def gil_error(self, env=None):
139 error(self.pos, "%s not allowed without gil" % self.gil_message)
141 def clone_node(self):
142 """Clone the node. This is defined as a shallow copy, except for member lists
143 amongst the child attributes (from get_child_accessors) which are also
144 copied. Lists containing child nodes are thus seen as a way for the node
145 to hold multiple children directly; the list is not treated as a seperate
146 level in the tree."""
147 result = copy.copy(self)
148 for attrname in result.child_attrs:
149 value = getattr(result, attrname)
150 if isinstance(value, list):
151 setattr(result, attrname, [x for x in value])
156 # There are 4 phases of parse tree processing, applied in order to
157 # all the statements in a given scope-block:
159 # (0) analyse_control_flow
160 # Create the control flow tree into which state can be asserted and
163 # (1) analyse_declarations
164 # Make symbol table entries for all declarations at the current
165 # level, both explicit (def, cdef, etc.) and implicit (assignment
166 # to an otherwise undeclared name).
168 # (2) analyse_expressions
169 # Determine the result types of expressions and fill in the
170 # 'type' attribute of each ExprNode. Insert coercion nodes into the
171 # tree where needed to convert to and from Python objects.
172 # Allocate temporary locals for intermediate results. Fill
173 # in the 'result_code' attribute of each ExprNode with a C code
177 # Emit C code for all declarations, statements and expressions.
178 # Recursively applies the 3 processing phases to the bodies of
182 def analyse_control_flow(self, env):
185 def analyse_declarations(self, env):
188 def analyse_expressions(self, env):
189 raise InternalError("analyse_expressions not implemented for %s" % \
190 self.__class__.__name__)
192 def generate_code(self, code):
193 raise InternalError("generate_code not implemented for %s" % \
194 self.__class__.__name__)
196 def annotate(self, code):
197 # mro does the wrong thing
198 if isinstance(self, BlockNode):
199 self.body.annotate(code)
204 except AttributeError:
206 if not self.child_attrs:
209 for attr in self.child_attrs:
210 child = getattr(self, attr)
211 # Sometimes lists, sometimes nodes
214 elif isinstance(child, list):
216 pos = max(pos, c.end_pos())
218 pos = max(pos, child.end_pos())
222 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
224 return "<...nesting level cutoff...>"
225 if encountered is None:
227 if id(self) in encountered:
228 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
229 encountered.add(id(self))
231 def dump_child(x, level):
232 if isinstance(x, Node):
233 return x.dump(level, filter_out, cutoff-1, encountered)
234 elif isinstance(x, list):
235 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
240 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
242 return "<%s (%d)>" % (self.__class__.__name__, id(self))
245 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
246 for key, value in attrs:
247 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
248 res += "%s>" % indent
251 class CompilerDirectivesNode(Node):
253 Sets compiler directives for the children nodes
255 # directives {string:value} A dictionary holding the right value for
256 # *all* possible directives.
258 child_attrs = ["body"]
260 def analyse_control_flow(self, env):
262 env.directives = self.directives
263 self.body.analyse_control_flow(env)
266 def analyse_declarations(self, env):
268 env.directives = self.directives
269 self.body.analyse_declarations(env)
272 def analyse_expressions(self, env):
274 env.directives = self.directives
275 self.body.analyse_expressions(env)
278 def generate_function_definitions(self, env, code):
279 env_old = env.directives
280 code_old = code.globalstate.directives
281 code.globalstate.directives = self.directives
282 self.body.generate_function_definitions(env, code)
283 env.directives = env_old
284 code.globalstate.directives = code_old
286 def generate_execution_code(self, code):
287 old = code.globalstate.directives
288 code.globalstate.directives = self.directives
289 self.body.generate_execution_code(code)
290 code.globalstate.directives = old
292 def annotate(self, code):
293 old = code.globalstate.directives
294 code.globalstate.directives = self.directives
295 self.body.annotate(code)
296 code.globalstate.directives = old
298 class BlockNode(object):
299 # Mixin class for nodes representing a declaration block.
301 def generate_cached_builtins_decls(self, env, code):
302 entries = env.global_scope().undeclared_cached_builtins
303 for entry in entries:
304 code.globalstate.add_cached_builtin_decl(entry)
308 class StatListNode(Node):
309 # stats a list of StatNode
311 child_attrs = ["stats"]
313 def create_analysed(pos, env, *args, **kw):
314 node = StatListNode(pos, *args, **kw)
315 return node # No node-specific analysis necesarry
316 create_analysed = staticmethod(create_analysed)
318 def analyse_control_flow(self, env):
319 for stat in self.stats:
320 stat.analyse_control_flow(env)
322 def analyse_declarations(self, env):
323 #print "StatListNode.analyse_declarations" ###
324 for stat in self.stats:
325 stat.analyse_declarations(env)
327 def analyse_expressions(self, env):
328 #print "StatListNode.analyse_expressions" ###
329 for stat in self.stats:
330 stat.analyse_expressions(env)
332 def generate_function_definitions(self, env, code):
333 #print "StatListNode.generate_function_definitions" ###
334 for stat in self.stats:
335 stat.generate_function_definitions(env, code)
337 def generate_execution_code(self, code):
338 #print "StatListNode.generate_execution_code" ###
339 for stat in self.stats:
340 code.mark_pos(stat.pos)
341 stat.generate_execution_code(code)
343 def annotate(self, code):
344 for stat in self.stats:
348 class StatNode(Node):
350 # Code generation for statements is split into the following subphases:
352 # (1) generate_function_definitions
353 # Emit C code for the definitions of any structs,
354 # unions, enums and functions defined in the current
357 # (2) generate_execution_code
358 # Emit C code for executable statements.
361 def generate_function_definitions(self, env, code):
364 def generate_execution_code(self, code):
365 raise InternalError("generate_execution_code not implemented for %s" % \
366 self.__class__.__name__)
369 class CDefExternNode(StatNode):
370 # include_file string or None
373 child_attrs = ["body"]
375 def analyse_declarations(self, env):
376 if self.include_file:
377 env.add_include_file(self.include_file)
378 old_cinclude_flag = env.in_cinclude
380 self.body.analyse_declarations(env)
381 env.in_cinclude = old_cinclude_flag
383 def analyse_expressions(self, env):
386 def generate_execution_code(self, code):
389 def annotate(self, code):
390 self.body.annotate(code)
393 class CDeclaratorNode(Node):
394 # Part of a C declaration.
396 # Processing during analyse_declarations phase:
399 # Returns (name, type) pair where name is the
400 # CNameDeclaratorNode of the name being declared
401 # and type is the type it is being declared as.
403 # calling_convention string Calling convention of CFuncDeclaratorNode
404 # for which this is a base
408 calling_convention = ""
411 class CNameDeclaratorNode(CDeclaratorNode):
412 # name string The Pyrex name being declared
413 # cname string or None C name, if specified
414 # default ExprNode or None the value assigned on declaration
416 child_attrs = ['default']
420 def analyse(self, base_type, env, nonempty = 0):
421 if nonempty and self.name == '':
422 # May have mistaken the name for the type.
423 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
424 error(self.pos, "Missing argument name")
425 elif base_type.is_void:
426 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
428 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
429 base_type = py_object_type
430 self.type = base_type
431 return self, base_type
433 class CPtrDeclaratorNode(CDeclaratorNode):
434 # base CDeclaratorNode
436 child_attrs = ["base"]
438 def analyse(self, base_type, env, nonempty = 0):
439 if base_type.is_pyobject:
441 "Pointer base type cannot be a Python object")
442 ptr_type = PyrexTypes.c_ptr_type(base_type)
443 return self.base.analyse(ptr_type, env, nonempty = nonempty)
445 class CArrayDeclaratorNode(CDeclaratorNode):
446 # base CDeclaratorNode
449 child_attrs = ["base", "dimension"]
451 def analyse(self, base_type, env, nonempty = 0):
453 self.dimension.analyse_const_expression(env)
454 if not self.dimension.type.is_int:
455 error(self.dimension.pos, "Array dimension not integer")
456 size = self.dimension.get_constant_c_result_code()
465 if not base_type.is_complete():
467 "Array element type '%s' is incomplete" % base_type)
468 if base_type.is_pyobject:
470 "Array element cannot be a Python object")
471 if base_type.is_cfunction:
473 "Array element cannot be a function")
474 array_type = PyrexTypes.c_array_type(base_type, size)
475 return self.base.analyse(array_type, env, nonempty = nonempty)
478 class CFuncDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
480 # args [CArgDeclNode]
481 # has_varargs boolean
482 # exception_value ConstNode
483 # exception_check boolean True if PyErr_Occurred check needed
484 # nogil boolean Can be called without gil
485 # with_gil boolean Acquire gil around function body
487 child_attrs = ["base", "args", "exception_value"]
490 optional_arg_count = 0
492 def analyse(self, return_type, env, nonempty = 0):
496 for arg_node in self.args:
497 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
498 name = name_declarator.name
499 if name_declarator.cname:
501 "Function argument cannot have C name specification")
502 # Turn *[] argument into **
504 type = PyrexTypes.c_ptr_type(type.base_type)
505 # Catch attempted C-style func(void) decl
507 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
508 func_type_args.append(
509 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
511 self.optional_arg_count += 1
512 elif self.optional_arg_count:
513 error(self.pos, "Non-default argument follows default argument")
515 if self.optional_arg_count:
516 scope = StructOrUnionScope()
517 arg_count_member = '%sn' % Naming.pyrex_prefix
518 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
519 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
520 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
521 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
522 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
527 cname = struct_cname)
528 self.op_args_struct.defined_in_pxd = 1
529 self.op_args_struct.used = 1
533 if self.exception_check == '+':
534 env.add_include_file('stdexcept')
535 if return_type.is_pyobject \
536 and (self.exception_value or self.exception_check) \
537 and self.exception_check != '+':
539 "Exception clause not allowed for function returning Python object")
541 if self.exception_value:
542 self.exception_value.analyse_const_expression(env)
543 exc_val = self.exception_value.get_constant_c_result_code()
544 if self.exception_check == '+':
545 exc_val_type = self.exception_value.type
546 if not exc_val_type.is_error and \
547 not exc_val_type.is_pyobject and \
548 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
549 error(self.exception_value.pos,
550 "Exception value must be a Python exception or cdef function with no arguments.")
552 if not return_type.assignable_from(self.exception_value.type):
553 error(self.exception_value.pos,
554 "Exception value incompatible with function return type")
555 exc_check = self.exception_check
556 if return_type.is_array:
558 "Function cannot return an array")
559 if return_type.is_cfunction:
561 "Function cannot return a function")
562 func_type = PyrexTypes.CFuncType(
563 return_type, func_type_args, self.has_varargs,
564 optional_arg_count = self.optional_arg_count,
565 exception_value = exc_val, exception_check = exc_check,
566 calling_convention = self.base.calling_convention,
567 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
568 if self.optional_arg_count:
569 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
570 callspec = env.directives['callspec']
572 current = func_type.calling_convention
573 if current and current != callspec:
574 error(self.pos, "cannot have both '%s' and '%s' "
575 "calling conventions" % (current, callspec))
576 func_type.calling_convention = callspec
577 return self.base.analyse(func_type, env)
580 class CArgDeclNode(Node):
581 # Item in a function declaration argument list.
583 # base_type CBaseTypeNode
584 # declarator CDeclaratorNode
585 # not_none boolean Tagged with 'not None'
586 # default ExprNode or None
587 # default_value PyObjectConst constant for default value
588 # is_self_arg boolean Is the "self" arg of an extension type method
589 # is_kw_only boolean Is a keyword-only argument
591 child_attrs = ["base_type", "declarator", "default"]
596 name_declarator = None
599 def analyse(self, env, nonempty = 0):
600 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
601 if self.type is None:
602 # The parser may missinterpret names as types...
604 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
606 self.declarator.name = self.base_type.name
607 self.base_type.name = None
608 self.base_type.is_basic_c_type = False
611 could_be_name = False
612 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
613 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
614 self.declarator.name = self.base_type.arg_name
615 return self.declarator.analyse(base_type, env, nonempty = nonempty)
617 return self.name_declarator, self.type
619 def calculate_default_value_code(self, code):
620 if self.default_value is None:
622 if self.default.is_literal:
623 # will not output any code, just assign the result_code
624 self.default.generate_evaluation_code(code)
625 return self.type.cast_code(self.default.result())
626 self.default_value = code.get_argument_default_const(self.type)
627 return self.default_value
629 def annotate(self, code):
631 self.default.annotate(code)
634 class CBaseTypeNode(Node):
635 # Abstract base class for C base type nodes.
637 # Processing during analyse_declarations phase:
644 class CAnalysedBaseTypeNode(Node):
649 def analyse(self, env, could_be_name = False):
652 class CSimpleBaseTypeNode(CBaseTypeNode):
654 # module_path [string] Qualifying name components
655 # is_basic_c_type boolean
659 # is_self_arg boolean Is self argument of C method
662 arg_name = None # in case the argument name was interpreted as a type
664 def analyse(self, env, could_be_name = False):
665 # Return type descriptor.
666 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
668 if self.is_basic_c_type:
669 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
671 error(self.pos, "Unrecognised type modifier combination")
672 elif self.name == "object" and not self.module_path:
673 type = py_object_type
674 elif self.name is None:
675 if self.is_self_arg and env.is_c_class_scope:
676 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
677 type = env.parent_type
679 type = py_object_type
682 scope = env.find_imported_module(self.module_path, self.pos)
686 if scope.is_c_class_scope:
687 scope = scope.global_scope()
688 entry = scope.lookup(self.name)
689 if entry and entry.is_type:
692 if self.is_self_arg and env.is_c_class_scope:
693 type = env.parent_type
695 type = py_object_type
696 self.arg_name = self.name
698 error(self.pos, "'%s' is not a type identifier" % self.name)
700 if not type.is_numeric or type.is_complex:
701 error(self.pos, "can only complexify c numeric types")
702 type = PyrexTypes.CComplexType(type)
703 type.create_declaration_utility_code(env)
707 return PyrexTypes.error_type
709 class CBufferAccessTypeNode(CBaseTypeNode):
711 # positional_args [ExprNode] List of positional arguments
712 # keyword_args DictNode Keyword arguments
713 # base_type_node CBaseTypeNode
716 # type PyrexType.BufferType ...containing the right options
719 child_attrs = ["base_type_node", "positional_args",
720 "keyword_args", "dtype_node"]
726 def analyse(self, env, could_be_name = False):
727 base_type = self.base_type_node.analyse(env)
728 if base_type.is_error: return base_type
731 options = Buffer.analyse_buffer_options(
734 self.positional_args,
736 base_type.buffer_defaults)
738 self.type = PyrexTypes.BufferType(base_type, **options)
741 class CComplexBaseTypeNode(CBaseTypeNode):
742 # base_type CBaseTypeNode
743 # declarator CDeclaratorNode
745 child_attrs = ["base_type", "declarator"]
747 def analyse(self, env, could_be_name = False):
748 base = self.base_type.analyse(env, could_be_name)
749 _, type = self.declarator.analyse(base, env)
753 class CVarDefNode(StatNode):
754 # C variable definition or forward/extern function declaration.
756 # visibility 'private' or 'public' or 'extern'
757 # base_type CBaseTypeNode
758 # declarators [CDeclaratorNode]
761 # need_properties [entry]
763 # decorators [cython.locals(...)] or None
764 # directive_locals { string : NameNode } locals defined by cython.locals(...)
766 child_attrs = ["base_type", "declarators"]
770 directive_locals = {}
772 def analyse_declarations(self, env, dest_scope = None):
775 self.dest_scope = dest_scope
776 base_type = self.base_type.analyse(env)
778 # If the field is an external typedef, we cannot be sure about the type,
779 # so do conversion ourself rather than rely on the CPython mechanism (through
780 # a property; made in AnalyseDeclarationsTransform).
781 if (dest_scope.is_c_class_scope
782 and self.visibility == 'public'
783 and base_type.is_pyobject
784 and (base_type.is_builtin_type or base_type.is_extension_type)):
785 self.need_properties = []
787 visibility = 'private'
789 need_property = False
790 visibility = self.visibility
792 for declarator in self.declarators:
793 name_declarator, type = declarator.analyse(base_type, env)
794 if not type.is_complete():
795 if not (self.visibility == 'extern' and type.is_array):
796 error(declarator.pos,
797 "Variable type '%s' is incomplete" % type)
798 if self.visibility == 'extern' and type.is_pyobject:
799 error(declarator.pos,
800 "Python object cannot be declared extern")
801 name = name_declarator.name
802 cname = name_declarator.cname
804 error(declarator.pos, "Missing name in declaration.")
806 if type.is_cfunction:
807 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
808 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
810 if entry is not None:
811 entry.directive_locals = self.directive_locals
813 if self.directive_locals:
814 s.error("Decorators can only be followed by functions")
815 if self.in_pxd and self.visibility != 'extern':
817 "Only 'extern' C variable declaration allowed in .pxd file")
818 entry = dest_scope.declare_var(name, type, declarator.pos,
819 cname = cname, visibility = visibility, is_cdef = 1)
821 self.need_properties.append(entry)
822 entry.needs_property = 1
825 class CStructOrUnionDefNode(StatNode):
827 # cname string or None
828 # kind "struct" or "union"
829 # typedef_flag boolean
830 # visibility "public" or "private"
832 # attributes [CVarDefNode] or None
836 child_attrs = ["attributes"]
838 def analyse_declarations(self, env):
840 if self.visibility == 'extern' and self.packed:
841 error(self.pos, "Cannot declare extern struct as 'packed'")
842 if self.attributes is not None:
843 scope = StructOrUnionScope(self.name)
844 self.entry = env.declare_struct_or_union(
845 self.name, self.kind, scope, self.typedef_flag, self.pos,
846 self.cname, visibility = self.visibility, packed = self.packed)
847 if self.attributes is not None:
848 if self.in_pxd and not env.in_cinclude:
849 self.entry.defined_in_pxd = 1
850 for attr in self.attributes:
851 attr.analyse_declarations(env, scope)
852 if self.visibility != 'extern':
853 need_typedef_indirection = False
854 for attr in scope.var_entries:
857 type = type.base_type
858 if type == self.entry.type:
859 error(attr.pos, "Struct cannot contain itself as a member.")
860 if self.typedef_flag:
862 type = type.base_type
863 if type == self.entry.type:
864 need_typedef_indirection = True
865 if need_typedef_indirection:
866 # C can't handle typedef structs that refer to themselves.
867 struct_entry = self.entry
868 self.entry = env.declare_typedef(
869 self.name, struct_entry.type, self.pos,
870 cname = self.cname, visibility='ignore')
871 struct_entry.type.typedef_flag = False
872 # FIXME: this might be considered a hack ;-)
873 struct_entry.cname = struct_entry.type.cname = \
874 '_' + self.entry.type.typedef_cname
876 def analyse_expressions(self, env):
879 def generate_execution_code(self, code):
883 class CEnumDefNode(StatNode):
884 # name string or None
885 # cname string or None
886 # items [CEnumDefItemNode]
887 # typedef_flag boolean
888 # visibility "public" or "private"
892 child_attrs = ["items"]
894 def analyse_declarations(self, env):
895 self.entry = env.declare_enum(self.name, self.pos,
896 cname = self.cname, typedef_flag = self.typedef_flag,
897 visibility = self.visibility)
898 if self.items is not None:
899 if self.in_pxd and not env.in_cinclude:
900 self.entry.defined_in_pxd = 1
901 for item in self.items:
902 item.analyse_declarations(env, self.entry)
904 def generate_execution_code(self, code):
905 if self.visibility == 'public':
906 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
907 for item in self.entry.enum_values:
908 code.putln("%s = PyInt_FromLong(%s); %s" % (
911 code.error_goto_if_null(temp, item.pos)))
912 code.put_gotref(temp)
913 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
917 code.error_goto(item.pos)))
918 code.put_decref_clear(temp, PyrexTypes.py_object_type)
919 code.funcstate.release_temp(temp)
922 class CEnumDefItemNode(StatNode):
924 # cname string or None
925 # value ExprNode or None
927 child_attrs = ["value"]
929 def analyse_declarations(self, env, enum_entry):
931 self.value.analyse_const_expression(env)
932 if not self.value.type.is_int:
933 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
934 self.value.analyse_const_expression(env)
935 entry = env.declare_const(self.name, enum_entry.type,
936 self.value, self.pos, cname = self.cname,
937 visibility = enum_entry.visibility)
938 enum_entry.enum_values.append(entry)
941 class CTypeDefNode(StatNode):
942 # base_type CBaseTypeNode
943 # declarator CDeclaratorNode
944 # visibility "public" or "private"
947 child_attrs = ["base_type", "declarator"]
949 def analyse_declarations(self, env):
950 base = self.base_type.analyse(env)
951 name_declarator, type = self.declarator.analyse(base, env)
952 name = name_declarator.name
953 cname = name_declarator.cname
954 entry = env.declare_typedef(name, type, self.pos,
955 cname = cname, visibility = self.visibility)
956 if self.in_pxd and not env.in_cinclude:
957 entry.defined_in_pxd = 1
959 def analyse_expressions(self, env):
961 def generate_execution_code(self, code):
965 class FuncDefNode(StatNode, BlockNode):
966 # Base class for function definition nodes.
968 # return_type PyrexType
969 # #filename string C name of filename string const
971 # needs_closure boolean Whether or not this function has inner functions/classes/yield
972 # directive_locals { string : NameNode } locals defined by cython.locals(...)
976 needs_closure = False
978 def analyse_default_values(self, env):
979 genv = env.global_scope()
980 for arg in self.args:
983 arg.default.analyse_types(env)
984 arg.default = arg.default.coerce_to(arg.type, genv)
987 "This argument cannot have a default value")
990 def need_gil_acquisition(self, lenv):
993 def create_local_scope(self, env):
995 while env.is_py_class_scope or env.is_c_class_scope:
996 env = env.outer_scope
997 if self.needs_closure:
998 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1000 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1001 lenv.return_type = self.return_type
1002 type = self.entry.type
1003 if type.is_cfunction:
1004 lenv.nogil = type.nogil and not type.with_gil
1005 self.local_scope = lenv
1006 lenv.directives = env.directives
1009 def generate_function_definitions(self, env, code):
1012 lenv = self.local_scope
1014 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1015 self.entry.scope.is_c_class_scope)
1017 # Generate C code for header and body of function
1018 code.enter_cfunc_scope()
1019 code.return_from_error_cleanup_label = code.new_label()
1021 # ----- Top-level constants used by this function
1022 code.mark_pos(self.pos)
1023 self.generate_cached_builtins_decls(lenv, code)
1024 # ----- Function header
1027 self.py_func.generate_function_header(code,
1028 with_pymethdef = env.is_py_class_scope,
1030 self.generate_function_header(code,
1031 with_pymethdef = env.is_py_class_scope)
1032 # ----- Local variable declarations
1033 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1034 self.generate_argument_declarations(lenv, code)
1035 if self.needs_closure:
1036 code.putln("/* TODO: declare and create scope object */")
1037 code.put_var_declarations(lenv.var_entries)
1039 if not self.return_type.is_void:
1040 if self.return_type.is_pyobject:
1044 (self.return_type.declaration_code(
1045 Naming.retval_cname),
1047 tempvardecl_code = code.insertion_point()
1048 self.generate_keyword_list(code)
1049 # ----- Extern library function declarations
1050 lenv.generate_library_function_declarations(code)
1051 # ----- GIL acquisition
1052 acquire_gil = self.need_gil_acquisition(lenv)
1054 env.use_utility_code(force_init_threads_utility_code)
1055 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1056 # ----- Automatic lead-ins for certain special functions
1058 code.put_setup_refcount_context(self.entry.name)
1059 if is_getbuffer_slot:
1060 self.getbuffer_init(code)
1061 # ----- Fetch arguments
1062 self.generate_argument_parsing_code(env, code)
1063 # If an argument is assigned to in the body, we must
1064 # incref it to properly keep track of refcounts.
1065 for entry in lenv.arg_entries:
1066 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1067 code.put_var_incref(entry)
1068 # ----- Initialise local variables
1069 for entry in lenv.var_entries:
1070 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1071 code.put_init_var_to_py_none(entry)
1072 # ----- Initialise local buffer auxiliary variables
1073 for entry in lenv.var_entries + lenv.arg_entries:
1074 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1075 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1076 # ----- Check and convert arguments
1077 self.generate_argument_type_tests(code)
1078 # ----- Acquire buffer arguments
1079 for entry in lenv.arg_entries:
1080 if entry.type.is_buffer:
1081 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1082 # ----- Function body
1083 self.body.generate_execution_code(code)
1084 # ----- Default return value
1086 if self.return_type.is_pyobject:
1087 #if self.return_type.is_extension_type:
1088 # lhs = "(PyObject *)%s" % Naming.retval_cname
1090 lhs = Naming.retval_cname
1091 code.put_init_to_py_none(lhs, self.return_type)
1093 val = self.return_type.default_value
1095 code.putln("%s = %s;" % (Naming.retval_cname, val))
1096 # ----- Error cleanup
1097 if code.error_label in code.labels_used:
1098 code.put_goto(code.return_label)
1099 code.put_label(code.error_label)
1100 for cname, type in code.funcstate.all_managed_temps():
1101 code.put_xdecref(cname, type)
1103 # Clean up buffers -- this calls a Python function
1104 # so need to save and restore error state
1105 buffers_present = len(lenv.buffer_entries) > 0
1107 code.globalstate.use_utility_code(restore_exception_utility_code)
1108 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1109 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1110 for entry in lenv.buffer_entries:
1111 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1112 #code.putln("%s = 0;" % entry.cname)
1113 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1115 err_val = self.error_value()
1116 exc_check = self.caller_will_check_exceptions()
1117 if err_val is not None or exc_check:
1118 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1120 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1121 % self.entry.qualified_name, 0)
1123 '__Pyx_WriteUnraisable("%s");' %
1124 self.entry.qualified_name)
1125 env.use_utility_code(unraisable_exception_utility_code)
1126 env.use_utility_code(restore_exception_utility_code)
1127 default_retval = self.return_type.default_value
1128 if err_val is None and default_retval:
1129 err_val = default_retval
1130 if err_val is not None:
1133 Naming.retval_cname,
1136 if is_getbuffer_slot:
1137 self.getbuffer_error_cleanup(code)
1139 # If we are using the non-error cleanup section we should
1140 # jump past it if we have an error. The if-test below determine
1141 # whether this section is used.
1142 if buffers_present or is_getbuffer_slot:
1143 code.put_goto(code.return_from_error_cleanup_label)
1146 # ----- Non-error return cleanup
1147 # If you add anything here, remember to add a condition to the
1148 # if-test above in the error block (so that it can jump past this
1150 code.put_label(code.return_label)
1151 for entry in lenv.buffer_entries:
1153 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1154 if is_getbuffer_slot:
1155 self.getbuffer_normal_cleanup(code)
1156 # ----- Return cleanup for both error and no-error return
1157 code.put_label(code.return_from_error_cleanup_label)
1158 if not Options.init_local_none:
1159 for entry in lenv.var_entries:
1160 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1161 entry.xdecref_cleanup = 1
1162 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1163 # Decref any increfed args
1164 for entry in lenv.arg_entries:
1165 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1166 code.put_var_decref(entry)
1168 # code.putln("/* TODO: decref scope object */")
1170 # This code is duplicated in ModuleNode.generate_module_init_func
1172 default_retval = self.return_type.default_value
1173 err_val = self.error_value()
1174 if err_val is None and default_retval:
1175 err_val = default_retval
1176 if self.return_type.is_pyobject:
1177 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1179 code.put_finish_refcount_context()
1181 if self.entry.is_special and self.entry.name == "__hash__":
1182 # Returning -1 for __hash__ is supposed to signal an error
1183 # We do as Python instances and coerce -1 into -2.
1184 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1187 code.putln("PyGILState_Release(_save);")
1189 if not self.return_type.is_void:
1190 code.putln("return %s;" % Naming.retval_cname)
1193 # ----- Go back and insert temp variable declarations
1194 tempvardecl_code.put_temp_declarations(code.funcstate)
1195 # ----- Python version
1196 code.exit_cfunc_scope()
1198 self.py_func.generate_function_definitions(env, code)
1199 self.generate_wrapper_functions(code)
1201 def declare_argument(self, env, arg):
1202 if arg.type.is_void:
1203 error(arg.pos, "Invalid use of 'void'")
1204 elif not arg.type.is_complete() and not arg.type.is_array:
1206 "Argument type '%s' is incomplete" % arg.type)
1207 return env.declare_arg(arg.name, arg.type, arg.pos)
1209 def generate_wrapper_functions(self, code):
1212 def generate_execution_code(self, code):
1213 # Evaluate and store argument default values
1214 for arg in self.args:
1215 default = arg.default
1217 if not default.is_literal:
1218 default.generate_evaluation_code(code)
1219 default.make_owned_reference(code)
1220 result = default.result_as(arg.type)
1223 arg.calculate_default_value_code(code),
1225 if arg.type.is_pyobject:
1226 code.put_giveref(default.result())
1227 default.generate_post_assignment_code(code)
1228 default.free_temps(code)
1229 # For Python class methods, create and store function object
1231 self.assmt.generate_execution_code(code)
1234 # Special code for the __getbuffer__ function
1236 def getbuffer_init(self, code):
1237 info = self.local_scope.arg_entries[1].cname
1238 # Python 3.0 betas have a bug in memoryview which makes it call
1239 # getbuffer with a NULL parameter. For now we work around this;
1240 # the following line should be removed when this bug is fixed.
1241 code.putln("if (%s == NULL) return 0;" % info)
1242 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1243 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1245 def getbuffer_error_cleanup(self, code):
1246 info = self.local_scope.arg_entries[1].cname
1247 code.put_gotref("%s->obj" % info)
1248 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1251 def getbuffer_normal_cleanup(self, code):
1252 info = self.local_scope.arg_entries[1].cname
1253 code.putln("if (%s->obj == Py_None) {" % info)
1254 code.put_gotref("Py_None")
1255 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1258 class CFuncDefNode(FuncDefNode):
1259 # C function definition.
1261 # modifiers ['inline']
1262 # visibility 'private' or 'public' or 'extern'
1263 # base_type CBaseTypeNode
1264 # declarator CDeclaratorNode
1267 # decorators [DecoratorNode] list of decorators
1269 # with_gil boolean Acquire GIL around body
1271 # py_func wrapper for calling from Python
1272 # overridable whether or not this is a cpdef function
1273 # inline_in_pxd whether this is an inline function in a pxd file
1275 child_attrs = ["base_type", "declarator", "body", "py_func"]
1277 inline_in_pxd = False
1279 directive_locals = {}
1281 def unqualified_name(self):
1282 return self.entry.name
1284 def analyse_declarations(self, env):
1285 directive_locals = self.directive_locals = env.directives['locals']
1286 base_type = self.base_type.analyse(env)
1287 # The 2 here is because we need both function and argument names.
1288 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1289 if not type.is_cfunction:
1291 "Suite attached to non-function declaration")
1292 # Remember the actual type according to the function header
1293 # written here, because the type in the symbol table entry
1294 # may be different if we're overriding a C method inherited
1295 # from the base type of an extension type.
1297 type.is_overridable = self.overridable
1298 declarator = self.declarator
1299 while not hasattr(declarator, 'args'):
1300 declarator = declarator.base
1301 self.args = declarator.args
1302 for formal_arg, type_arg in zip(self.args, type.args):
1303 formal_arg.type = type_arg.type
1304 formal_arg.name = type_arg.name
1305 formal_arg.cname = type_arg.cname
1306 name = name_declarator.name
1307 cname = name_declarator.cname
1308 self.entry = env.declare_cfunction(
1309 name, type, self.pos,
1310 cname = cname, visibility = self.visibility,
1311 defining = self.body is not None,
1312 api = self.api, modifiers = self.modifiers)
1313 self.entry.inline_func_in_pxd = self.inline_in_pxd
1314 self.return_type = type.return_type
1316 if self.overridable and not env.is_module_scope:
1317 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1318 # An error will be produced in the cdef function
1319 self.overridable = False
1321 if self.overridable:
1323 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1324 self.py_func = DefNode(pos = self.pos,
1325 name = self.entry.name,
1328 starstar_arg = None,
1330 body = py_func_body,
1332 self.py_func.is_module_scope = env.is_module_scope
1333 self.py_func.analyse_declarations(env)
1334 self.entry.as_variable = self.py_func.entry
1335 # Reset scope entry the above cfunction
1336 env.entries[name] = self.entry
1337 if not env.is_module_scope or Options.lookup_module_cpdef:
1338 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1339 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1341 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1343 args = self.type.args
1344 if omit_optional_args:
1345 args = args[:len(args) - self.type.optional_arg_count]
1346 arg_names = [arg.name for arg in args]
1348 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1350 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1351 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1352 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1353 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)
1354 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1356 def declare_arguments(self, env):
1357 for arg in self.type.args:
1359 error(arg.pos, "Missing argument name")
1360 self.declare_argument(env, arg)
1362 def need_gil_acquisition(self, lenv):
1363 return self.type.with_gil
1365 def nogil_check(self, env):
1367 with_gil = type.with_gil
1368 if type.nogil and not with_gil:
1369 if type.return_type.is_pyobject:
1371 "Function with Python return type cannot be declared nogil")
1372 for entry in self.local_scope.var_entries:
1373 if entry.type.is_pyobject:
1374 error(self.pos, "Function declared nogil has Python locals or temporaries")
1376 def analyse_expressions(self, env):
1377 self.local_scope.directives = env.directives
1378 if self.py_func is not None:
1379 # this will also analyse the default values
1380 self.py_func.analyse_expressions(env)
1382 self.analyse_default_values(env)
1384 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1387 visibility = self.entry.visibility
1388 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1389 arg_decls.append(arg.declaration_code())
1390 if with_dispatch and self.overridable:
1391 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1392 if type.optional_arg_count and with_opt_args:
1393 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1394 if type.has_varargs:
1395 arg_decls.append("...")
1397 arg_decls = ["void"]
1399 cname = self.entry.func_cname
1400 entity = type.function_header_code(cname, ', '.join(arg_decls))
1401 if visibility == 'public':
1402 dll_linkage = "DL_EXPORT"
1405 header = self.return_type.declaration_code(entity,
1406 dll_linkage = dll_linkage)
1407 if visibility == 'extern':
1408 storage_class = "%s " % Naming.extern_c_macro
1409 elif visibility == 'public':
1412 storage_class = "static "
1413 code.putln("%s%s %s {" % (
1415 ' '.join(self.modifiers).upper(), # macro forms
1418 def generate_argument_declarations(self, env, code):
1419 for arg in self.args:
1421 result = arg.calculate_default_value_code(code)
1422 code.putln('%s = %s;' % (
1423 arg.type.declaration_code(arg.cname), result))
1425 def generate_keyword_list(self, code):
1428 def generate_argument_parsing_code(self, env, code):
1430 if self.type.optional_arg_count:
1431 code.putln('if (%s) {' % Naming.optional_args_cname)
1432 for arg in self.args:
1434 # FIXME: simple name prefixing doesn't work when
1435 # argument name mangling is in place
1436 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1437 declarator = arg.declarator
1438 while not hasattr(declarator, 'name'):
1439 declarator = declarator.base
1440 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1442 for _ in range(self.type.optional_arg_count):
1446 def generate_argument_conversion_code(self, code):
1449 def generate_argument_type_tests(self, code):
1450 # Generate type tests for args whose type in a parent
1451 # class is a supertype of the declared type.
1452 for arg in self.type.args:
1453 if arg.needs_type_test:
1454 self.generate_arg_type_test(arg, code)
1456 def generate_arg_type_test(self, arg, code):
1457 # Generate type test for one argument.
1458 if arg.type.typeobj_is_available():
1459 typeptr_cname = arg.type.typeptr_cname
1460 arg_code = "((PyObject *)%s)" % arg.cname
1462 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1467 type.is_builtin_type,
1468 code.error_goto(arg.pos)))
1470 error(arg.pos, "Cannot test type of extern C class "
1471 "without type object name specification")
1473 def error_value(self):
1474 if self.return_type.is_pyobject:
1478 return self.entry.type.exception_value
1480 def caller_will_check_exceptions(self):
1481 return self.entry.type.exception_check
1483 def generate_wrapper_functions(self, code):
1484 # If the C signature of a function has changed, we need to generate
1485 # wrappers to put in the slots here.
1488 func_type = entry.type
1489 while entry.prev_entry is not None:
1491 entry = entry.prev_entry
1492 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1494 self.generate_function_header(code,
1496 with_dispatch = entry.type.is_overridable,
1497 with_opt_args = entry.type.optional_arg_count,
1498 cname = entry.func_cname)
1499 if not self.return_type.is_void:
1501 args = self.type.args
1502 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1503 if entry.type.is_overridable:
1504 arglist.append(Naming.skip_dispatch_cname)
1505 elif func_type.is_overridable:
1507 if entry.type.optional_arg_count:
1508 arglist.append(Naming.optional_args_cname)
1509 elif func_type.optional_arg_count:
1510 arglist.append('NULL')
1511 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1515 class PyArgDeclNode(Node):
1516 # Argument which must be a Python object (used
1517 # for * and ** arguments).
1520 # entry Symtab.Entry
1524 class DecoratorNode(Node):
1527 # decorator NameNode or CallNode
1528 child_attrs = ['decorator']
1531 class DefNode(FuncDefNode):
1532 # A Python function definition.
1534 # name string the Python name of the function
1535 # decorators [DecoratorNode] list of decorators
1536 # args [CArgDeclNode] formal arguments
1537 # star_arg PyArgDeclNode or None * argument
1538 # starstar_arg PyArgDeclNode or None ** argument
1539 # doc EncodedString or None
1542 # The following subnode is constructed internally
1543 # when the def statement is inside a Python class definition.
1545 # assmt AssignmentNode Function construction/assignment
1547 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1551 num_required_kw_args = 0
1552 reqd_kw_flags_cname = "0"
1558 def __init__(self, pos, **kwds):
1559 FuncDefNode.__init__(self, pos, **kwds)
1561 for arg in self.args:
1568 self.num_kwonly_args = k
1569 self.num_required_kw_args = rk
1570 self.num_required_args = r
1572 def as_cfunction(self, cfunc=None, scope=None):
1574 error(self.star_arg.pos, "cdef function cannot have star argument")
1575 if self.starstar_arg:
1576 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1579 for formal_arg in self.args:
1580 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1581 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1583 type = py_object_type,
1584 pos = formal_arg.pos))
1585 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1587 has_varargs = False,
1588 exception_value = None,
1589 exception_check = False,
1592 is_overridable = True)
1593 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1595 cfunc_type = cfunc.type
1596 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1597 error(self.pos, "wrong number of arguments")
1598 error(declarator.pos, "previous declaration here")
1599 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1600 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1601 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1602 formal_arg.type = type_arg.type
1603 formal_arg.name_declarator = name_declarator
1605 if cfunc_type.exception_value is None:
1606 exception_value = None
1608 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1609 declarator = CFuncDeclaratorNode(self.pos,
1610 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1612 has_varargs = False,
1613 exception_check = cfunc_type.exception_check,
1614 exception_value = exception_value,
1615 with_gil = cfunc_type.with_gil,
1616 nogil = cfunc_type.nogil)
1617 return CFuncDefNode(self.pos,
1619 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1620 declarator = declarator,
1623 overridable = cfunc_type.is_overridable,
1625 with_gil = cfunc_type.with_gil,
1626 nogil = cfunc_type.nogil,
1627 visibility = 'private',
1629 directive_locals = getattr(cfunc, 'directive_locals', {}))
1631 def analyse_declarations(self, env):
1632 directive_locals = self.directive_locals = env.directives['locals']
1633 for arg in self.args:
1634 if hasattr(arg, 'name'):
1636 name_declarator = None
1638 base_type = arg.base_type.analyse(env)
1639 name_declarator, type = \
1640 arg.declarator.analyse(base_type, env)
1641 arg.name = name_declarator.name
1642 if arg.name in directive_locals:
1643 type_node = directive_locals[arg.name]
1644 other_type = type_node.analyse_as_type(env)
1645 if other_type is None:
1646 error(type_node.pos, "Not a type")
1647 elif (type is not PyrexTypes.py_object_type
1648 and not type.same_as(other_type)):
1649 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1650 error(type_node.pos, "Previous declaration here")
1653 if name_declarator and name_declarator.cname:
1655 "Python function argument cannot have C name specification")
1656 arg.type = type.as_argument_type()
1658 arg.needs_conversion = 0
1659 arg.needs_type_test = 0
1661 if arg.not_none and not arg.type.is_extension_type:
1663 "Only extension type arguments can have 'not None'")
1664 self.declare_pyfunction(env)
1665 self.analyse_signature(env)
1666 self.return_type = self.entry.signature.return_type()
1668 def analyse_signature(self, env):
1669 any_type_tests_needed = 0
1670 if self.entry.is_special:
1671 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1672 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1673 # Use the simpler calling signature for zero- and one-argument functions.
1674 if self.entry.signature is TypeSlots.pyfunction_signature:
1675 if len(self.args) == 0:
1676 self.entry.signature = TypeSlots.pyfunction_noargs
1677 elif len(self.args) == 1:
1678 if self.args[0].default is None and not self.args[0].kw_only:
1679 self.entry.signature = TypeSlots.pyfunction_onearg
1680 elif self.entry.signature is TypeSlots.pymethod_signature:
1681 if len(self.args) == 1:
1682 self.entry.signature = TypeSlots.unaryfunc
1683 elif len(self.args) == 2:
1684 if self.args[1].default is None and not self.args[1].kw_only:
1685 self.entry.signature = TypeSlots.ibinaryfunc
1686 sig = self.entry.signature
1687 nfixed = sig.num_fixed_args()
1688 for i in range(nfixed):
1689 if i < len(self.args):
1692 if sig.is_self_arg(i):
1694 arg.hdr_type = arg.type = env.parent_type
1695 arg.needs_conversion = 0
1697 arg.hdr_type = sig.fixed_arg_type(i)
1698 if not arg.type.same_as(arg.hdr_type):
1699 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1700 arg.needs_type_test = 1
1701 any_type_tests_needed = 1
1703 arg.needs_conversion = 1
1704 if arg.needs_conversion:
1705 arg.hdr_cname = Naming.arg_prefix + arg.name
1707 arg.hdr_cname = Naming.var_prefix + arg.name
1709 self.bad_signature()
1711 if nfixed < len(self.args):
1712 if not sig.has_generic_args:
1713 self.bad_signature()
1714 for arg in self.args:
1715 if arg.is_generic and \
1716 (arg.type.is_extension_type or arg.type.is_builtin_type):
1717 arg.needs_type_test = 1
1718 any_type_tests_needed = 1
1719 if any_type_tests_needed:
1720 env.use_utility_code(arg_type_test_utility_code)
1722 def bad_signature(self):
1723 sig = self.entry.signature
1724 expected_str = "%d" % sig.num_fixed_args()
1725 if sig.has_generic_args:
1726 expected_str = expected_str + " or more"
1728 if name.startswith("__") and name.endswith("__"):
1729 desc = "Special method"
1733 "%s %s has wrong number of arguments "
1734 "(%d declared, %s expected)" % (
1735 desc, self.name, len(self.args), expected_str))
1737 def signature_has_nongeneric_args(self):
1738 argcount = len(self.args)
1739 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1743 def signature_has_generic_args(self):
1744 return self.entry.signature.has_generic_args
1746 def declare_pyfunction(self, env):
1747 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1749 entry = env.lookup_here(self.name)
1750 if entry and entry.type.is_cfunction and not self.is_wrapper:
1751 warning(self.pos, "Overriding cdef method with def method.", 5)
1752 entry = env.declare_pyfunction(self.name, self.pos)
1754 prefix = env.scope_prefix
1755 entry.func_cname = \
1756 Naming.pyfunc_prefix + prefix + name
1757 entry.pymethdef_cname = \
1758 Naming.pymethdef_prefix + prefix + name
1759 if Options.docstrings:
1760 entry.doc = embed_position(self.pos, self.doc)
1762 Naming.funcdoc_prefix + prefix + name
1766 def declare_arguments(self, env):
1767 for arg in self.args:
1769 error(arg.pos, "Missing argument name")
1770 if arg.needs_conversion:
1771 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1772 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1773 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1774 if arg.type.is_pyobject:
1775 arg.entry.init = "0"
1776 arg.entry.init_to_none = 0
1778 arg.entry = self.declare_argument(env, arg)
1780 arg.entry.is_self_arg = arg.is_self_arg
1782 if arg.is_self_arg or \
1783 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1784 arg.entry.is_declared_generic = 1
1785 self.declare_python_arg(env, self.star_arg)
1786 self.declare_python_arg(env, self.starstar_arg)
1788 def declare_python_arg(self, env, arg):
1790 entry = env.declare_var(arg.name,
1791 PyrexTypes.py_object_type, arg.pos)
1794 entry.init_to_none = 0
1795 entry.xdecref_cleanup = 1
1797 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1799 def analyse_expressions(self, env):
1800 self.local_scope.directives = env.directives
1801 self.analyse_default_values(env)
1802 if env.is_py_class_scope:
1803 self.synthesize_assignment_node(env)
1805 def synthesize_assignment_node(self, env):
1807 self.assmt = SingleAssignmentNode(self.pos,
1808 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1809 rhs = ExprNodes.UnboundMethodNode(self.pos,
1810 function = ExprNodes.PyCFunctionNode(self.pos,
1811 pymethdef_cname = self.entry.pymethdef_cname)))
1812 self.assmt.analyse_declarations(env)
1813 self.assmt.analyse_expressions(env)
1815 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1817 sig = self.entry.signature
1818 if sig.has_dummy_arg:
1819 arg_code_list.append(
1820 "PyObject *%s" % Naming.self_cname)
1821 for arg in self.args:
1822 if not arg.is_generic:
1824 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1826 arg_code_list.append(
1827 arg.hdr_type.declaration_code(arg.hdr_cname))
1828 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1829 arg_code_list.append("PyObject *unused")
1830 if sig.has_generic_args:
1831 arg_code_list.append(
1832 "PyObject *%s, PyObject *%s"
1833 % (Naming.args_cname, Naming.kwds_cname))
1834 arg_code = ", ".join(arg_code_list)
1835 dc = self.return_type.declaration_code(self.entry.func_cname)
1836 header = "static %s(%s)" % (dc, arg_code)
1837 code.putln("%s; /*proto*/" % header)
1840 if self.entry.doc and Options.docstrings:
1841 docstr = self.entry.doc
1842 if not isinstance(docstr, str):
1843 docstr = docstr.utf8encode()
1845 'static char %s[] = "%s";' % (
1846 self.entry.doc_cname,
1847 split_docstring(escape_byte_string(docstr))))
1850 "static PyMethodDef %s = " %
1851 self.entry.pymethdef_cname)
1852 code.put_pymethoddef(self.entry, ";")
1853 code.putln("%s {" % header)
1855 def generate_argument_declarations(self, env, code):
1856 for arg in self.args:
1857 if arg.is_generic: # or arg.needs_conversion:
1858 if arg.needs_conversion:
1859 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1861 code.put_var_declaration(arg.entry)
1863 def generate_keyword_list(self, code):
1864 if self.signature_has_generic_args() and \
1865 self.signature_has_nongeneric_args():
1867 "static PyObject **%s[] = {" %
1868 Naming.pykwdlist_cname)
1869 for arg in self.args:
1871 pystring_cname = code.intern_identifier(arg.name)
1872 code.put('&%s,' % pystring_cname)
1875 def generate_argument_parsing_code(self, env, code):
1876 # Generate PyArg_ParseTuple call for generic
1877 # arguments, if any.
1878 if self.entry.signature.has_dummy_arg:
1879 # get rid of unused argument warning
1880 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1882 old_error_label = code.new_error_label()
1883 our_error_label = code.error_label
1884 end_label = code.new_label("argument_unpacking_done")
1886 has_kwonly_args = self.num_kwonly_args > 0
1887 has_star_or_kw_args = self.star_arg is not None \
1888 or self.starstar_arg is not None or has_kwonly_args
1890 for arg in self.args:
1891 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1892 arg.type.create_from_py_utility_code(env)
1894 if not self.signature_has_generic_args():
1895 if has_star_or_kw_args:
1896 error(self.pos, "This method cannot have * or keyword arguments")
1897 self.generate_argument_conversion_code(code)
1899 elif not self.signature_has_nongeneric_args():
1900 # func(*args) or func(**kw) or func(*args, **kw)
1901 self.generate_stararg_copy_code(code)
1904 positional_args = []
1907 for arg in self.args:
1908 arg_entry = arg.entry
1912 if not arg.is_self_arg:
1914 kw_only_args.append(arg)
1916 positional_args.append(arg)
1918 kw_only_args.append(arg)
1921 error(arg.pos, "Non-default argument following default argument")
1922 elif not arg.is_self_arg:
1923 positional_args.append(arg)
1925 self.generate_tuple_and_keyword_parsing_code(
1926 positional_args, kw_only_args, end_label, code)
1928 code.error_label = old_error_label
1929 if code.label_used(our_error_label):
1930 if not code.label_used(end_label):
1931 code.put_goto(end_label)
1932 code.put_label(our_error_label)
1933 if has_star_or_kw_args:
1934 self.generate_arg_decref(self.star_arg, code)
1935 if self.starstar_arg:
1936 if self.starstar_arg.entry.xdecref_cleanup:
1937 code.put_var_xdecref(self.starstar_arg.entry)
1939 code.put_var_decref(self.starstar_arg.entry)
1940 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1941 code.putln("return %s;" % self.error_value())
1942 if code.label_used(end_label):
1943 code.put_label(end_label)
1945 def generate_arg_assignment(self, arg, item, code):
1946 if arg.type.is_pyobject:
1948 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1949 code.putln("%s = %s;" % (arg.entry.cname, item))
1951 func = arg.type.from_py_function
1953 code.putln("%s = %s(%s); %s" % (
1957 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1959 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1961 def generate_arg_xdecref(self, arg, code):
1963 code.put_var_xdecref(arg.entry)
1965 def generate_arg_decref(self, arg, code):
1967 code.put_var_decref(arg.entry)
1969 def generate_stararg_copy_code(self, code):
1970 if not self.star_arg:
1971 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1972 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1974 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1975 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1978 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1980 if self.starstar_arg:
1982 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1984 kwarg_check = "%s" % Naming.kwds_cname
1986 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1987 Naming.kwds_cname, Naming.kwds_cname)
1989 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1990 kwarg_check, Naming.kwds_cname, self.name,
1991 bool(self.starstar_arg), self.error_value()))
1993 if self.starstar_arg:
1994 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1995 self.starstar_arg.entry.cname,
1998 code.putln("if (unlikely(!%s)) return %s;" % (
1999 self.starstar_arg.entry.cname, self.error_value()))
2000 self.starstar_arg.entry.xdecref_cleanup = 0
2001 code.put_gotref(self.starstar_arg.entry.cname)
2005 code.put_incref(Naming.args_cname, py_object_type)
2006 code.putln("%s = %s;" % (
2007 self.star_arg.entry.cname,
2009 self.star_arg.entry.xdecref_cleanup = 0
2011 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2012 kw_only_args, success_label, code):
2013 argtuple_error_label = code.new_label("argtuple_error")
2015 min_positional_args = self.num_required_args - self.num_required_kw_args
2016 if len(self.args) > 0 and self.args[0].is_self_arg:
2017 min_positional_args -= 1
2018 max_positional_args = len(positional_args)
2019 has_fixed_positional_count = not self.star_arg and \
2020 min_positional_args == max_positional_args
2022 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2023 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2024 if self.num_required_kw_args:
2025 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2027 if self.starstar_arg or self.star_arg:
2028 self.generate_stararg_init_code(max_positional_args, code)
2030 # --- optimised code when we receive keyword arguments
2031 if self.num_required_kw_args:
2032 likely_hint = "likely"
2034 likely_hint = "unlikely"
2035 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2036 self.generate_keyword_unpacking_code(
2037 min_positional_args, max_positional_args,
2038 has_fixed_positional_count,
2039 positional_args, kw_only_args, argtuple_error_label, code)
2041 # --- optimised code when we do not receive any keyword arguments
2042 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2043 # Python raises arg tuple related errors first, so we must
2044 # check the length here
2045 if min_positional_args == max_positional_args and not self.star_arg:
2049 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2050 Naming.args_cname, compare, min_positional_args))
2051 code.put_goto(argtuple_error_label)
2053 if self.num_required_kw_args:
2054 # pure error case: keywords required but not passed
2055 if max_positional_args > min_positional_args and not self.star_arg:
2056 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2057 Naming.args_cname, max_positional_args))
2058 code.put_goto(argtuple_error_label)
2059 code.putln('} else {')
2060 for i, arg in enumerate(kw_only_args):
2062 pystring_cname = code.intern_identifier(arg.name)
2063 # required keyword-only argument missing
2064 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2065 self.name.utf8encode(),
2067 code.putln(code.error_goto(self.pos))
2070 elif min_positional_args == max_positional_args:
2071 # parse the exact number of positional arguments from the
2073 code.putln('} else {')
2074 for i, arg in enumerate(positional_args):
2075 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2076 self.generate_arg_assignment(arg, item, code)
2077 self.generate_arg_default_assignments(code)
2080 # parse the positional arguments from the variable length
2082 code.putln('} else {')
2083 self.generate_arg_default_assignments(code)
2084 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2086 code.putln('default:')
2087 reversed_args = list(enumerate(positional_args))[::-1]
2088 for i, arg in reversed_args:
2089 if i >= min_positional_args-1:
2090 if min_positional_args > 1:
2091 code.putln('case %2d:' % (i+1)) # pure code beautification
2093 code.put('case %2d: ' % (i+1))
2094 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2095 self.generate_arg_assignment(arg, item, code)
2096 if min_positional_args == 0:
2097 code.put('case 0: ')
2098 code.putln('break;')
2100 if min_positional_args:
2101 for i in range(min_positional_args-1, -1, -1):
2102 code.putln('case %2d:' % i)
2103 code.put_goto(argtuple_error_label)
2105 code.put('default: ')
2106 code.put_goto(argtuple_error_label)
2111 if code.label_used(argtuple_error_label):
2112 code.put_goto(success_label)
2113 code.put_label(argtuple_error_label)
2114 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2115 self.name.utf8encode(), has_fixed_positional_count,
2116 min_positional_args, max_positional_args,
2118 code.putln(code.error_goto(self.pos))
2120 def generate_arg_default_assignments(self, code):
2121 for arg in self.args:
2122 if arg.is_generic and arg.default:
2126 arg.calculate_default_value_code(code)))
2128 def generate_stararg_init_code(self, max_positional_args, code):
2129 if self.starstar_arg:
2130 self.starstar_arg.entry.xdecref_cleanup = 0
2131 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2132 self.starstar_arg.entry.cname,
2133 self.starstar_arg.entry.cname,
2134 self.error_value()))
2135 code.put_gotref(self.starstar_arg.entry.cname)
2137 self.star_arg.entry.xdecref_cleanup = 0
2138 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2140 max_positional_args))
2141 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2142 self.star_arg.entry.cname, Naming.args_cname,
2143 max_positional_args, Naming.args_cname))
2144 code.put_gotref(self.star_arg.entry.cname)
2145 if self.starstar_arg:
2147 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2148 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2149 code.putln('return %s;' % self.error_value())
2152 code.putln("if (unlikely(!%s)) return %s;" % (
2153 self.star_arg.entry.cname, self.error_value()))
2154 code.putln('} else {')
2155 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2156 code.put_incref(Naming.empty_tuple, py_object_type)
2159 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2160 has_fixed_positional_count, positional_args,
2161 kw_only_args, argtuple_error_label, code):
2162 all_args = tuple(positional_args) + tuple(kw_only_args)
2163 max_args = len(all_args)
2166 for i, arg in enumerate(all_args):
2167 if arg.default and arg.type.is_pyobject:
2168 default_value = arg.calculate_default_value_code(code)
2169 if arg.type is not PyrexTypes.py_object_type:
2170 default_value = "(PyObject*)"+default_value
2171 default_args.append((i, default_value))
2173 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2175 # it looks funny to separate the init-to-0 from setting the
2176 # default value, but C89 needs this
2177 code.putln("PyObject* values[%d] = {%s};" % (
2178 max_args, ','.join(['0']*max_args)))
2179 for i, default_value in default_args:
2180 code.putln('values[%d] = %s;' % (i, default_value))
2182 # parse the tuple and check that it's not too long
2183 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2185 code.putln('default:')
2186 for i in range(max_positional_args-1, -1, -1):
2187 code.put('case %2d: ' % (i+1))
2188 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2189 i, Naming.args_cname, i))
2190 code.putln('case 0: break;')
2191 if not self.star_arg:
2192 code.put('default: ') # more arguments than allowed
2193 code.put_goto(argtuple_error_label)
2196 # now fill up the positional/required arguments with values
2198 if self.num_required_args or max_positional_args > 0:
2199 last_required_arg = -1
2200 for i, arg in enumerate(all_args):
2202 last_required_arg = i
2203 if last_required_arg < max_positional_args:
2204 last_required_arg = max_positional_args-1
2205 num_required_args = self.num_required_args
2206 if max_positional_args > 0:
2207 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2208 for i, arg in enumerate(all_args[:last_required_arg+1]):
2209 if max_positional_args > 0 and i <= max_positional_args:
2210 if self.star_arg and i == max_positional_args:
2211 code.putln('default:')
2213 code.putln('case %2d:' % i)
2214 pystring_cname = code.intern_identifier(arg.name)
2217 # handled separately below
2219 code.putln('if (kw_args > %d) {' % num_required_args)
2220 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2221 Naming.kwds_cname, pystring_cname))
2222 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2225 num_required_args -= 1
2226 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2227 i, Naming.kwds_cname, pystring_cname))
2228 code.putln('if (likely(values[%d])) kw_args--;' % i);
2229 if i < min_positional_args:
2231 # special case: we know arg 0 is missing
2233 code.put_goto(argtuple_error_label)
2235 # print the correct number of values (args or
2236 # kwargs) that were passed into positional
2237 # arguments up to this point
2238 code.putln('else {')
2239 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2240 self.name.utf8encode(), has_fixed_positional_count,
2241 min_positional_args, max_positional_args, i))
2242 code.putln(code.error_goto(self.pos))
2245 code.putln('else {')
2246 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2247 self.name.utf8encode(), pystring_cname))
2248 code.putln(code.error_goto(self.pos))
2250 if max_positional_args > 0:
2253 if kw_only_args and not self.starstar_arg:
2254 # unpack optional keyword-only arguments
2255 # checking for interned strings in a dict is faster than iterating
2256 # but it's too likely that we must iterate if we expect **kwargs
2258 for i, arg in enumerate(all_args[max_positional_args:]):
2259 if not arg.kw_only or not arg.default:
2261 optional_args.append((i+max_positional_args, arg))
2263 # this mimics an unrolled loop so that we can "break" out of it
2264 code.putln('while (kw_args > 0) {')
2265 code.putln('PyObject* value;')
2266 for i, arg in optional_args:
2267 pystring_cname = code.intern_identifier(arg.name)
2269 'value = PyDict_GetItem(%s, %s);' % (
2270 Naming.kwds_cname, pystring_cname))
2272 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2273 code.putln('break;')
2276 code.putln('if (unlikely(kw_args > 0)) {')
2277 # non-positional/-required kw args left in dict: default args,
2278 # kw-only args, **kwargs or error
2280 # This is sort of a catch-all: except for checking required
2281 # arguments, this will always do the right thing for unpacking
2282 # keyword arguments, so that we can concentrate on optimising
2283 # common cases above.
2284 if max_positional_args == 0:
2287 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2288 Naming.args_cname, max_positional_args,
2289 Naming.args_cname, max_positional_args))
2290 pos_arg_count = "used_pos_args"
2292 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2293 code.globalstate.use_utility_code(parse_keywords_utility_code)
2295 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2297 Naming.pykwdlist_cname,
2298 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2300 self.name.utf8encode()))
2301 code.putln(code.error_goto(self.pos))
2304 # convert arg values to their final type and assign them
2305 for i, arg in enumerate(all_args):
2306 if arg.default and not arg.type.is_pyobject:
2307 code.putln("if (values[%d]) {" % i)
2308 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2309 if arg.default and not arg.type.is_pyobject:
2310 code.putln('} else {')
2314 arg.calculate_default_value_code(code)))
2317 def generate_argument_conversion_code(self, code):
2318 # Generate code to convert arguments from
2319 # signature type to declared type, if needed.
2320 for arg in self.args:
2321 if arg.needs_conversion:
2322 self.generate_arg_conversion(arg, code)
2324 def generate_arg_conversion(self, arg, code):
2325 # Generate conversion code for one argument.
2326 old_type = arg.hdr_type
2328 if old_type.is_pyobject:
2330 code.putln("if (%s) {" % arg.hdr_cname)
2332 code.putln("assert(%s); {" % arg.hdr_cname)
2333 self.generate_arg_conversion_from_pyobject(arg, code)
2335 elif new_type.is_pyobject:
2336 self.generate_arg_conversion_to_pyobject(arg, code)
2338 if new_type.assignable_from(old_type):
2340 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2343 "Cannot convert 1 argument from '%s' to '%s'" %
2344 (old_type, new_type))
2346 def generate_arg_conversion_from_pyobject(self, arg, code):
2348 func = new_type.from_py_function
2349 # copied from CoerceFromPyTypeNode
2351 code.putln("%s = %s(%s); %s" % (
2355 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2358 "Cannot convert Python object argument to type '%s'"
2361 def generate_arg_conversion_to_pyobject(self, arg, code):
2362 old_type = arg.hdr_type
2363 func = old_type.to_py_function
2365 code.putln("%s = %s(%s); %s" % (
2369 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2370 code.put_var_gotref(arg.entry)
2373 "Cannot convert argument of type '%s' to Python object"
2376 def generate_argument_type_tests(self, code):
2377 # Generate type tests for args whose signature
2378 # type is PyObject * and whose declared type is
2379 # a subtype thereof.
2380 for arg in self.args:
2381 if arg.needs_type_test:
2382 self.generate_arg_type_test(arg, code)
2384 def generate_arg_type_test(self, arg, code):
2385 # Generate type test for one argument.
2386 if arg.type.typeobj_is_available():
2387 typeptr_cname = arg.type.typeptr_cname
2388 arg_code = "((PyObject *)%s)" % arg.entry.cname
2390 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2395 arg.type.is_builtin_type,
2396 code.error_goto(arg.pos)))
2398 error(arg.pos, "Cannot test type of extern C class "
2399 "without type object name specification")
2401 def error_value(self):
2402 return self.entry.signature.error_value
2404 def caller_will_check_exceptions(self):
2407 class OverrideCheckNode(StatNode):
2408 # A Node for dispatching to the def method if it
2417 child_attrs = ['body']
2421 def analyse_expressions(self, env):
2422 self.args = env.arg_entries
2423 if self.py_func.is_module_scope:
2428 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2429 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2430 call_node = ExprNodes.SimpleCallNode(self.pos,
2431 function=self.func_node,
2432 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2433 self.body = ReturnStatNode(self.pos, value=call_node)
2434 self.body.analyse_expressions(env)
2436 def generate_execution_code(self, code):
2437 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2438 # Check to see if we are an extension type
2439 if self.py_func.is_module_scope:
2440 self_arg = "((PyObject *)%s)" % Naming.module_cname
2442 self_arg = "((PyObject *)%s)" % self.args[0].cname
2443 code.putln("/* Check if called by wrapper */")
2444 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2445 code.putln("/* Check if overriden in Python */")
2446 if self.py_func.is_module_scope:
2447 code.putln("else {")
2449 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2450 self.func_node.allocate(code)
2451 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2452 # need to get attribute manually--scope would return cdef method
2453 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2454 self.func_node.result(), self_arg, interned_attr_cname, err))
2455 code.put_gotref(self.func_node.py_result())
2456 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2457 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2458 self.func_node.result(), self.py_func.entry.func_cname)
2459 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2460 self.body.generate_execution_code(code)
2462 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2464 self.func_node.release(code)
2466 class ClassDefNode(StatNode, BlockNode):
2469 class PyClassDefNode(ClassDefNode):
2470 # A Python class definition.
2472 # name EncodedString Name of the class
2473 # doc string or None
2474 # body StatNode Attribute definition code
2475 # entry Symtab.Entry
2476 # scope PyClassScope
2477 # decorators [DecoratorNode] list of decorators or None
2479 # The following subnodes are constructed internally:
2481 # dict DictNode Class dictionary
2482 # classobj ClassNode Class object
2483 # target NameNode Variable to assign class object to
2485 child_attrs = ["body", "dict", "classobj", "target"]
2488 def __init__(self, pos, name, bases, doc, body, decorators = None):
2489 StatNode.__init__(self, pos)
2493 self.decorators = decorators
2495 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2496 if self.doc and Options.docstrings:
2497 doc = embed_position(self.pos, self.doc)
2498 doc_node = ExprNodes.StringNode(pos, value = doc)
2501 self.classobj = ExprNodes.ClassNode(pos, name = name,
2502 bases = bases, dict = self.dict, doc = doc_node)
2503 self.target = ExprNodes.NameNode(pos, name = name)
2505 def as_cclass(self):
2507 Return this node as if it were declared as an extension class
2509 bases = self.classobj.bases.args
2511 base_class_name = None
2512 base_class_module = None
2513 elif len(bases) == 1:
2516 from ExprNodes import AttributeNode, NameNode
2517 while isinstance(base, AttributeNode):
2518 path.insert(0, base.attribute)
2520 if isinstance(base, NameNode):
2521 path.insert(0, base.name)
2522 base_class_name = path[-1]
2524 base_class_module = u'.'.join(path[:-1])
2526 base_class_module = None
2528 error(self.classobj.bases.args.pos, "Invalid base class")
2530 error(self.classobj.bases.args.pos, "C class may only have one base class")
2533 return CClassDefNode(self.pos,
2534 visibility = 'private',
2536 class_name = self.name,
2537 base_class_module = base_class_module,
2538 base_class_name = base_class_name,
2539 decorators = self.decorators,
2544 def create_scope(self, env):
2546 while env.is_py_class_scope or env.is_c_class_scope:
2547 env = env.outer_scope
2548 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2551 def analyse_declarations(self, env):
2552 self.target.analyse_target_declaration(env)
2553 cenv = self.create_scope(env)
2554 cenv.directives = env.directives
2555 cenv.class_obj_cname = self.target.entry.cname
2556 self.body.analyse_declarations(cenv)
2558 def analyse_expressions(self, env):
2559 self.dict.analyse_expressions(env)
2560 self.classobj.analyse_expressions(env)
2561 genv = env.global_scope()
2563 self.body.analyse_expressions(cenv)
2564 self.target.analyse_target_expression(env, self.classobj)
2566 def generate_function_definitions(self, env, code):
2567 self.body.generate_function_definitions(self.scope, code)
2569 def generate_execution_code(self, code):
2570 code.pyclass_stack.append(self)
2572 self.dict.generate_evaluation_code(code)
2573 self.classobj.generate_evaluation_code(code)
2574 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2575 self.body.generate_execution_code(code)
2576 self.target.generate_assignment_code(self.classobj, code)
2577 self.dict.generate_disposal_code(code)
2578 self.dict.free_temps(code)
2579 code.pyclass_stack.pop()
2582 class CClassDefNode(ClassDefNode):
2583 # An extension type definition.
2585 # visibility 'private' or 'public' or 'extern'
2586 # typedef_flag boolean
2588 # module_name string or None For import of extern type objects
2589 # class_name string Unqualified name of class
2590 # as_name string or None Name to declare as in this scope
2591 # base_class_module string or None Module containing the base class
2592 # base_class_name string or None Name of the base class
2593 # objstruct_name string or None Specified C name of object struct
2594 # typeobj_name string or None Specified C name of type object
2595 # in_pxd boolean Is in a .pxd file
2596 # decorators [DecoratorNode] list of decorators or None
2597 # doc string or None
2598 # body StatNode or None
2599 # entry Symtab.Entry
2600 # base_type PyExtensionType or None
2601 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2602 # buffer_defaults_pos
2604 child_attrs = ["body"]
2605 buffer_defaults_node = None
2606 buffer_defaults_pos = None
2607 typedef_flag = False
2609 objstruct_name = None
2613 def analyse_declarations(self, env):
2614 #print "CClassDefNode.analyse_declarations:", self.class_name
2615 #print "...visibility =", self.visibility
2616 #print "...module_name =", self.module_name
2619 if self.buffer_defaults_node:
2620 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2621 env, [], self.buffer_defaults_node,
2622 need_complete=False)
2624 buffer_defaults = None
2626 if env.in_cinclude and not self.objstruct_name:
2627 error(self.pos, "Object struct name specification required for "
2628 "C class defined in 'extern from' block")
2629 self.base_type = None
2630 # Now that module imports are cached, we need to
2631 # import the modules for extern classes.
2632 if self.module_name:
2634 for module in env.cimported_modules:
2635 if module.name == self.module_name:
2636 self.module = module
2637 if self.module is None:
2638 self.module = ModuleScope(self.module_name, None, env.context)
2639 self.module.has_extern_class = 1
2640 env.add_imported_module(self.module)
2642 if self.base_class_name:
2643 if self.base_class_module:
2644 base_class_scope = env.find_module(self.base_class_module, self.pos)
2646 base_class_scope = env
2647 if self.base_class_name == 'object':
2648 # extension classes are special and don't need to inherit from object
2649 if base_class_scope is None or base_class_scope.lookup('object') is None:
2650 self.base_class_name = None
2651 self.base_class_module = None
2652 base_class_scope = None
2653 if base_class_scope:
2654 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2655 if base_class_entry:
2656 if not base_class_entry.is_type:
2657 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2658 elif not base_class_entry.type.is_extension_type:
2659 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2660 elif not base_class_entry.type.is_complete():
2661 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2663 self.base_type = base_class_entry.type
2664 has_body = self.body is not None
2665 if self.module_name and self.visibility != 'extern':
2666 module_path = self.module_name.split(".")
2667 home_scope = env.find_imported_module(module_path, self.pos)
2673 if self.visibility == 'extern':
2674 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2675 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2677 self.entry = home_scope.declare_c_class(
2678 name = self.class_name,
2680 defining = has_body and self.in_pxd,
2681 implementing = has_body and not self.in_pxd,
2682 module_name = self.module_name,
2683 base_type = self.base_type,
2684 objstruct_cname = self.objstruct_name,
2685 typeobj_cname = self.typeobj_name,
2686 visibility = self.visibility,
2687 typedef_flag = self.typedef_flag,
2689 buffer_defaults = buffer_defaults)
2690 if home_scope is not env and self.visibility == 'extern':
2691 env.add_imported_entry(self.class_name, self.entry, pos)
2692 scope = self.entry.type.scope
2693 if scope is not None:
2694 scope.directives = env.directives
2696 if self.doc and Options.docstrings:
2697 scope.doc = embed_position(self.pos, self.doc)
2700 self.body.analyse_declarations(scope)
2704 scope.implemented = 1
2705 env.allocate_vtable_names(self.entry)
2707 def analyse_expressions(self, env):
2709 scope = self.entry.type.scope
2710 self.body.analyse_expressions(scope)
2712 def generate_function_definitions(self, env, code):
2714 self.body.generate_function_definitions(
2715 self.entry.type.scope, code)
2717 def generate_execution_code(self, code):
2718 # This is needed to generate evaluation code for
2719 # default values of method arguments.
2721 self.body.generate_execution_code(code)
2723 def annotate(self, code):
2725 self.body.annotate(code)
2728 class PropertyNode(StatNode):
2729 # Definition of a property in an extension type.
2732 # doc EncodedString or None Doc string
2735 child_attrs = ["body"]
2737 def analyse_declarations(self, env):
2738 entry = env.declare_property(self.name, self.doc, self.pos)
2740 entry.scope.directives = env.directives
2741 self.body.analyse_declarations(entry.scope)
2743 def analyse_expressions(self, env):
2744 self.body.analyse_expressions(env)
2746 def generate_function_definitions(self, env, code):
2747 self.body.generate_function_definitions(env, code)
2749 def generate_execution_code(self, code):
2752 def annotate(self, code):
2753 self.body.annotate(code)
2756 class GlobalNode(StatNode):
2757 # Global variable declaration.
2763 def analyse_declarations(self, env):
2764 for name in self.names:
2765 env.declare_global(name, self.pos)
2767 def analyse_expressions(self, env):
2770 def generate_execution_code(self, code):
2774 class ExprStatNode(StatNode):
2775 # Expression used as a statement.
2779 child_attrs = ["expr"]
2781 def analyse_declarations(self, env):
2783 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2784 func = self.expr.function.as_cython_attribute()
2785 if func == u'declare':
2786 args, kwds = self.expr.explicit_args_kwds()
2788 error(self.expr.pos, "Variable names must be specified.")
2789 for var, type_node in kwds.key_value_pairs:
2790 type = type_node.analyse_as_type(env)
2792 error(type_node.pos, "Unknown type")
2794 env.declare_var(var.value, type, var.pos, is_cdef = True)
2795 self.__class__ = PassStatNode
2797 def analyse_expressions(self, env):
2798 self.expr.analyse_expressions(env)
2800 def generate_execution_code(self, code):
2801 self.expr.generate_evaluation_code(code)
2802 if not self.expr.is_temp and self.expr.result():
2803 code.putln("%s;" % self.expr.result())
2804 self.expr.generate_disposal_code(code)
2805 self.expr.free_temps(code)
2807 def annotate(self, code):
2808 self.expr.annotate(code)
2811 class AssignmentNode(StatNode):
2812 # Abstract base class for assignment nodes.
2814 # The analyse_expressions and generate_execution_code
2815 # phases of assignments are split into two sub-phases
2816 # each, to enable all the right hand sides of a
2817 # parallel assignment to be evaluated before assigning
2818 # to any of the left hand sides.
2820 def analyse_expressions(self, env):
2821 self.analyse_types(env)
2823 # def analyse_expressions(self, env):
2824 # self.analyse_expressions_1(env)
2825 # self.analyse_expressions_2(env)
2827 def generate_execution_code(self, code):
2828 self.generate_rhs_evaluation_code(code)
2829 self.generate_assignment_code(code)
2832 class SingleAssignmentNode(AssignmentNode):
2833 # The simplest case:
2837 # lhs ExprNode Left hand side
2838 # rhs ExprNode Right hand side
2839 # first bool Is this guaranteed the first assignment to lhs?
2841 child_attrs = ["lhs", "rhs"]
2843 declaration_only = False
2845 def analyse_declarations(self, env):
2848 # handle declarations of the form x = cython.foo()
2849 if isinstance(self.rhs, ExprNodes.CallNode):
2850 func_name = self.rhs.function.as_cython_attribute()
2852 args, kwds = self.rhs.explicit_args_kwds()
2854 if func_name in ['declare', 'typedef']:
2855 if len(args) > 2 or kwds is not None:
2856 error(rhs.pos, "Can only declare one type at a time.")
2858 type = args[0].analyse_as_type(env)
2860 error(args[0].pos, "Unknown type")
2863 if func_name == 'declare':
2864 if isinstance(lhs, ExprNodes.NameNode):
2865 vars = [(lhs.name, lhs.pos)]
2866 elif isinstance(lhs, ExprNodes.TupleNode):
2867 vars = [(var.name, var.pos) for var in lhs.args]
2869 error(lhs.pos, "Invalid declaration")
2871 for var, pos in vars:
2872 env.declare_var(var, type, pos, is_cdef = True)
2877 self.declaration_only = True
2879 self.declaration_only = True
2880 if not isinstance(lhs, ExprNodes.NameNode):
2881 error(lhs.pos, "Invalid declaration.")
2882 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2884 elif func_name in ['struct', 'union']:
2885 self.declaration_only = True
2886 if len(args) > 0 or kwds is None:
2887 error(rhs.pos, "Struct or union members must be given by name.")
2890 for member, type_node in kwds.key_value_pairs:
2891 type = type_node.analyse_as_type(env)
2893 error(type_node.pos, "Unknown type")
2895 members.append((member.value, type, member.pos))
2896 if len(members) < len(kwds.key_value_pairs):
2898 if not isinstance(self.lhs, ExprNodes.NameNode):
2899 error(self.lhs.pos, "Invalid declaration.")
2900 name = self.lhs.name
2901 scope = StructOrUnionScope(name)
2902 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2903 for member, type, pos in members:
2904 scope.declare_var(member, type, pos)
2906 if self.declaration_only:
2909 self.lhs.analyse_target_declaration(env)
2911 def analyse_types(self, env, use_temp = 0):
2912 self.rhs.analyse_types(env)
2913 self.lhs.analyse_target_types(env)
2914 self.lhs.gil_assignment_check(env)
2915 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2917 self.rhs = self.rhs.coerce_to_temp(env)
2919 def generate_rhs_evaluation_code(self, code):
2920 self.rhs.generate_evaluation_code(code)
2922 def generate_assignment_code(self, code):
2923 self.lhs.generate_assignment_code(self.rhs, code)
2925 def annotate(self, code):
2926 self.lhs.annotate(code)
2927 self.rhs.annotate(code)
2930 class CascadedAssignmentNode(AssignmentNode):
2931 # An assignment with multiple left hand sides:
2935 # lhs_list [ExprNode] Left hand sides
2936 # rhs ExprNode Right hand sides
2940 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2942 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2943 coerced_rhs_list = None
2945 def analyse_declarations(self, env):
2946 for lhs in self.lhs_list:
2947 lhs.analyse_target_declaration(env)
2949 def analyse_types(self, env, use_temp = 0):
2950 self.rhs.analyse_types(env)
2952 self.rhs = self.rhs.coerce_to_temp(env)
2954 self.rhs = self.rhs.coerce_to_simple(env)
2955 from ExprNodes import CloneNode
2956 self.coerced_rhs_list = []
2957 for lhs in self.lhs_list:
2958 lhs.analyse_target_types(env)
2959 lhs.gil_assignment_check(env)
2960 rhs = CloneNode(self.rhs)
2961 rhs = rhs.coerce_to(lhs.type, env)
2962 self.coerced_rhs_list.append(rhs)
2964 def generate_rhs_evaluation_code(self, code):
2965 self.rhs.generate_evaluation_code(code)
2967 def generate_assignment_code(self, code):
2968 for i in range(len(self.lhs_list)):
2969 lhs = self.lhs_list[i]
2970 rhs = self.coerced_rhs_list[i]
2971 rhs.generate_evaluation_code(code)
2972 lhs.generate_assignment_code(rhs, code)
2973 # Assignment has disposed of the cloned RHS
2974 self.rhs.generate_disposal_code(code)
2975 self.rhs.free_temps(code)
2977 def annotate(self, code):
2978 for i in range(len(self.lhs_list)):
2979 lhs = self.lhs_list[i].annotate(code)
2980 rhs = self.coerced_rhs_list[i].annotate(code)
2981 self.rhs.annotate(code)
2984 class ParallelAssignmentNode(AssignmentNode):
2985 # A combined packing/unpacking assignment:
2989 # This has been rearranged by the parser into
2991 # a = d ; b = e ; c = f
2993 # but we must evaluate all the right hand sides
2994 # before assigning to any of the left hand sides.
2996 # stats [AssignmentNode] The constituent assignments
2998 child_attrs = ["stats"]
3000 def analyse_declarations(self, env):
3001 for stat in self.stats:
3002 stat.analyse_declarations(env)
3004 def analyse_expressions(self, env):
3005 for stat in self.stats:
3006 stat.analyse_types(env, use_temp = 1)
3008 # def analyse_expressions(self, env):
3009 # for stat in self.stats:
3010 # stat.analyse_expressions_1(env, use_temp = 1)
3011 # for stat in self.stats:
3012 # stat.analyse_expressions_2(env)
3014 def generate_execution_code(self, code):
3015 for stat in self.stats:
3016 stat.generate_rhs_evaluation_code(code)
3017 for stat in self.stats:
3018 stat.generate_assignment_code(code)
3020 def annotate(self, code):
3021 for stat in self.stats:
3025 class InPlaceAssignmentNode(AssignmentNode):
3026 # An in place arithmatic operand:
3032 # lhs ExprNode Left hand side
3033 # rhs ExprNode Right hand side
3034 # op char one of "+-*/%^&|"
3035 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3037 # This code is a bit tricky because in order to obey Python
3038 # semantics the sub-expressions (e.g. indices) of the lhs must
3039 # not be evaluated twice. So we must re-use the values calculated
3040 # in evaluation phase for the assignment phase as well.
3041 # Fortunately, the type of the lhs node is fairly constrained
3042 # (it must be a NameNode, AttributeNode, or IndexNode).
3044 child_attrs = ["lhs", "rhs"]
3047 def analyse_declarations(self, env):
3048 self.lhs.analyse_target_declaration(env)
3050 def analyse_types(self, env):
3051 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3052 self.rhs.analyse_types(env)
3053 self.lhs.analyse_target_types(env)
3054 if Options.incref_local_binop and self.dup.type.is_pyobject:
3055 self.dup = self.dup.coerce_to_temp(env)
3057 if self.lhs.type.is_pyobject:
3058 self.rhs = self.rhs.coerce_to_pyobject(env)
3059 elif self.rhs.type.is_pyobject:
3060 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3061 if self.lhs.type.is_pyobject:
3062 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3063 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3065 def generate_execution_code(self, code):
3067 self.rhs.generate_evaluation_code(code)
3068 self.dup.generate_subexpr_evaluation_code(code)
3069 if self.dup.is_temp:
3070 self.dup.allocate_temp_result(code)
3071 # self.dup.generate_result_code is run only if it is not buffer access
3072 if self.operator == "**":
3076 if self.lhs.type.is_pyobject:
3077 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3078 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3079 self.dup.generate_result_code(code)
3080 self.result_value_temp.allocate(code)
3082 "%s = %s(%s, %s%s); %s" % (
3083 self.result_value.result(),
3084 self.py_operation_function(),
3085 self.dup.py_result(),
3086 self.rhs.py_result(),
3088 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3089 code.put_gotref(self.result_value.py_result())
3090 self.result_value.generate_evaluation_code(code) # May be a type check...
3091 self.rhs.generate_disposal_code(code)
3092 self.rhs.free_temps(code)
3093 self.dup.generate_disposal_code(code)
3094 self.dup.free_temps(code)
3095 self.lhs.generate_assignment_code(self.result_value, code)
3096 self.result_value_temp.release(code)
3098 c_op = self.operator
3102 error(self.pos, "No C inplace power operator")
3103 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3104 error(self.pos, "Inplace operators not implemented for complex types.")
3106 # have to do assignment directly to avoid side-effects
3107 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3108 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3110 self.dup.generate_result_code(code)
3111 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3112 self.rhs.generate_disposal_code(code)
3113 self.rhs.free_temps(code)
3114 if self.dup.is_temp:
3115 self.dup.generate_subexpr_disposal_code(code)
3116 self.dup.free_subexpr_temps(code)
3118 def create_dup_node(self, env):
3121 self.dup.analyse_types(env)
3122 if isinstance(self.lhs, ExprNodes.NameNode):
3123 target_lhs = ExprNodes.NameNode(self.dup.pos,
3124 name = self.dup.name,
3125 is_temp = self.dup.is_temp,
3126 entry = self.dup.entry)
3127 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3128 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3129 obj = ExprNodes.CloneNode(self.lhs.obj),
3130 attribute = self.dup.attribute,
3131 is_temp = self.dup.is_temp)
3132 elif isinstance(self.lhs, ExprNodes.IndexNode):
3134 index = ExprNodes.CloneNode(self.lhs.index)
3137 if self.lhs.indices:
3138 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3141 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3142 base = ExprNodes.CloneNode(self.dup.base),
3145 is_temp = self.dup.is_temp)
3148 self.lhs = target_lhs
3151 def py_operation_function(self):
3152 return self.py_functions[self.operator]
3155 "|": "PyNumber_InPlaceOr",
3156 "^": "PyNumber_InPlaceXor",
3157 "&": "PyNumber_InPlaceAnd",
3158 "+": "PyNumber_InPlaceAdd",
3159 "-": "PyNumber_InPlaceSubtract",
3160 "*": "PyNumber_InPlaceMultiply",
3161 "/": "PyNumber_InPlaceDivide",
3162 "%": "PyNumber_InPlaceRemainder",
3163 "<<": "PyNumber_InPlaceLshift",
3164 ">>": "PyNumber_InPlaceRshift",
3165 "**": "PyNumber_InPlacePower",
3166 "//": "PyNumber_InPlaceFloorDivide",
3169 def annotate(self, code):
3170 self.lhs.annotate(code)
3171 self.rhs.annotate(code)
3172 self.dup.annotate(code)
3175 class PrintStatNode(StatNode):
3178 # arg_tuple TupleNode
3179 # append_newline boolean
3181 child_attrs = ["arg_tuple"]
3183 def analyse_expressions(self, env):
3184 self.arg_tuple.analyse_expressions(env)
3185 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3186 env.use_utility_code(printing_utility_code)
3187 if len(self.arg_tuple.args) == 1 and self.append_newline:
3188 env.use_utility_code(printing_one_utility_code)
3190 nogil_check = Node.gil_error
3191 gil_message = "Python print statement"
3193 def generate_execution_code(self, code):
3194 if len(self.arg_tuple.args) == 1 and self.append_newline:
3195 arg = self.arg_tuple.args[0]
3196 arg.generate_evaluation_code(code)
3199 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3201 code.error_goto(self.pos)))
3202 arg.generate_disposal_code(code)
3203 arg.free_temps(code)
3205 self.arg_tuple.generate_evaluation_code(code)
3207 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3208 self.arg_tuple.py_result(),
3209 self.append_newline,
3210 code.error_goto(self.pos)))
3211 self.arg_tuple.generate_disposal_code(code)
3212 self.arg_tuple.free_temps(code)
3214 def annotate(self, code):
3215 self.arg_tuple.annotate(code)
3218 class ExecStatNode(StatNode):
3223 child_attrs = ["args"]
3225 def analyse_expressions(self, env):
3226 for i, arg in enumerate(self.args):
3227 arg.analyse_expressions(env)
3228 arg = arg.coerce_to_pyobject(env)
3230 env.use_utility_code(Builtin.pyexec_utility_code)
3232 nogil_check = Node.gil_error
3233 gil_message = "Python exec statement"
3235 def generate_execution_code(self, code):
3237 for arg in self.args:
3238 arg.generate_evaluation_code(code)
3239 args.append( arg.py_result() )
3240 args = tuple(args + ['0', '0'][:3-len(args)])
3241 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3242 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3243 (temp_result,) + args))
3244 for arg in self.args:
3245 arg.generate_disposal_code(code)
3246 arg.free_temps(code)
3248 code.error_goto_if_null(temp_result, self.pos))
3249 code.put_gotref(temp_result)
3250 code.put_decref_clear(temp_result, py_object_type)
3251 code.funcstate.release_temp(temp_result)
3253 def annotate(self, code):
3254 for arg in self.args:
3258 class DelStatNode(StatNode):
3263 child_attrs = ["args"]
3265 def analyse_declarations(self, env):
3266 for arg in self.args:
3267 arg.analyse_target_declaration(env)
3269 def analyse_expressions(self, env):
3270 for arg in self.args:
3271 arg.analyse_target_expression(env, None)
3272 if not arg.type.is_pyobject:
3273 error(arg.pos, "Deletion of non-Python object")
3274 #arg.release_target_temp(env)
3276 def nogil_check(self, env):
3277 for arg in self.args:
3278 if arg.type.is_pyobject:
3281 gil_message = "Deleting Python object"
3283 def generate_execution_code(self, code):
3284 for arg in self.args:
3285 if arg.type.is_pyobject:
3286 arg.generate_deletion_code(code)
3287 # else error reported earlier
3289 def annotate(self, code):
3290 for arg in self.args:
3294 class PassStatNode(StatNode):
3299 def analyse_expressions(self, env):
3302 def generate_execution_code(self, code):
3306 class BreakStatNode(StatNode):
3310 def analyse_expressions(self, env):
3313 def generate_execution_code(self, code):
3314 if not code.break_label:
3315 error(self.pos, "break statement not inside loop")
3317 code.put_goto(code.break_label)
3320 class ContinueStatNode(StatNode):
3324 def analyse_expressions(self, env):
3327 def generate_execution_code(self, code):
3328 if code.funcstate.in_try_finally:
3329 error(self.pos, "continue statement inside try of try...finally")
3330 elif not code.continue_label:
3331 error(self.pos, "continue statement not inside loop")
3333 code.put_goto(code.continue_label)
3336 class ReturnStatNode(StatNode):
3339 # value ExprNode or None
3340 # return_type PyrexType
3342 child_attrs = ["value"]
3344 def analyse_expressions(self, env):
3345 return_type = env.return_type
3346 self.return_type = return_type
3348 error(self.pos, "Return not inside a function body")
3351 self.value.analyse_types(env)
3352 if return_type.is_void or return_type.is_returncode:
3353 error(self.value.pos,
3354 "Return with value in void function")
3356 self.value = self.value.coerce_to(env.return_type, env)
3358 if (not return_type.is_void
3359 and not return_type.is_pyobject
3360 and not return_type.is_returncode):
3361 error(self.pos, "Return value required")
3363 def nogil_check(self, env):
3364 if self.return_type.is_pyobject:
3367 gil_message = "Returning Python object"
3369 def generate_execution_code(self, code):
3370 code.mark_pos(self.pos)
3371 if not self.return_type:
3372 # error reported earlier
3374 if self.return_type.is_pyobject:
3375 code.put_xdecref(Naming.retval_cname,
3378 self.value.generate_evaluation_code(code)
3379 self.value.make_owned_reference(code)
3382 Naming.retval_cname,
3383 self.value.result_as(self.return_type)))
3384 self.value.generate_post_assignment_code(code)
3385 self.value.free_temps(code)
3387 if self.return_type.is_pyobject:
3388 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3389 elif self.return_type.is_returncode:
3392 Naming.retval_cname,
3393 self.return_type.default_value))
3394 for cname, type in code.funcstate.temps_holding_reference():
3395 code.put_decref_clear(cname, type)
3396 code.put_goto(code.return_label)
3398 def annotate(self, code):
3400 self.value.annotate(code)
3403 class RaiseStatNode(StatNode):
3406 # exc_type ExprNode or None
3407 # exc_value ExprNode or None
3408 # exc_tb ExprNode or None
3410 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3412 def analyse_expressions(self, env):
3414 self.exc_type.analyse_types(env)
3415 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3417 self.exc_value.analyse_types(env)
3418 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3420 self.exc_tb.analyse_types(env)
3421 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3422 env.use_utility_code(raise_utility_code)
3423 env.use_utility_code(restore_exception_utility_code)
3425 nogil_check = Node.gil_error
3426 gil_message = "Raising exception"
3428 def generate_execution_code(self, code):
3430 self.exc_type.generate_evaluation_code(code)
3431 type_code = self.exc_type.py_result()
3435 self.exc_value.generate_evaluation_code(code)
3436 value_code = self.exc_value.py_result()
3440 self.exc_tb.generate_evaluation_code(code)
3441 tb_code = self.exc_tb.py_result()
3444 if self.exc_type or self.exc_value or self.exc_tb:
3446 "__Pyx_Raise(%s, %s, %s);" % (
3453 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3455 obj.generate_disposal_code(code)
3456 obj.free_temps(code)
3458 code.error_goto(self.pos))
3460 def annotate(self, code):
3462 self.exc_type.annotate(code)
3464 self.exc_value.annotate(code)
3466 self.exc_tb.annotate(code)
3469 class ReraiseStatNode(StatNode):
3473 def analyse_expressions(self, env):
3474 env.use_utility_code(raise_utility_code)
3475 env.use_utility_code(restore_exception_utility_code)
3477 nogil_check = Node.gil_error
3478 gil_message = "Raising exception"
3480 def generate_execution_code(self, code):
3481 vars = code.funcstate.exc_vars
3483 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3484 code.putln(code.error_goto(self.pos))
3486 error(self.pos, "Reraise not inside except clause")
3489 class AssertStatNode(StatNode):
3493 # value ExprNode or None
3495 child_attrs = ["cond", "value"]
3497 def analyse_expressions(self, env):
3498 self.cond = self.cond.analyse_boolean_expression(env)
3500 self.value.analyse_types(env)
3501 self.value = self.value.coerce_to_pyobject(env)
3503 nogil_check = Node.gil_error
3504 gil_message = "Raising exception"
3506 def generate_execution_code(self, code):
3507 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3508 self.cond.generate_evaluation_code(code)
3510 "if (unlikely(!%s)) {" %
3513 self.value.generate_evaluation_code(code)
3515 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3516 self.value.py_result())
3517 self.value.generate_disposal_code(code)
3518 self.value.free_temps(code)
3521 "PyErr_SetNone(PyExc_AssertionError);")
3523 code.error_goto(self.pos))
3526 self.cond.generate_disposal_code(code)
3527 self.cond.free_temps(code)
3528 code.putln("#endif")
3530 def annotate(self, code):
3531 self.cond.annotate(code)
3533 self.value.annotate(code)
3536 class IfStatNode(StatNode):
3539 # if_clauses [IfClauseNode]
3540 # else_clause StatNode or None
3542 child_attrs = ["if_clauses", "else_clause"]
3544 def analyse_control_flow(self, env):
3545 env.start_branching(self.pos)
3546 for if_clause in self.if_clauses:
3547 if_clause.analyse_control_flow(env)
3548 env.next_branch(if_clause.end_pos())
3549 if self.else_clause:
3550 self.else_clause.analyse_control_flow(env)
3551 env.finish_branching(self.end_pos())
3553 def analyse_declarations(self, env):
3554 for if_clause in self.if_clauses:
3555 if_clause.analyse_declarations(env)
3556 if self.else_clause:
3557 self.else_clause.analyse_declarations(env)
3559 def analyse_expressions(self, env):
3560 for if_clause in self.if_clauses:
3561 if_clause.analyse_expressions(env)
3562 if self.else_clause:
3563 self.else_clause.analyse_expressions(env)
3565 def generate_execution_code(self, code):
3566 code.mark_pos(self.pos)
3567 end_label = code.new_label()
3568 for if_clause in self.if_clauses:
3569 if_clause.generate_execution_code(code, end_label)
3570 if self.else_clause:
3571 code.putln("/*else*/ {")
3572 self.else_clause.generate_execution_code(code)
3574 code.put_label(end_label)
3576 def annotate(self, code):
3577 for if_clause in self.if_clauses:
3578 if_clause.annotate(code)
3579 if self.else_clause:
3580 self.else_clause.annotate(code)
3583 class IfClauseNode(Node):
3584 # if or elif clause in an if statement
3586 # condition ExprNode
3589 child_attrs = ["condition", "body"]
3591 def analyse_control_flow(self, env):
3592 self.body.analyse_control_flow(env)
3594 def analyse_declarations(self, env):
3595 self.condition.analyse_declarations(env)
3596 self.body.analyse_declarations(env)
3598 def analyse_expressions(self, env):
3600 self.condition.analyse_temp_boolean_expression(env)
3601 self.body.analyse_expressions(env)
3603 def generate_execution_code(self, code, end_label):
3604 self.condition.generate_evaluation_code(code)
3607 self.condition.result())
3608 self.condition.generate_disposal_code(code)
3609 self.condition.free_temps(code)
3610 self.body.generate_execution_code(code)
3614 code.put_goto(end_label)
3617 def annotate(self, code):
3618 self.condition.annotate(code)
3619 self.body.annotate(code)
3622 class SwitchCaseNode(StatNode):
3623 # Generated in the optimization of an if-elif-else node
3625 # conditions [ExprNode]
3628 child_attrs = ['conditions', 'body']
3630 def generate_execution_code(self, code):
3631 for cond in self.conditions:
3632 code.mark_pos(cond.pos)
3633 cond.generate_evaluation_code(code)
3634 code.putln("case %s:" % cond.result())
3635 self.body.generate_execution_code(code)
3636 code.putln("break;")
3638 def annotate(self, code):
3639 for cond in self.conditions:
3641 self.body.annotate(code)
3643 class SwitchStatNode(StatNode):
3644 # Generated in the optimization of an if-elif-else node
3647 # cases [SwitchCaseNode]
3648 # else_clause StatNode or None
3650 child_attrs = ['test', 'cases', 'else_clause']
3652 def generate_execution_code(self, code):
3653 code.putln("switch (%s) {" % self.test.result())
3654 for case in self.cases:
3655 case.generate_execution_code(code)
3656 if self.else_clause is not None:
3657 code.putln("default:")
3658 self.else_clause.generate_execution_code(code)
3659 code.putln("break;")
3662 def annotate(self, code):
3663 self.test.annotate(code)
3664 for case in self.cases:
3666 if self.else_clause is not None:
3667 self.else_clause.annotate(code)
3669 class LoopNode(object):
3671 def analyse_control_flow(self, env):
3672 env.start_branching(self.pos)
3673 self.body.analyse_control_flow(env)
3674 env.next_branch(self.body.end_pos())
3675 if self.else_clause:
3676 self.else_clause.analyse_control_flow(env)
3677 env.finish_branching(self.end_pos())
3680 class WhileStatNode(LoopNode, StatNode):
3683 # condition ExprNode
3685 # else_clause StatNode
3687 child_attrs = ["condition", "body", "else_clause"]
3689 def analyse_declarations(self, env):
3690 self.body.analyse_declarations(env)
3691 if self.else_clause:
3692 self.else_clause.analyse_declarations(env)
3694 def analyse_expressions(self, env):
3696 self.condition.analyse_temp_boolean_expression(env)
3697 self.body.analyse_expressions(env)
3698 if self.else_clause:
3699 self.else_clause.analyse_expressions(env)
3701 def generate_execution_code(self, code):
3702 old_loop_labels = code.new_loop_labels()
3705 self.condition.generate_evaluation_code(code)
3706 self.condition.generate_disposal_code(code)
3709 self.condition.result())
3710 self.condition.free_temps(code)
3711 self.body.generate_execution_code(code)
3712 code.put_label(code.continue_label)
3714 break_label = code.break_label
3715 code.set_loop_labels(old_loop_labels)
3716 if self.else_clause:
3717 code.putln("/*else*/ {")
3718 self.else_clause.generate_execution_code(code)
3720 code.put_label(break_label)
3722 def annotate(self, code):
3723 self.condition.annotate(code)
3724 self.body.annotate(code)
3725 if self.else_clause:
3726 self.else_clause.annotate(code)
3729 def ForStatNode(pos, **kw):
3730 if 'iterator' in kw:
3731 return ForInStatNode(pos, **kw)
3733 return ForFromStatNode(pos, **kw)
3735 class ForInStatNode(LoopNode, StatNode):
3739 # iterator IteratorNode
3741 # else_clause StatNode
3742 # item NextNode used internally
3744 child_attrs = ["target", "iterator", "body", "else_clause"]
3747 def analyse_declarations(self, env):
3748 self.target.analyse_target_declaration(env)
3749 self.body.analyse_declarations(env)
3750 if self.else_clause:
3751 self.else_clause.analyse_declarations(env)
3753 def analyse_expressions(self, env):
3755 self.target.analyse_target_types(env)
3756 self.iterator.analyse_expressions(env)
3757 self.item = ExprNodes.NextNode(self.iterator, env)
3758 self.item = self.item.coerce_to(self.target.type, env)
3759 self.body.analyse_expressions(env)
3760 if self.else_clause:
3761 self.else_clause.analyse_expressions(env)
3763 def generate_execution_code(self, code):
3764 old_loop_labels = code.new_loop_labels()
3765 self.iterator.allocate_counter_temp(code)
3766 self.iterator.generate_evaluation_code(code)
3769 self.item.generate_evaluation_code(code)
3770 self.target.generate_assignment_code(self.item, code)
3771 self.body.generate_execution_code(code)
3772 code.put_label(code.continue_label)
3775 break_label = code.break_label
3776 code.set_loop_labels(old_loop_labels)
3777 if self.else_clause:
3778 code.putln("/*else*/ {")
3779 self.else_clause.generate_execution_code(code)
3781 code.put_label(break_label)
3782 self.iterator.release_counter_temp(code)
3783 self.iterator.generate_disposal_code(code)
3784 self.iterator.free_temps(code)
3786 def annotate(self, code):
3787 self.target.annotate(code)
3788 self.iterator.annotate(code)
3789 self.body.annotate(code)
3790 if self.else_clause:
3791 self.else_clause.annotate(code)
3792 self.item.annotate(code)
3795 class ForFromStatNode(LoopNode, StatNode):
3796 # for name from expr rel name rel expr
3803 # step ExprNode or None
3805 # else_clause StatNode or None
3811 # loopvar_node ExprNode (usually a NameNode or temp node)
3812 # py_loopvar_node PyTempNode or None
3813 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3815 is_py_target = False
3817 py_loopvar_node = None
3820 gil_message = "For-loop using object bounds or target"
3822 def nogil_check(self, env):
3823 for x in (self.target, self.bound1, self.bound2):
3824 if x.type.is_pyobject:
3827 def analyse_declarations(self, env):
3828 self.target.analyse_target_declaration(env)
3829 self.body.analyse_declarations(env)
3830 if self.else_clause:
3831 self.else_clause.analyse_declarations(env)
3833 def analyse_expressions(self, env):
3835 self.target.analyse_target_types(env)
3836 self.bound1.analyse_types(env)
3837 self.bound2.analyse_types(env)
3838 if self.step is not None:
3839 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3840 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3841 self.step.analyse_types(env)
3843 target_type = self.target.type
3844 if self.target.type.is_numeric:
3845 loop_type = self.target.type
3847 loop_type = PyrexTypes.c_int_type
3848 if not self.bound1.type.is_pyobject:
3849 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3850 if not self.bound2.type.is_pyobject:
3851 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3852 if self.step is not None and not self.step.type.is_pyobject:
3853 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3854 self.bound1 = self.bound1.coerce_to(loop_type, env)
3855 self.bound2 = self.bound2.coerce_to(loop_type, env)
3856 if not self.bound2.is_literal:
3857 self.bound2 = self.bound2.coerce_to_temp(env)
3858 if self.step is not None:
3859 self.step = self.step.coerce_to(loop_type, env)
3860 if not self.step.is_literal:
3861 self.step = self.step.coerce_to_temp(env)
3863 target_type = self.target.type
3864 if not (target_type.is_pyobject or target_type.is_numeric):
3865 error(self.target.pos,
3866 "for-from loop variable must be c numeric type or Python object")
3867 if target_type.is_numeric:
3868 self.is_py_target = False
3869 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3870 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3871 self.loopvar_node = self.target
3872 self.py_loopvar_node = None
3874 self.is_py_target = True
3875 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3876 self.loopvar_node = c_loopvar_node
3877 self.py_loopvar_node = \
3878 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3879 self.body.analyse_expressions(env)
3880 if self.else_clause:
3881 self.else_clause.analyse_expressions(env)
3883 def generate_execution_code(self, code):
3884 old_loop_labels = code.new_loop_labels()
3885 from_range = self.from_range
3886 self.bound1.generate_evaluation_code(code)
3887 self.bound2.generate_evaluation_code(code)
3888 offset, incop = self.relation_table[self.relation1]
3889 if self.step is not None:
3890 self.step.generate_evaluation_code(code)
3891 step = self.step.result()
3892 incop = "%s=%s" % (incop[0], step)
3894 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3895 self.loopvar_node.allocate(code)
3896 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3897 self.py_loopvar_node.allocate(code)
3899 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3901 loopvar_name = self.loopvar_node.result()
3903 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3905 self.bound1.result(), offset,
3906 loopvar_name, self.relation2, self.bound2.result(),
3907 loopvar_name, incop))
3908 if self.py_loopvar_node:
3909 self.py_loopvar_node.generate_evaluation_code(code)
3910 self.target.generate_assignment_code(self.py_loopvar_node, code)
3912 code.putln("%s = %s;" % (
3913 self.target.result(), loopvar_name))
3914 self.body.generate_execution_code(code)
3915 code.put_label(code.continue_label)
3916 if self.py_loopvar_node:
3917 # This mess is to make for..from loops with python targets behave
3918 # exactly like those with C targets with regards to re-assignment
3919 # of the loop variable.
3921 if self.target.entry.is_pyglobal:
3922 # We know target is a NameNode, this is the only ugly case.
3923 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3924 target_node.allocate(code)
3925 interned_cname = code.intern_identifier(self.target.entry.name)
3926 code.putln("/*here*/")
3927 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3928 target_node.result(),
3929 Naming.module_cname,
3931 code.error_goto_if_null(target_node.result(), self.target.pos)))
3932 code.put_gotref(target_node.result())
3934 target_node = self.target
3935 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3936 from_py_node.temp_code = loopvar_name
3937 from_py_node.generate_result_code(code)
3938 if self.target.entry.is_pyglobal:
3939 code.put_decref(target_node.result(), target_node.type)
3940 target_node.release(code)
3942 if self.py_loopvar_node:
3943 # This is potentially wasteful, but we don't want the semantics to
3944 # depend on whether or not the loop is a python type.
3945 self.py_loopvar_node.generate_evaluation_code(code)
3946 self.target.generate_assignment_code(self.py_loopvar_node, code)
3947 break_label = code.break_label
3948 code.set_loop_labels(old_loop_labels)
3949 if self.else_clause:
3950 code.putln("/*else*/ {")
3951 self.else_clause.generate_execution_code(code)
3953 code.put_label(break_label)
3954 self.bound1.generate_disposal_code(code)
3955 self.bound1.free_temps(code)
3956 self.bound2.generate_disposal_code(code)
3957 self.bound2.free_temps(code)
3958 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3959 self.loopvar_node.release(code)
3960 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3961 self.py_loopvar_node.release(code)
3962 if self.step is not None:
3963 self.step.generate_disposal_code(code)
3964 self.step.free_temps(code)
3967 # {relop : (initial offset, increment op)}
3974 def annotate(self, code):
3975 self.target.annotate(code)
3976 self.bound1.annotate(code)
3977 self.bound2.annotate(code)
3979 self.bound2.annotate(code)
3980 self.body.annotate(code)
3981 if self.else_clause:
3982 self.else_clause.annotate(code)
3985 class WithStatNode(StatNode):
3987 Represents a Python with statement.
3989 This is only used at parse tree level; and is not present in
3990 analysis or generation phases.
3992 # manager The with statement manager object
3993 # target Node (lhs expression)
3995 child_attrs = ["manager", "target", "body"]
3997 class TryExceptStatNode(StatNode):
3998 # try .. except statement
4001 # except_clauses [ExceptClauseNode]
4002 # else_clause StatNode or None
4004 child_attrs = ["body", "except_clauses", "else_clause"]
4006 def analyse_control_flow(self, env):
4007 env.start_branching(self.pos)
4008 self.body.analyse_control_flow(env)
4009 successful_try = env.control_flow # grab this for later
4010 env.next_branch(self.body.end_pos())
4011 env.finish_branching(self.body.end_pos())
4013 env.start_branching(self.except_clauses[0].pos)
4014 for except_clause in self.except_clauses:
4015 except_clause.analyse_control_flow(env)
4016 env.next_branch(except_clause.end_pos())
4018 # the else cause it executed only when the try clause finishes
4019 env.control_flow.incoming = successful_try
4020 if self.else_clause:
4021 self.else_clause.analyse_control_flow(env)
4022 env.finish_branching(self.end_pos())
4024 def analyse_declarations(self, env):
4025 self.body.analyse_declarations(env)
4026 for except_clause in self.except_clauses:
4027 except_clause.analyse_declarations(env)
4028 if self.else_clause:
4029 self.else_clause.analyse_declarations(env)
4030 env.use_utility_code(reset_exception_utility_code)
4032 def analyse_expressions(self, env):
4033 self.body.analyse_expressions(env)
4034 default_clause_seen = 0
4035 for except_clause in self.except_clauses:
4036 except_clause.analyse_expressions(env)
4037 if default_clause_seen:
4038 error(except_clause.pos, "default 'except:' must be last")
4039 if not except_clause.pattern:
4040 default_clause_seen = 1
4041 self.has_default_clause = default_clause_seen
4042 if self.else_clause:
4043 self.else_clause.analyse_expressions(env)
4045 nogil_check = Node.gil_error
4046 gil_message = "Try-except statement"
4048 def generate_execution_code(self, code):
4049 old_return_label = code.return_label
4050 old_break_label = code.break_label
4051 old_continue_label = code.continue_label
4052 old_error_label = code.new_error_label()
4053 our_error_label = code.error_label
4054 except_end_label = code.new_label('exception_handled')
4055 except_error_label = code.new_label('except_error')
4056 except_return_label = code.new_label('except_return')
4057 try_return_label = code.new_label('try_return')
4058 try_break_label = code.new_label('try_break')
4059 try_continue_label = code.new_label('try_continue')
4060 try_end_label = code.new_label('try_end')
4063 code.putln("PyObject %s;" %
4064 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4065 code.putln("__Pyx_ExceptionSave(%s);" %
4066 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4067 for var in Naming.exc_save_vars:
4068 code.put_xgotref(var)
4071 code.return_label = try_return_label
4072 code.break_label = try_break_label
4073 code.continue_label = try_continue_label
4074 self.body.generate_execution_code(code)
4077 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4078 code.error_label = except_error_label
4079 code.return_label = except_return_label
4080 if self.else_clause:
4083 self.else_clause.generate_execution_code(code)
4086 for var in Naming.exc_save_vars:
4087 code.put_xdecref_clear(var, py_object_type)
4088 code.put_goto(try_end_label)
4089 if code.label_used(try_return_label):
4090 code.put_label(try_return_label)
4091 for var in Naming.exc_save_vars:
4092 code.put_xdecref_clear(var, py_object_type)
4093 code.put_goto(old_return_label)
4094 code.put_label(our_error_label)
4095 for temp_name, type in temps_to_clean_up:
4096 code.put_xdecref_clear(temp_name, type)
4097 for except_clause in self.except_clauses:
4098 except_clause.generate_handling_code(code, except_end_label)
4100 error_label_used = code.label_used(except_error_label)
4101 if error_label_used or not self.has_default_clause:
4102 if error_label_used:
4103 code.put_label(except_error_label)
4104 for var in Naming.exc_save_vars:
4105 code.put_xdecref(var, py_object_type)
4106 code.put_goto(old_error_label)
4108 if code.label_used(try_break_label):
4109 code.put_label(try_break_label)
4110 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4111 code.putln("__Pyx_ExceptionReset(%s);" %
4112 ', '.join(Naming.exc_save_vars))
4113 code.put_goto(old_break_label)
4115 if code.label_used(try_continue_label):
4116 code.put_label(try_continue_label)
4117 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4118 code.putln("__Pyx_ExceptionReset(%s);" %
4119 ', '.join(Naming.exc_save_vars))
4120 code.put_goto(old_continue_label)
4122 if code.label_used(except_return_label):
4123 code.put_label(except_return_label)
4124 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4125 code.putln("__Pyx_ExceptionReset(%s);" %
4126 ', '.join(Naming.exc_save_vars))
4127 code.put_goto(old_return_label)
4129 if code.label_used(except_end_label):
4130 code.put_label(except_end_label)
4131 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4132 code.putln("__Pyx_ExceptionReset(%s);" %
4133 ', '.join(Naming.exc_save_vars))
4134 code.put_label(try_end_label)
4137 code.return_label = old_return_label
4138 code.break_label = old_break_label
4139 code.continue_label = old_continue_label
4140 code.error_label = old_error_label
4142 def annotate(self, code):
4143 self.body.annotate(code)
4144 for except_node in self.except_clauses:
4145 except_node.annotate(code)
4146 if self.else_clause:
4147 self.else_clause.annotate(code)
4150 class ExceptClauseNode(Node):
4151 # Part of try ... except statement.
4154 # target ExprNode or None
4156 # excinfo_target NameNode or None optional target for exception info
4157 # match_flag string result of exception match
4158 # exc_value ExcValueNode used internally
4159 # function_name string qualified name of enclosing function
4160 # exc_vars (string * 3) local exception variables
4162 # excinfo_target is never set by the parser, but can be set by a transform
4163 # in order to extract more extensive information about the exception as a
4164 # sys.exc_info()-style tuple into a target variable
4166 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4169 excinfo_target = None
4171 def analyse_declarations(self, env):
4173 self.target.analyse_target_declaration(env)
4174 if self.excinfo_target is not None:
4175 self.excinfo_target.analyse_target_declaration(env)
4176 self.body.analyse_declarations(env)
4178 def analyse_expressions(self, env):
4180 genv = env.global_scope()
4181 self.function_name = env.qualified_name
4183 self.pattern.analyse_expressions(env)
4184 self.pattern = self.pattern.coerce_to_pyobject(env)
4187 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4188 self.target.analyse_target_expression(env, self.exc_value)
4189 if self.excinfo_target is not None:
4191 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4192 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4193 self.excinfo_tuple.analyse_expressions(env)
4194 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4196 self.body.analyse_expressions(env)
4198 def generate_handling_code(self, code, end_label):
4199 code.mark_pos(self.pos)
4201 self.pattern.generate_evaluation_code(code)
4203 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4205 "%s = PyErr_ExceptionMatches(%s);" % (
4207 self.pattern.py_result()))
4208 self.pattern.generate_disposal_code(code)
4209 self.pattern.free_temps(code)
4213 code.funcstate.release_temp(match_flag)
4215 code.putln("/*except:*/ {")
4217 if not getattr(self.body, 'stats', True):
4218 # most simple case: no exception variable, empty body (pass)
4219 # => reset the exception state, done
4220 code.putln("PyErr_Restore(0,0,0);")
4221 code.put_goto(end_label)
4225 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4228 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4229 # We always have to fetch the exception value even if
4230 # there is no target, because this also normalises the
4231 # exception and stores it in the thread state.
4232 code.globalstate.use_utility_code(get_exception_utility_code)
4233 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4234 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4235 code.error_goto(self.pos)))
4239 self.exc_value.set_var(exc_vars[1])
4240 self.exc_value.generate_evaluation_code(code)
4241 self.target.generate_assignment_code(self.exc_value, code)
4242 if self.excinfo_target is not None:
4243 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4244 node.set_var(tempvar)
4245 self.excinfo_tuple.generate_evaluation_code(code)
4246 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4248 old_break_label, old_continue_label = code.break_label, code.continue_label
4249 code.break_label = code.new_label('except_break')
4250 code.continue_label = code.new_label('except_continue')
4252 old_exc_vars = code.funcstate.exc_vars
4253 code.funcstate.exc_vars = exc_vars
4254 self.body.generate_execution_code(code)
4255 code.funcstate.exc_vars = old_exc_vars
4256 for var in exc_vars:
4257 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4258 code.put_goto(end_label)
4260 if code.label_used(code.break_label):
4261 code.put_label(code.break_label)
4262 for var in exc_vars:
4263 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4264 code.put_goto(old_break_label)
4265 code.break_label = old_break_label
4267 if code.label_used(code.continue_label):
4268 code.put_label(code.continue_label)
4269 for var in exc_vars:
4270 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4271 code.put_goto(old_continue_label)
4272 code.continue_label = old_continue_label
4274 for temp in exc_vars:
4275 code.funcstate.release_temp(temp)
4280 def annotate(self, code):
4282 self.pattern.annotate(code)
4284 self.target.annotate(code)
4285 self.body.annotate(code)
4288 class TryFinallyStatNode(StatNode):
4289 # try ... finally statement
4292 # finally_clause StatNode
4294 # The plan is that we funnel all continue, break
4295 # return and error gotos into the beginning of the
4296 # finally block, setting a variable to remember which
4297 # one we're doing. At the end of the finally block, we
4298 # switch on the variable to figure out where to go.
4299 # In addition, if we're doing an error, we save the
4300 # exception on entry to the finally block and restore
4303 child_attrs = ["body", "finally_clause"]
4305 preserve_exception = 1
4307 disallow_continue_in_try_finally = 0
4308 # There doesn't seem to be any point in disallowing
4309 # continue in the try block, since we have no problem
4312 def create_analysed(pos, env, body, finally_clause):
4313 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4315 create_analysed = staticmethod(create_analysed)
4317 def analyse_control_flow(self, env):
4318 env.start_branching(self.pos)
4319 self.body.analyse_control_flow(env)
4320 env.next_branch(self.body.end_pos())
4321 env.finish_branching(self.body.end_pos())
4322 self.finally_clause.analyse_control_flow(env)
4324 def analyse_declarations(self, env):
4325 self.body.analyse_declarations(env)
4326 self.finally_clause.analyse_declarations(env)
4328 def analyse_expressions(self, env):
4329 self.body.analyse_expressions(env)
4330 self.finally_clause.analyse_expressions(env)
4332 nogil_check = Node.gil_error
4333 gil_message = "Try-finally statement"
4335 def generate_execution_code(self, code):
4336 old_error_label = code.error_label
4337 old_labels = code.all_new_labels()
4338 new_labels = code.get_all_labels()
4339 new_error_label = code.error_label
4340 catch_label = code.new_label()
4343 if self.disallow_continue_in_try_finally:
4344 was_in_try_finally = code.funcstate.in_try_finally
4345 code.funcstate.in_try_finally = 1
4346 self.body.generate_execution_code(code)
4347 if self.disallow_continue_in_try_finally:
4348 code.funcstate.in_try_finally = was_in_try_finally
4351 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4355 error_label_used = 0
4356 for i, new_label in enumerate(new_labels):
4357 if new_label in code.labels_used:
4358 cases_used.append(i)
4359 if new_label == new_error_label:
4360 error_label_used = 1
4361 error_label_case = i
4365 if error_label_used and self.preserve_exception:
4367 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4369 "int %s;" % Naming.exc_lineno_name)
4370 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4371 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4372 code.putln(exc_var_init_zero)
4374 exc_var_init_zero = None
4375 code.use_label(catch_label)
4377 "__pyx_why = 0; goto %s;" % catch_label)
4378 for i in cases_used:
4379 new_label = new_labels[i]
4380 #if new_label and new_label != "<try>":
4381 if new_label == new_error_label and self.preserve_exception:
4382 self.put_error_catcher(code,
4383 new_error_label, i+1, catch_label, temps_to_clean_up)
4385 code.put('%s: ' % new_label)
4386 if exc_var_init_zero:
4387 code.putln(exc_var_init_zero)
4388 code.putln("__pyx_why = %s; goto %s;" % (
4391 code.put_label(catch_label)
4392 code.set_all_labels(old_labels)
4393 if error_label_used:
4394 code.new_error_label()
4395 finally_error_label = code.error_label
4396 self.finally_clause.generate_execution_code(code)
4397 if error_label_used:
4398 if finally_error_label in code.labels_used and self.preserve_exception:
4399 over_label = code.new_label()
4400 code.put_goto(over_label);
4401 code.put_label(finally_error_label)
4402 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4403 for var in Naming.exc_vars:
4404 code.putln("Py_XDECREF(%s);" % var)
4406 code.put_goto(old_error_label)
4407 code.put_label(over_label)
4408 code.error_label = old_error_label
4411 "switch (__pyx_why) {")
4412 for i in cases_used:
4413 old_label = old_labels[i]
4414 if old_label == old_error_label and self.preserve_exception:
4415 self.put_error_uncatcher(code, i+1, old_error_label)
4417 code.use_label(old_label)
4419 "case %s: goto %s;" % (
4427 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4428 code.globalstate.use_utility_code(restore_exception_utility_code)
4435 for temp_name, type in temps_to_clean_up:
4436 code.put_xdecref_clear(temp_name, type)
4438 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4442 Naming.exc_lineno_name, Naming.lineno_cname))
4446 code.put_goto(catch_label)
4450 def put_error_uncatcher(self, code, i, error_label):
4451 code.globalstate.use_utility_code(restore_exception_utility_code)
4456 "__Pyx_ErrRestore(%s, %s, %s);" %
4460 Naming.lineno_cname, Naming.exc_lineno_name))
4461 for var in Naming.exc_vars:
4465 code.put_goto(error_label)
4469 def annotate(self, code):
4470 self.body.annotate(code)
4471 self.finally_clause.annotate(code)
4474 class GILStatNode(TryFinallyStatNode):
4475 # 'with gil' or 'with nogil' statement
4477 # state string 'gil' or 'nogil'
4481 preserve_exception = 0
4483 def __init__(self, pos, state, body):
4485 TryFinallyStatNode.__init__(self, pos,
4487 finally_clause = GILExitNode(pos, state = state))
4489 def analyse_expressions(self, env):
4490 env.use_utility_code(force_init_threads_utility_code)
4491 was_nogil = env.nogil
4493 TryFinallyStatNode.analyse_expressions(self, env)
4494 env.nogil = was_nogil
4498 def generate_execution_code(self, code):
4499 code.mark_pos(self.pos)
4500 if self.state == 'gil':
4501 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4503 code.putln("{ PyThreadState *_save;")
4504 code.putln("Py_UNBLOCK_THREADS")
4505 TryFinallyStatNode.generate_execution_code(self, code)
4509 class GILExitNode(StatNode):
4510 # Used as the 'finally' block in a GILStatNode
4512 # state string 'gil' or 'nogil'
4516 def analyse_expressions(self, env):
4519 def generate_execution_code(self, code):
4520 if self.state == 'gil':
4521 code.putln("PyGILState_Release();")
4523 code.putln("Py_BLOCK_THREADS")
4526 class CImportStatNode(StatNode):
4529 # module_name string Qualified name of module being imported
4530 # as_name string or None Name specified in "as" clause, if any
4534 def analyse_declarations(self, env):
4535 if not env.is_module_scope:
4536 error(self.pos, "cimport only allowed at module level")
4538 module_scope = env.find_module(self.module_name, self.pos)
4539 if "." in self.module_name:
4540 names = [EncodedString(name) for name in self.module_name.split(".")]
4542 top_module_scope = env.context.find_submodule(top_name)
4543 module_scope = top_module_scope
4544 for name in names[1:]:
4545 submodule_scope = module_scope.find_submodule(name)
4546 module_scope.declare_module(name, submodule_scope, self.pos)
4547 module_scope = submodule_scope
4549 env.declare_module(self.as_name, module_scope, self.pos)
4551 env.declare_module(top_name, top_module_scope, self.pos)
4553 name = self.as_name or self.module_name
4554 env.declare_module(name, module_scope, self.pos)
4556 def analyse_expressions(self, env):
4559 def generate_execution_code(self, code):
4563 class FromCImportStatNode(StatNode):
4564 # from ... cimport statement
4566 # module_name string Qualified name of module
4567 # imported_names [(pos, name, as_name, kind)] Names to be imported
4571 def analyse_declarations(self, env):
4572 if not env.is_module_scope:
4573 error(self.pos, "cimport only allowed at module level")
4575 module_scope = env.find_module(self.module_name, self.pos)
4576 env.add_imported_module(module_scope)
4577 for pos, name, as_name, kind in self.imported_names:
4579 for local_name, entry in module_scope.entries.items():
4580 env.add_imported_entry(local_name, entry, pos)
4582 entry = module_scope.lookup(name)
4584 if kind and not self.declaration_matches(entry, kind):
4585 entry.redeclared(pos)
4587 if kind == 'struct' or kind == 'union':
4588 entry = module_scope.declare_struct_or_union(name,
4589 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4590 elif kind == 'class':
4591 entry = module_scope.declare_c_class(name, pos = pos,
4592 module_name = self.module_name)
4594 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4595 if submodule_scope.parent_module is module_scope:
4596 env.declare_module(as_name or name, submodule_scope, self.pos)
4598 error(pos, "Name '%s' not declared in module '%s'"
4599 % (name, self.module_name))
4602 local_name = as_name or name
4603 env.add_imported_entry(local_name, entry, pos)
4605 def declaration_matches(self, entry, kind):
4606 if not entry.is_type:
4610 if not type.is_extension_type:
4613 if not type.is_struct_or_union:
4615 if kind != type.kind:
4619 def analyse_expressions(self, env):
4622 def generate_execution_code(self, code):
4626 class FromImportStatNode(StatNode):
4627 # from ... import statement
4630 # items [(string, NameNode)]
4631 # interned_items [(string, NameNode, ExprNode)]
4632 # item PyTempNode used internally
4633 # import_star boolean used internally
4635 child_attrs = ["module"]
4638 def analyse_declarations(self, env):
4639 for name, target in self.items:
4641 if not env.is_module_scope:
4642 error(self.pos, "import * only allowed at module level")
4644 env.has_import_star = 1
4645 self.import_star = 1
4647 target.analyse_target_declaration(env)
4649 def analyse_expressions(self, env):
4651 self.module.analyse_expressions(env)
4652 self.item = ExprNodes.PyTempNode(self.pos, env)
4653 self.interned_items = []
4654 for name, target in self.items:
4656 for _, entry in env.entries.items():
4657 if not entry.is_type and entry.type.is_extension_type:
4658 env.use_utility_code(ExprNodes.type_test_utility_code)
4661 entry = env.lookup(target.name)
4662 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4663 continue # already cimported
4664 target.analyse_target_expression(env, None)
4665 if target.type is py_object_type:
4668 coerced_item = self.item.coerce_to(target.type, env)
4669 self.interned_items.append(
4670 (name, target, coerced_item))
4672 def generate_execution_code(self, code):
4673 self.module.generate_evaluation_code(code)
4674 if self.import_star:
4676 'if (%s(%s) < 0) %s;' % (
4678 self.module.py_result(),
4679 code.error_goto(self.pos)))
4680 self.item.allocate(code)
4681 for name, target, coerced_item in self.interned_items:
4682 cname = code.intern_identifier(name)
4684 '%s = PyObject_GetAttr(%s, %s); %s' % (
4686 self.module.py_result(),
4688 code.error_goto_if_null(self.item.result(), self.pos)))
4689 code.put_gotref(self.item.py_result())
4690 if coerced_item is None:
4691 target.generate_assignment_code(self.item, code)
4693 coerced_item.allocate_temp_result(code)
4694 coerced_item.generate_result_code(code)
4695 target.generate_assignment_code(coerced_item, code)
4696 if self.item.result() != coerced_item.result():
4697 code.put_decref_clear(self.item.result(), self.item.type)
4698 self.item.release(code)
4699 self.module.generate_disposal_code(code)
4700 self.module.free_temps(code)
4704 #------------------------------------------------------------------------------------
4706 # Runtime support code
4708 #------------------------------------------------------------------------------------
4710 utility_function_predeclarations = \
4713 #define INLINE __inline__
4715 #define INLINE __inline
4720 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4724 static int %(skip_dispatch_cname)s = 0;
4726 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4728 if Options.gcc_branch_hints:
4729 branch_prediction_macros = \
4732 /* Test for GCC > 2.95 */
4733 #if __GNUC__ > 2 || \
4734 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4735 #define likely(x) __builtin_expect(!!(x), 1)
4736 #define unlikely(x) __builtin_expect(!!(x), 0)
4737 #else /* __GNUC__ > 2 ... */
4738 #define likely(x) (x)
4739 #define unlikely(x) (x)
4740 #endif /* __GNUC__ > 2 ... */
4741 #else /* __GNUC__ */
4742 #define likely(x) (x)
4743 #define unlikely(x) (x)
4744 #endif /* __GNUC__ */
4747 branch_prediction_macros = \
4749 #define likely(x) (x)
4750 #define unlikely(x) (x)
4753 #get_name_predeclaration = \
4754 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4756 #get_name_interned_predeclaration = \
4757 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4759 #------------------------------------------------------------------------------------
4761 printing_utility_code = UtilityCode(
4763 static int __Pyx_Print(PyObject *, int); /*proto*/
4764 #if PY_MAJOR_VERSION >= 3
4765 static PyObject* %s = 0;
4766 static PyObject* %s = 0;
4768 """ % (Naming.print_function, Naming.print_function_kwargs),
4770 #if PY_MAJOR_VERSION < 3
4771 static PyObject *__Pyx_GetStdout(void) {
4772 PyObject *f = PySys_GetObject((char *)"stdout");
4774 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4779 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4784 if (!(f = __Pyx_GetStdout()))
4786 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4787 if (PyFile_SoftSpace(f, 1)) {
4788 if (PyFile_WriteString(" ", f) < 0)
4791 v = PyTuple_GET_ITEM(arg_tuple, i);
4792 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4794 if (PyString_Check(v)) {
4795 char *s = PyString_AsString(v);
4796 Py_ssize_t len = PyString_Size(v);
4798 isspace(Py_CHARMASK(s[len-1])) &&
4800 PyFile_SoftSpace(f, 0);
4804 if (PyFile_WriteString("\n", f) < 0)
4806 PyFile_SoftSpace(f, 0);
4811 #else /* Python 3 has a print function */
4813 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4814 PyObject* kwargs = 0;
4815 PyObject* result = 0;
4816 PyObject* end_string;
4817 if (!%(PRINT_FUNCTION)s) {
4818 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4819 if (!%(PRINT_FUNCTION)s)
4823 if (!%(PRINT_KWARGS)s) {
4824 %(PRINT_KWARGS)s = PyDict_New();
4825 if (!%(PRINT_KWARGS)s)
4827 end_string = PyUnicode_FromStringAndSize(" ", 1);
4830 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4831 Py_DECREF(end_string);
4834 Py_DECREF(end_string);
4836 kwargs = %(PRINT_KWARGS)s;
4838 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4846 """ % {'BUILTINS' : Naming.builtins_cname,
4847 'PRINT_FUNCTION' : Naming.print_function,
4848 'PRINT_KWARGS' : Naming.print_function_kwargs}
4852 printing_one_utility_code = UtilityCode(
4854 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4857 #if PY_MAJOR_VERSION < 3
4859 static int __Pyx_PrintOne(PyObject *o) {
4861 if (!(f = __Pyx_GetStdout()))
4863 if (PyFile_SoftSpace(f, 0)) {
4864 if (PyFile_WriteString(" ", f) < 0)
4867 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4869 if (PyFile_WriteString("\n", f) < 0)
4872 /* the line below is just to avoid compiler
4873 * compiler warnings about unused functions */
4874 return __Pyx_Print(NULL, 0);
4877 #else /* Python 3 has a print function */
4879 static int __Pyx_PrintOne(PyObject *o) {
4881 PyObject* arg_tuple = PyTuple_New(1);
4882 if (unlikely(!arg_tuple))
4885 PyTuple_SET_ITEM(arg_tuple, 0, o);
4886 res = __Pyx_Print(arg_tuple, 1);
4887 Py_DECREF(arg_tuple);
4893 requires=[printing_utility_code])
4897 #------------------------------------------------------------------------------------
4899 # The following function is based on do_raise() from ceval.c.
4901 raise_utility_code = UtilityCode(
4903 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4906 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4910 /* First, check the traceback argument, replacing None with NULL. */
4911 if (tb == Py_None) {
4915 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4916 PyErr_SetString(PyExc_TypeError,
4917 "raise: arg 3 must be a traceback or None");
4920 /* Next, replace a missing value with None */
4921 if (value == NULL) {
4925 #if PY_VERSION_HEX < 0x02050000
4926 if (!PyClass_Check(type))
4928 if (!PyType_Check(type))
4931 /* Raising an instance. The value should be a dummy. */
4932 if (value != Py_None) {
4933 PyErr_SetString(PyExc_TypeError,
4934 "instance exception may not have a separate value");
4937 /* Normalize to raise <class>, <instance> */
4940 #if PY_VERSION_HEX < 0x02050000
4941 if (PyInstance_Check(type)) {
4942 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4947 PyErr_SetString(PyExc_TypeError,
4948 "raise: exception must be an old-style class or instance");
4952 type = (PyObject*) Py_TYPE(type);
4954 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4955 PyErr_SetString(PyExc_TypeError,
4956 "raise: exception class must be a subclass of BaseException");
4961 __Pyx_ErrRestore(type, value, tb);
4971 #------------------------------------------------------------------------------------
4973 reraise_utility_code = UtilityCode(
4975 static void __Pyx_ReRaise(void); /*proto*/
4978 static void __Pyx_ReRaise(void) {
4979 PyThreadState *tstate = PyThreadState_GET();
4980 PyObject* tmp_type = tstate->curexc_type;
4981 PyObject* tmp_value = tstate->curexc_value;
4982 PyObject* tmp_tb = tstate->curexc_traceback;
4983 tstate->curexc_type = tstate->exc_type;
4984 tstate->curexc_value = tstate->exc_value;
4985 tstate->curexc_traceback = tstate->exc_traceback;
4986 tstate->exc_type = 0;
4987 tstate->exc_value = 0;
4988 tstate->exc_traceback = 0;
4989 Py_XDECREF(tmp_type);
4990 Py_XDECREF(tmp_value);
4995 #------------------------------------------------------------------------------------
4997 arg_type_test_utility_code = UtilityCode(
4999 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5000 const char *name, int exact); /*proto*/
5003 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5004 const char *name, int exact)
5007 PyErr_Format(PyExc_SystemError, "Missing type object");
5010 if (none_allowed && obj == Py_None) return 1;
5012 if (Py_TYPE(obj) == type) return 1;
5015 if (PyObject_TypeCheck(obj, type)) return 1;
5017 PyErr_Format(PyExc_TypeError,
5018 "Argument '%s' has incorrect type (expected %s, got %s)",
5019 name, type->tp_name, Py_TYPE(obj)->tp_name);
5024 #------------------------------------------------------------------------------------
5026 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5027 # many or too few positional arguments were found. This handles
5028 # Py_ssize_t formatting correctly.
5030 raise_argtuple_invalid_utility_code = UtilityCode(
5032 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5033 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5036 static void __Pyx_RaiseArgtupleInvalid(
5037 const char* func_name,
5041 Py_ssize_t num_found)
5043 Py_ssize_t num_expected;
5044 const char *number, *more_or_less;
5046 if (num_found < num_min) {
5047 num_expected = num_min;
5048 more_or_less = "at least";
5050 num_expected = num_max;
5051 more_or_less = "at most";
5054 more_or_less = "exactly";
5056 number = (num_expected == 1) ? "" : "s";
5057 PyErr_Format(PyExc_TypeError,
5058 #if PY_VERSION_HEX < 0x02050000
5059 "%s() takes %s %d positional argument%s (%d given)",
5061 "%s() takes %s %zd positional argument%s (%zd given)",
5063 func_name, more_or_less, num_expected, number, num_found);
5067 raise_keyword_required_utility_code = UtilityCode(
5069 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5072 static INLINE void __Pyx_RaiseKeywordRequired(
5073 const char* func_name,
5076 PyErr_Format(PyExc_TypeError,
5077 #if PY_MAJOR_VERSION >= 3
5078 "%s() needs keyword-only argument %U", func_name, kw_name);
5080 "%s() needs keyword-only argument %s", func_name,
5081 PyString_AS_STRING(kw_name));
5086 raise_double_keywords_utility_code = UtilityCode(
5088 static void __Pyx_RaiseDoubleKeywordsError(
5089 const char* func_name, PyObject* kw_name); /*proto*/
5092 static void __Pyx_RaiseDoubleKeywordsError(
5093 const char* func_name,
5096 PyErr_Format(PyExc_TypeError,
5097 #if PY_MAJOR_VERSION >= 3
5098 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5100 "%s() got multiple values for keyword argument '%s'", func_name,
5101 PyString_AS_STRING(kw_name));
5106 #------------------------------------------------------------------------------------
5108 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5109 # were passed to a function, or if any keywords were passed to a
5110 # function that does not accept them.
5112 keyword_string_check_utility_code = UtilityCode(
5114 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5115 const char* function_name, int kw_allowed); /*proto*/
5118 static INLINE int __Pyx_CheckKeywordStrings(
5120 const char* function_name,
5125 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5126 #if PY_MAJOR_VERSION < 3
5127 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5129 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5131 goto invalid_keyword_type;
5133 if ((!kw_allowed) && unlikely(key))
5134 goto invalid_keyword;
5136 invalid_keyword_type:
5137 PyErr_Format(PyExc_TypeError,
5138 "%s() keywords must be strings", function_name);
5141 PyErr_Format(PyExc_TypeError,
5142 #if PY_MAJOR_VERSION < 3
5143 "%s() got an unexpected keyword argument '%s'",
5144 function_name, PyString_AsString(key));
5146 "%s() got an unexpected keyword argument '%U'",
5147 function_name, key);
5153 #------------------------------------------------------------------------------------
5155 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5156 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5157 # keywords will raise an invalid keyword error.
5159 # Three kinds of errors are checked: 1) non-string keywords, 2)
5160 # unexpected keywords and 3) overlap with positional arguments.
5162 # If num_posargs is greater 0, it denotes the number of positional
5163 # arguments that were passed and that must therefore not appear
5164 # amongst the keywords as well.
5166 # This method does not check for required keyword arguments.
5169 parse_keywords_utility_code = UtilityCode(
5171 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5172 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5173 const char* function_name); /*proto*/
5176 static int __Pyx_ParseOptionalKeywords(
5178 PyObject **argnames[],
5181 Py_ssize_t num_pos_args,
5182 const char* function_name)
5184 PyObject *key = 0, *value = 0;
5187 PyObject*** first_kw_arg = argnames + num_pos_args;
5189 while (PyDict_Next(kwds, &pos, &key, &value)) {
5190 name = first_kw_arg;
5191 while (*name && (**name != key)) name++;
5193 values[name-argnames] = value;
5195 #if PY_MAJOR_VERSION < 3
5196 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5198 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5200 goto invalid_keyword_type;
5202 for (name = first_kw_arg; *name; name++) {
5203 #if PY_MAJOR_VERSION >= 3
5204 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5205 PyUnicode_Compare(**name, key) == 0) break;
5207 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5208 _PyString_Eq(**name, key)) break;
5212 values[name-argnames] = value;
5214 /* unexpected keyword found */
5215 for (name=argnames; name != first_kw_arg; name++) {
5216 if (**name == key) goto arg_passed_twice;
5217 #if PY_MAJOR_VERSION >= 3
5218 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5219 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5221 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5222 _PyString_Eq(**name, key)) goto arg_passed_twice;
5226 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5228 goto invalid_keyword;
5236 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5238 invalid_keyword_type:
5239 PyErr_Format(PyExc_TypeError,
5240 "%s() keywords must be strings", function_name);
5243 PyErr_Format(PyExc_TypeError,
5244 #if PY_MAJOR_VERSION < 3
5245 "%s() got an unexpected keyword argument '%s'",
5246 function_name, PyString_AsString(key));
5248 "%s() got an unexpected keyword argument '%U'",
5249 function_name, key);
5256 #------------------------------------------------------------------------------------
5258 traceback_utility_code = UtilityCode(
5260 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5263 #include "compile.h"
5264 #include "frameobject.h"
5265 #include "traceback.h"
5267 static void __Pyx_AddTraceback(const char *funcname) {
5268 PyObject *py_srcfile = 0;
5269 PyObject *py_funcname = 0;
5270 PyObject *py_globals = 0;
5271 PyObject *empty_string = 0;
5272 PyCodeObject *py_code = 0;
5273 PyFrameObject *py_frame = 0;
5275 #if PY_MAJOR_VERSION < 3
5276 py_srcfile = PyString_FromString(%(FILENAME)s);
5278 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5280 if (!py_srcfile) goto bad;
5282 #if PY_MAJOR_VERSION < 3
5283 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5285 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5289 #if PY_MAJOR_VERSION < 3
5290 py_funcname = PyString_FromString(funcname);
5292 py_funcname = PyUnicode_FromString(funcname);
5295 if (!py_funcname) goto bad;
5296 py_globals = PyModule_GetDict(%(GLOBALS)s);
5297 if (!py_globals) goto bad;
5298 #if PY_MAJOR_VERSION < 3
5299 empty_string = PyString_FromStringAndSize("", 0);
5301 empty_string = PyBytes_FromStringAndSize("", 0);
5303 if (!empty_string) goto bad;
5304 py_code = PyCode_New(
5305 0, /*int argcount,*/
5306 #if PY_MAJOR_VERSION >= 3
5307 0, /*int kwonlyargcount,*/
5310 0, /*int stacksize,*/
5312 empty_string, /*PyObject *code,*/
5313 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5314 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5315 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5316 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5317 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5318 py_srcfile, /*PyObject *filename,*/
5319 py_funcname, /*PyObject *name,*/
5320 %(LINENO)s, /*int firstlineno,*/
5321 empty_string /*PyObject *lnotab*/
5323 if (!py_code) goto bad;
5324 py_frame = PyFrame_New(
5325 PyThreadState_GET(), /*PyThreadState *tstate,*/
5326 py_code, /*PyCodeObject *code,*/
5327 py_globals, /*PyObject *globals,*/
5328 0 /*PyObject *locals*/
5330 if (!py_frame) goto bad;
5331 py_frame->f_lineno = %(LINENO)s;
5332 PyTraceBack_Here(py_frame);
5334 Py_XDECREF(py_srcfile);
5335 Py_XDECREF(py_funcname);
5336 Py_XDECREF(empty_string);
5337 Py_XDECREF(py_code);
5338 Py_XDECREF(py_frame);
5341 'FILENAME': Naming.filename_cname,
5342 'LINENO': Naming.lineno_cname,
5343 'CFILENAME': Naming.cfilenm_cname,
5344 'CLINENO': Naming.clineno_cname,
5345 'GLOBALS': Naming.module_cname,
5346 'EMPTY_TUPLE' : Naming.empty_tuple,
5349 restore_exception_utility_code = UtilityCode(
5351 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5352 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5355 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5356 PyObject *tmp_type, *tmp_value, *tmp_tb;
5357 PyThreadState *tstate = PyThreadState_GET();
5359 #if PY_MAJOR_VERSION >= 3
5360 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5361 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5362 tmp_type = tstate->exc_type;
5363 tmp_value = tstate->exc_value;
5364 tmp_tb = tstate->exc_traceback;
5365 PyErr_NormalizeException(&type, &value, &tb);
5366 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5367 tstate->exc_type = 0;
5368 tstate->exc_value = 0;
5369 tstate->exc_traceback = 0;
5370 PyException_SetContext(value, tmp_value);
5371 Py_DECREF(tmp_type);
5376 tmp_type = tstate->curexc_type;
5377 tmp_value = tstate->curexc_value;
5378 tmp_tb = tstate->curexc_traceback;
5379 tstate->curexc_type = type;
5380 tstate->curexc_value = value;
5381 tstate->curexc_traceback = tb;
5382 Py_XDECREF(tmp_type);
5383 Py_XDECREF(tmp_value);
5387 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5388 PyThreadState *tstate = PyThreadState_GET();
5389 *type = tstate->curexc_type;
5390 *value = tstate->curexc_value;
5391 *tb = tstate->curexc_traceback;
5393 tstate->curexc_type = 0;
5394 tstate->curexc_value = 0;
5395 tstate->curexc_traceback = 0;
5400 #------------------------------------------------------------------------------------
5402 unraisable_exception_utility_code = UtilityCode(
5404 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5407 static void __Pyx_WriteUnraisable(const char *name) {
5408 PyObject *old_exc, *old_val, *old_tb;
5410 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5411 #if PY_MAJOR_VERSION < 3
5412 ctx = PyString_FromString(name);
5414 ctx = PyUnicode_FromString(name);
5416 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5418 PyErr_WriteUnraisable(Py_None);
5420 PyErr_WriteUnraisable(ctx);
5425 requires=[restore_exception_utility_code])
5427 #------------------------------------------------------------------------------------
5429 set_vtable_utility_code = UtilityCode(
5431 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5434 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5435 PyObject *pycobj = 0;
5438 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5441 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5454 #------------------------------------------------------------------------------------
5456 get_vtable_utility_code = UtilityCode(
5458 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5461 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5465 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5468 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5469 if (!*(void **)vtabptr)
5482 #------------------------------------------------------------------------------------
5484 init_string_tab_utility_code = UtilityCode(
5486 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5489 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5491 #if PY_MAJOR_VERSION < 3
5492 if (t->is_unicode && (!t->is_identifier)) {
5493 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5494 } else if (t->intern) {
5495 *t->p = PyString_InternFromString(t->s);
5497 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5499 #else /* Python 3+ has unicode identifiers */
5500 if (t->is_identifier || (t->is_unicode && t->intern)) {
5501 *t->p = PyUnicode_InternFromString(t->s);
5502 } else if (t->is_unicode) {
5503 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5505 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5516 #------------------------------------------------------------------------------------
5518 get_exception_utility_code = UtilityCode(
5520 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5523 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5524 PyObject *tmp_type, *tmp_value, *tmp_tb;
5525 PyThreadState *tstate = PyThreadState_GET();
5526 *type = tstate->curexc_type;
5527 *value = tstate->curexc_value;
5528 *tb = tstate->curexc_traceback;
5529 tstate->curexc_type = 0;
5530 tstate->curexc_value = 0;
5531 tstate->curexc_traceback = 0;
5532 PyErr_NormalizeException(type, value, tb);
5533 if (PyErr_Occurred())
5538 tmp_type = tstate->exc_type;
5539 tmp_value = tstate->exc_value;
5540 tmp_tb = tstate->exc_traceback;
5541 tstate->exc_type = *type;
5542 tstate->exc_value = *value;
5543 tstate->exc_traceback = *tb;
5544 /* Make sure tstate is in a consistent state when we XDECREF
5545 these objects (XDECREF may run arbitrary code). */
5546 Py_XDECREF(tmp_type);
5547 Py_XDECREF(tmp_value);
5559 #------------------------------------------------------------------------------------
5561 reset_exception_utility_code = UtilityCode(
5563 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5564 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5567 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5568 PyThreadState *tstate = PyThreadState_GET();
5569 *type = tstate->exc_type;
5570 *value = tstate->exc_value;
5571 *tb = tstate->exc_traceback;
5577 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5578 PyObject *tmp_type, *tmp_value, *tmp_tb;
5579 PyThreadState *tstate = PyThreadState_GET();
5580 tmp_type = tstate->exc_type;
5581 tmp_value = tstate->exc_value;
5582 tmp_tb = tstate->exc_traceback;
5583 tstate->exc_type = type;
5584 tstate->exc_value = value;
5585 tstate->exc_traceback = tb;
5586 Py_XDECREF(tmp_type);
5587 Py_XDECREF(tmp_value);
5592 #------------------------------------------------------------------------------------
5594 force_init_threads_utility_code = UtilityCode(
5596 #ifndef __PYX_FORCE_INIT_THREADS
5597 #if PY_VERSION_HEX < 0x02040200
5598 #define __PYX_FORCE_INIT_THREADS 1
5600 #define __PYX_FORCE_INIT_THREADS 0
5605 #------------------------------------------------------------------------------------