2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
136 def _gil_check(self, env):
141 error(self.pos, "%s not allowed without gil" % self.gil_message)
143 def clone_node(self):
144 """Clone the node. This is defined as a shallow copy, except for member lists
145 amongst the child attributes (from get_child_accessors) which are also
146 copied. Lists containing child nodes are thus seen as a way for the node
147 to hold multiple children directly; the list is not treated as a seperate
148 level in the tree."""
149 result = copy.copy(self)
150 for attrname in result.child_attrs:
151 value = getattr(result, attrname)
152 if isinstance(value, list):
153 setattr(result, attrname, [x for x in value])
158 # There are 4 phases of parse tree processing, applied in order to
159 # all the statements in a given scope-block:
161 # (0) analyse_control_flow
162 # Create the control flow tree into which state can be asserted and
165 # (1) analyse_declarations
166 # Make symbol table entries for all declarations at the current
167 # level, both explicit (def, cdef, etc.) and implicit (assignment
168 # to an otherwise undeclared name).
170 # (2) analyse_expressions
171 # Determine the result types of expressions and fill in the
172 # 'type' attribute of each ExprNode. Insert coercion nodes into the
173 # tree where needed to convert to and from Python objects.
174 # Allocate temporary locals for intermediate results. Fill
175 # in the 'result_code' attribute of each ExprNode with a C code
179 # Emit C code for all declarations, statements and expressions.
180 # Recursively applies the 3 processing phases to the bodies of
184 def analyse_control_flow(self, env):
187 def analyse_declarations(self, env):
190 def analyse_expressions(self, env):
191 raise InternalError("analyse_expressions not implemented for %s" % \
192 self.__class__.__name__)
194 def generate_code(self, code):
195 raise InternalError("generate_code not implemented for %s" % \
196 self.__class__.__name__)
198 def annotate(self, code):
199 # mro does the wrong thing
200 if isinstance(self, BlockNode):
201 self.body.annotate(code)
206 except AttributeError:
208 if not self.child_attrs:
211 for attr in self.child_attrs:
212 child = getattr(self, attr)
213 # Sometimes lists, sometimes nodes
216 elif isinstance(child, list):
218 pos = max(pos, c.end_pos())
220 pos = max(pos, child.end_pos())
224 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
226 return "<...nesting level cutoff...>"
227 if encountered is None:
229 if id(self) in encountered:
230 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
231 encountered.add(id(self))
233 def dump_child(x, level):
234 if isinstance(x, Node):
235 return x.dump(level, filter_out, cutoff-1, encountered)
236 elif isinstance(x, list):
237 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
242 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
244 return "<%s (%d)>" % (self.__class__.__name__, id(self))
247 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
248 for key, value in attrs:
249 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
250 res += "%s>" % indent
253 class CompilerDirectivesNode(Node):
255 Sets compiler directives for the children nodes
257 # directives {string:value} A dictionary holding the right value for
258 # *all* possible directives.
260 child_attrs = ["body"]
262 def analyse_control_flow(self, env):
264 env.directives = self.directives
265 self.body.analyse_control_flow(env)
268 def analyse_declarations(self, env):
270 env.directives = self.directives
271 self.body.analyse_declarations(env)
274 def analyse_expressions(self, env):
276 env.directives = self.directives
277 self.body.analyse_expressions(env)
280 def generate_function_definitions(self, env, code):
281 env_old = env.directives
282 code_old = code.globalstate.directives
283 code.globalstate.directives = self.directives
284 self.body.generate_function_definitions(env, code)
285 env.directives = env_old
286 code.globalstate.directives = code_old
288 def generate_execution_code(self, code):
289 old = code.globalstate.directives
290 code.globalstate.directives = self.directives
291 self.body.generate_execution_code(code)
292 code.globalstate.directives = old
294 def annotate(self, code):
295 old = code.globalstate.directives
296 code.globalstate.directives = self.directives
297 self.body.annotate(code)
298 code.globalstate.directives = old
300 class BlockNode(object):
301 # Mixin class for nodes representing a declaration block.
303 def generate_cached_builtins_decls(self, env, code):
304 entries = env.global_scope().undeclared_cached_builtins
305 for entry in entries:
306 code.globalstate.add_cached_builtin_decl(entry)
310 class StatListNode(Node):
311 # stats a list of StatNode
313 child_attrs = ["stats"]
315 def create_analysed(pos, env, *args, **kw):
316 node = StatListNode(pos, *args, **kw)
317 return node # No node-specific analysis necesarry
318 create_analysed = staticmethod(create_analysed)
320 def analyse_control_flow(self, env):
321 for stat in self.stats:
322 stat.analyse_control_flow(env)
324 def analyse_declarations(self, env):
325 #print "StatListNode.analyse_declarations" ###
326 for stat in self.stats:
327 stat.analyse_declarations(env)
329 def analyse_expressions(self, env):
330 #print "StatListNode.analyse_expressions" ###
331 for stat in self.stats:
332 stat.analyse_expressions(env)
334 def generate_function_definitions(self, env, code):
335 #print "StatListNode.generate_function_definitions" ###
336 for stat in self.stats:
337 stat.generate_function_definitions(env, code)
339 def generate_execution_code(self, code):
340 #print "StatListNode.generate_execution_code" ###
341 for stat in self.stats:
342 code.mark_pos(stat.pos)
343 stat.generate_execution_code(code)
345 def annotate(self, code):
346 for stat in self.stats:
350 class StatNode(Node):
352 # Code generation for statements is split into the following subphases:
354 # (1) generate_function_definitions
355 # Emit C code for the definitions of any structs,
356 # unions, enums and functions defined in the current
359 # (2) generate_execution_code
360 # Emit C code for executable statements.
363 def generate_function_definitions(self, env, code):
366 def generate_execution_code(self, code):
367 raise InternalError("generate_execution_code not implemented for %s" % \
368 self.__class__.__name__)
371 class CDefExternNode(StatNode):
372 # include_file string or None
375 child_attrs = ["body"]
377 def analyse_declarations(self, env):
378 if self.include_file:
379 env.add_include_file(self.include_file)
380 old_cinclude_flag = env.in_cinclude
382 self.body.analyse_declarations(env)
383 env.in_cinclude = old_cinclude_flag
385 def analyse_expressions(self, env):
388 def generate_execution_code(self, code):
391 def annotate(self, code):
392 self.body.annotate(code)
395 class CDeclaratorNode(Node):
396 # Part of a C declaration.
398 # Processing during analyse_declarations phase:
401 # Returns (name, type) pair where name is the
402 # CNameDeclaratorNode of the name being declared
403 # and type is the type it is being declared as.
405 # calling_convention string Calling convention of CFuncDeclaratorNode
406 # for which this is a base
410 calling_convention = ""
413 class CNameDeclaratorNode(CDeclaratorNode):
414 # name string The Pyrex name being declared
415 # cname string or None C name, if specified
416 # default ExprNode or None the value assigned on declaration
418 child_attrs = ['default']
422 def analyse(self, base_type, env, nonempty = 0):
423 if nonempty and self.name == '':
424 # May have mistaken the name for the type.
425 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
426 error(self.pos, "Missing argument name")
427 elif base_type.is_void:
428 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
430 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
431 base_type = py_object_type
432 self.type = base_type
433 return self, base_type
435 class CPtrDeclaratorNode(CDeclaratorNode):
436 # base CDeclaratorNode
438 child_attrs = ["base"]
440 def analyse(self, base_type, env, nonempty = 0):
441 if base_type.is_pyobject:
443 "Pointer base type cannot be a Python object")
444 ptr_type = PyrexTypes.c_ptr_type(base_type)
445 return self.base.analyse(ptr_type, env, nonempty = nonempty)
447 class CArrayDeclaratorNode(CDeclaratorNode):
448 # base CDeclaratorNode
451 child_attrs = ["base", "dimension"]
453 def analyse(self, base_type, env, nonempty = 0):
455 self.dimension.analyse_const_expression(env)
456 if not self.dimension.type.is_int:
457 error(self.dimension.pos, "Array dimension not integer")
458 size = self.dimension.get_constant_c_result_code()
467 if not base_type.is_complete():
469 "Array element type '%s' is incomplete" % base_type)
470 if base_type.is_pyobject:
472 "Array element cannot be a Python object")
473 if base_type.is_cfunction:
475 "Array element cannot be a function")
476 array_type = PyrexTypes.c_array_type(base_type, size)
477 return self.base.analyse(array_type, env, nonempty = nonempty)
480 class CFuncDeclaratorNode(CDeclaratorNode):
481 # base CDeclaratorNode
482 # args [CArgDeclNode]
483 # has_varargs boolean
484 # exception_value ConstNode
485 # exception_check boolean True if PyErr_Occurred check needed
486 # nogil boolean Can be called without gil
487 # with_gil boolean Acquire gil around function body
489 child_attrs = ["base", "args", "exception_value"]
492 optional_arg_count = 0
494 def analyse(self, return_type, env, nonempty = 0):
498 for arg_node in self.args:
499 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
500 name = name_declarator.name
501 if name_declarator.cname:
503 "Function argument cannot have C name specification")
504 # Turn *[] argument into **
506 type = PyrexTypes.c_ptr_type(type.base_type)
507 # Catch attempted C-style func(void) decl
509 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
510 func_type_args.append(
511 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
513 self.optional_arg_count += 1
514 elif self.optional_arg_count:
515 error(self.pos, "Non-default argument follows default argument")
517 if self.optional_arg_count:
518 scope = StructOrUnionScope()
519 arg_count_member = '%sn' % Naming.pyrex_prefix
520 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
521 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
522 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
523 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
524 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
529 cname = struct_cname)
530 self.op_args_struct.defined_in_pxd = 1
531 self.op_args_struct.used = 1
535 if self.exception_check == '+':
536 env.add_include_file('stdexcept')
537 if return_type.is_pyobject \
538 and (self.exception_value or self.exception_check) \
539 and self.exception_check != '+':
541 "Exception clause not allowed for function returning Python object")
543 if self.exception_value:
544 self.exception_value.analyse_const_expression(env)
545 exc_val = self.exception_value.get_constant_c_result_code()
546 if self.exception_check == '+':
547 exc_val_type = self.exception_value.type
548 if not exc_val_type.is_error and \
549 not exc_val_type.is_pyobject and \
550 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
551 error(self.exception_value.pos,
552 "Exception value must be a Python exception or cdef function with no arguments.")
554 if not return_type.assignable_from(self.exception_value.type):
555 error(self.exception_value.pos,
556 "Exception value incompatible with function return type")
557 exc_check = self.exception_check
558 if return_type.is_array:
560 "Function cannot return an array")
561 if return_type.is_cfunction:
563 "Function cannot return a function")
564 func_type = PyrexTypes.CFuncType(
565 return_type, func_type_args, self.has_varargs,
566 optional_arg_count = self.optional_arg_count,
567 exception_value = exc_val, exception_check = exc_check,
568 calling_convention = self.base.calling_convention,
569 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
570 if self.optional_arg_count:
571 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
572 callspec = env.directives['callspec']
574 current = func_type.calling_convention
575 if current and current != callspec:
576 error(self.pos, "cannot have both '%s' and '%s' "
577 "calling conventions" % (current, callspec))
578 func_type.calling_convention = callspec
579 return self.base.analyse(func_type, env)
582 class CArgDeclNode(Node):
583 # Item in a function declaration argument list.
585 # base_type CBaseTypeNode
586 # declarator CDeclaratorNode
587 # not_none boolean Tagged with 'not None'
588 # default ExprNode or None
589 # default_value PyObjectConst constant for default value
590 # is_self_arg boolean Is the "self" arg of an extension type method
591 # is_kw_only boolean Is a keyword-only argument
593 child_attrs = ["base_type", "declarator", "default"]
598 name_declarator = None
601 def analyse(self, env, nonempty = 0):
602 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
603 if self.type is None:
604 # The parser may missinterpret names as types...
606 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
608 self.declarator.name = self.base_type.name
609 self.base_type.name = None
610 self.base_type.is_basic_c_type = False
613 could_be_name = False
614 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
615 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
616 self.declarator.name = self.base_type.arg_name
617 return self.declarator.analyse(base_type, env, nonempty = nonempty)
619 return self.name_declarator, self.type
621 def calculate_default_value_code(self, code):
622 if self.default_value is None:
624 if self.default.is_literal:
625 # will not output any code, just assign the result_code
626 self.default.generate_evaluation_code(code)
627 return self.type.cast_code(self.default.result())
628 self.default_value = code.get_argument_default_const(self.type)
629 return self.default_value
631 def annotate(self, code):
633 self.default.annotate(code)
636 class CBaseTypeNode(Node):
637 # Abstract base class for C base type nodes.
639 # Processing during analyse_declarations phase:
646 class CAnalysedBaseTypeNode(Node):
651 def analyse(self, env, could_be_name = False):
654 class CSimpleBaseTypeNode(CBaseTypeNode):
656 # module_path [string] Qualifying name components
657 # is_basic_c_type boolean
661 # is_self_arg boolean Is self argument of C method
664 arg_name = None # in case the argument name was interpreted as a type
666 def analyse(self, env, could_be_name = False):
667 # Return type descriptor.
668 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
670 if self.is_basic_c_type:
671 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
673 error(self.pos, "Unrecognised type modifier combination")
674 elif self.name == "object" and not self.module_path:
675 type = py_object_type
676 elif self.name is None:
677 if self.is_self_arg and env.is_c_class_scope:
678 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
679 type = env.parent_type
681 type = py_object_type
684 scope = env.find_imported_module(self.module_path, self.pos)
688 if scope.is_c_class_scope:
689 scope = scope.global_scope()
690 entry = scope.lookup(self.name)
691 if entry and entry.is_type:
694 if self.is_self_arg and env.is_c_class_scope:
695 type = env.parent_type
697 type = py_object_type
698 self.arg_name = self.name
700 error(self.pos, "'%s' is not a type identifier" % self.name)
702 if not type.is_numeric or type.is_complex:
703 error(self.pos, "can only complexify c numeric types")
704 type = PyrexTypes.CComplexType(type)
705 type.create_declaration_utility_code(env)
709 return PyrexTypes.error_type
711 class CBufferAccessTypeNode(CBaseTypeNode):
713 # positional_args [ExprNode] List of positional arguments
714 # keyword_args DictNode Keyword arguments
715 # base_type_node CBaseTypeNode
718 # type PyrexType.BufferType ...containing the right options
721 child_attrs = ["base_type_node", "positional_args",
722 "keyword_args", "dtype_node"]
728 def analyse(self, env, could_be_name = False):
729 base_type = self.base_type_node.analyse(env)
730 if base_type.is_error: return base_type
733 options = Buffer.analyse_buffer_options(
736 self.positional_args,
738 base_type.buffer_defaults)
740 self.type = PyrexTypes.BufferType(base_type, **options)
743 class CComplexBaseTypeNode(CBaseTypeNode):
744 # base_type CBaseTypeNode
745 # declarator CDeclaratorNode
747 child_attrs = ["base_type", "declarator"]
749 def analyse(self, env, could_be_name = False):
750 base = self.base_type.analyse(env, could_be_name)
751 _, type = self.declarator.analyse(base, env)
755 class CVarDefNode(StatNode):
756 # C variable definition or forward/extern function declaration.
758 # visibility 'private' or 'public' or 'extern'
759 # base_type CBaseTypeNode
760 # declarators [CDeclaratorNode]
763 # need_properties [entry]
765 # decorators [cython.locals(...)] or None
766 # directive_locals { string : NameNode } locals defined by cython.locals(...)
768 child_attrs = ["base_type", "declarators"]
772 directive_locals = {}
774 def analyse_declarations(self, env, dest_scope = None):
777 self.dest_scope = dest_scope
778 base_type = self.base_type.analyse(env)
780 need_property = False
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 # If the field is settable and extension type, then the CPython mechanism does
786 # not do enough type-checking for us.
788 elif (base_type.is_typedef and base_type.typedef_is_external
789 and (self.visibility in ('public', 'readonly'))):
790 # If the field is an external typedef, we cannot be sure about the type,
791 # so do conversion ourself rather than rely on the CPython mechanism (through
792 # a property; made in AnalyseDeclarationsTransform).
796 visibility = 'private'
797 self.need_properties = []
799 visibility = self.visibility
801 for declarator in self.declarators:
802 name_declarator, type = declarator.analyse(base_type, env)
803 if not type.is_complete():
804 if not (self.visibility == 'extern' and type.is_array):
805 error(declarator.pos,
806 "Variable type '%s' is incomplete" % type)
807 if self.visibility == 'extern' and type.is_pyobject:
808 error(declarator.pos,
809 "Python object cannot be declared extern")
810 name = name_declarator.name
811 cname = name_declarator.cname
813 error(declarator.pos, "Missing name in declaration.")
815 if type.is_cfunction:
816 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
817 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
819 if entry is not None:
820 entry.directive_locals = self.directive_locals
822 if self.directive_locals:
823 s.error("Decorators can only be followed by functions")
824 if self.in_pxd and self.visibility != 'extern':
826 "Only 'extern' C variable declaration allowed in .pxd file")
827 entry = dest_scope.declare_var(name, type, declarator.pos,
828 cname = cname, visibility = visibility, is_cdef = 1)
830 self.need_properties.append(entry)
831 entry.needs_property = 1
834 class CStructOrUnionDefNode(StatNode):
836 # cname string or None
837 # kind "struct" or "union"
838 # typedef_flag boolean
839 # visibility "public" or "private"
841 # attributes [CVarDefNode] or None
845 child_attrs = ["attributes"]
847 def analyse_declarations(self, env):
849 if self.visibility == 'extern' and self.packed:
850 error(self.pos, "Cannot declare extern struct as 'packed'")
851 if self.attributes is not None:
852 scope = StructOrUnionScope(self.name)
853 self.entry = env.declare_struct_or_union(
854 self.name, self.kind, scope, self.typedef_flag, self.pos,
855 self.cname, visibility = self.visibility, packed = self.packed)
856 if self.attributes is not None:
857 if self.in_pxd and not env.in_cinclude:
858 self.entry.defined_in_pxd = 1
859 for attr in self.attributes:
860 attr.analyse_declarations(env, scope)
861 if self.visibility != 'extern':
862 need_typedef_indirection = False
863 for attr in scope.var_entries:
866 type = type.base_type
867 if type == self.entry.type:
868 error(attr.pos, "Struct cannot contain itself as a member.")
869 if self.typedef_flag:
871 type = type.base_type
872 if type == self.entry.type:
873 need_typedef_indirection = True
874 if need_typedef_indirection:
875 # C can't handle typedef structs that refer to themselves.
876 struct_entry = self.entry
877 self.entry = env.declare_typedef(
878 self.name, struct_entry.type, self.pos,
879 cname = self.cname, visibility='ignore')
880 struct_entry.type.typedef_flag = False
881 # FIXME: this might be considered a hack ;-)
882 struct_entry.cname = struct_entry.type.cname = \
883 '_' + self.entry.type.typedef_cname
885 def analyse_expressions(self, env):
888 def generate_execution_code(self, code):
892 class CEnumDefNode(StatNode):
893 # name string or None
894 # cname string or None
895 # items [CEnumDefItemNode]
896 # typedef_flag boolean
897 # visibility "public" or "private"
901 child_attrs = ["items"]
903 def analyse_declarations(self, env):
904 self.entry = env.declare_enum(self.name, self.pos,
905 cname = self.cname, typedef_flag = self.typedef_flag,
906 visibility = self.visibility)
907 if self.items is not None:
908 if self.in_pxd and not env.in_cinclude:
909 self.entry.defined_in_pxd = 1
910 for item in self.items:
911 item.analyse_declarations(env, self.entry)
913 def generate_execution_code(self, code):
914 if self.visibility == 'public':
915 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
916 for item in self.entry.enum_values:
917 code.putln("%s = PyInt_FromLong(%s); %s" % (
920 code.error_goto_if_null(temp, item.pos)))
921 code.put_gotref(temp)
922 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
926 code.error_goto(item.pos)))
927 code.put_decref_clear(temp, PyrexTypes.py_object_type)
928 code.funcstate.release_temp(temp)
931 class CEnumDefItemNode(StatNode):
933 # cname string or None
934 # value ExprNode or None
936 child_attrs = ["value"]
938 def analyse_declarations(self, env, enum_entry):
940 self.value.analyse_const_expression(env)
941 if not self.value.type.is_int:
942 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
943 self.value.analyse_const_expression(env)
944 entry = env.declare_const(self.name, enum_entry.type,
945 self.value, self.pos, cname = self.cname,
946 visibility = enum_entry.visibility)
947 enum_entry.enum_values.append(entry)
950 class CTypeDefNode(StatNode):
951 # base_type CBaseTypeNode
952 # declarator CDeclaratorNode
953 # visibility "public" or "private"
956 child_attrs = ["base_type", "declarator"]
958 def analyse_declarations(self, env):
959 base = self.base_type.analyse(env)
960 name_declarator, type = self.declarator.analyse(base, env)
961 name = name_declarator.name
962 cname = name_declarator.cname
963 entry = env.declare_typedef(name, type, self.pos,
964 cname = cname, visibility = self.visibility)
965 if self.in_pxd and not env.in_cinclude:
966 entry.defined_in_pxd = 1
968 def analyse_expressions(self, env):
970 def generate_execution_code(self, code):
974 class FuncDefNode(StatNode, BlockNode):
975 # Base class for function definition nodes.
977 # return_type PyrexType
978 # #filename string C name of filename string const
980 # needs_closure boolean Whether or not this function has inner functions/classes/yield
981 # directive_locals { string : NameNode } locals defined by cython.locals(...)
985 needs_closure = False
987 def analyse_default_values(self, env):
988 genv = env.global_scope()
989 for arg in self.args:
992 arg.default.analyse_types(env)
993 arg.default = arg.default.coerce_to(arg.type, genv)
996 "This argument cannot have a default value")
999 def need_gil_acquisition(self, lenv):
1002 def create_local_scope(self, env):
1004 while env.is_py_class_scope or env.is_c_class_scope:
1005 env = env.outer_scope
1006 if self.needs_closure:
1007 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1009 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1010 lenv.return_type = self.return_type
1011 type = self.entry.type
1012 if type.is_cfunction:
1013 lenv.nogil = type.nogil and not type.with_gil
1014 self.local_scope = lenv
1015 lenv.directives = env.directives
1018 def generate_function_definitions(self, env, code):
1021 lenv = self.local_scope
1023 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1024 self.entry.scope.is_c_class_scope)
1026 # Generate C code for header and body of function
1027 code.enter_cfunc_scope()
1028 code.return_from_error_cleanup_label = code.new_label()
1030 # ----- Top-level constants used by this function
1031 code.mark_pos(self.pos)
1032 self.generate_cached_builtins_decls(lenv, code)
1033 # ----- Function header
1036 self.py_func.generate_function_header(code,
1037 with_pymethdef = env.is_py_class_scope,
1039 self.generate_function_header(code,
1040 with_pymethdef = env.is_py_class_scope)
1041 # ----- Local variable declarations
1042 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1043 self.generate_argument_declarations(lenv, code)
1044 if self.needs_closure:
1045 code.putln("/* TODO: declare and create scope object */")
1046 code.put_var_declarations(lenv.var_entries)
1048 if not self.return_type.is_void:
1049 if self.return_type.is_pyobject:
1053 (self.return_type.declaration_code(
1054 Naming.retval_cname),
1056 tempvardecl_code = code.insertion_point()
1057 self.generate_keyword_list(code)
1058 # ----- Extern library function declarations
1059 lenv.generate_library_function_declarations(code)
1060 # ----- GIL acquisition
1061 acquire_gil = self.need_gil_acquisition(lenv)
1063 env.use_utility_code(force_init_threads_utility_code)
1064 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1065 # ----- Automatic lead-ins for certain special functions
1067 code.put_setup_refcount_context(self.entry.name)
1068 if is_getbuffer_slot:
1069 self.getbuffer_init(code)
1070 # ----- Fetch arguments
1071 self.generate_argument_parsing_code(env, code)
1072 # If an argument is assigned to in the body, we must
1073 # incref it to properly keep track of refcounts.
1074 for entry in lenv.arg_entries:
1075 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1076 code.put_var_incref(entry)
1077 # ----- Initialise local variables
1078 for entry in lenv.var_entries:
1079 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1080 code.put_init_var_to_py_none(entry)
1081 # ----- Initialise local buffer auxiliary variables
1082 for entry in lenv.var_entries + lenv.arg_entries:
1083 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1084 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1085 # ----- Check and convert arguments
1086 self.generate_argument_type_tests(code)
1087 # ----- Acquire buffer arguments
1088 for entry in lenv.arg_entries:
1089 if entry.type.is_buffer:
1090 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1091 # ----- Function body
1092 self.body.generate_execution_code(code)
1093 # ----- Default return value
1095 if self.return_type.is_pyobject:
1096 #if self.return_type.is_extension_type:
1097 # lhs = "(PyObject *)%s" % Naming.retval_cname
1099 lhs = Naming.retval_cname
1100 code.put_init_to_py_none(lhs, self.return_type)
1102 val = self.return_type.default_value
1104 code.putln("%s = %s;" % (Naming.retval_cname, val))
1105 # ----- Error cleanup
1106 if code.error_label in code.labels_used:
1107 code.put_goto(code.return_label)
1108 code.put_label(code.error_label)
1109 for cname, type in code.funcstate.all_managed_temps():
1110 code.put_xdecref(cname, type)
1112 # Clean up buffers -- this calls a Python function
1113 # so need to save and restore error state
1114 buffers_present = len(lenv.buffer_entries) > 0
1116 code.globalstate.use_utility_code(restore_exception_utility_code)
1117 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1118 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1119 for entry in lenv.buffer_entries:
1120 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1121 #code.putln("%s = 0;" % entry.cname)
1122 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1124 err_val = self.error_value()
1125 exc_check = self.caller_will_check_exceptions()
1126 if err_val is not None or exc_check:
1127 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1129 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1130 % self.entry.qualified_name, 0)
1132 '__Pyx_WriteUnraisable("%s");' %
1133 self.entry.qualified_name)
1134 env.use_utility_code(unraisable_exception_utility_code)
1135 env.use_utility_code(restore_exception_utility_code)
1136 default_retval = self.return_type.default_value
1137 if err_val is None and default_retval:
1138 err_val = default_retval
1139 if err_val is not None:
1142 Naming.retval_cname,
1145 if is_getbuffer_slot:
1146 self.getbuffer_error_cleanup(code)
1148 # If we are using the non-error cleanup section we should
1149 # jump past it if we have an error. The if-test below determine
1150 # whether this section is used.
1151 if buffers_present or is_getbuffer_slot:
1152 code.put_goto(code.return_from_error_cleanup_label)
1155 # ----- Non-error return cleanup
1156 # If you add anything here, remember to add a condition to the
1157 # if-test above in the error block (so that it can jump past this
1159 code.put_label(code.return_label)
1160 for entry in lenv.buffer_entries:
1162 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1163 if is_getbuffer_slot:
1164 self.getbuffer_normal_cleanup(code)
1165 # ----- Return cleanup for both error and no-error return
1166 code.put_label(code.return_from_error_cleanup_label)
1167 if not Options.init_local_none:
1168 for entry in lenv.var_entries:
1169 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1170 entry.xdecref_cleanup = 1
1171 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1172 # Decref any increfed args
1173 for entry in lenv.arg_entries:
1174 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1175 code.put_var_decref(entry)
1177 # code.putln("/* TODO: decref scope object */")
1179 # This code is duplicated in ModuleNode.generate_module_init_func
1181 default_retval = self.return_type.default_value
1182 err_val = self.error_value()
1183 if err_val is None and default_retval:
1184 err_val = default_retval
1185 if self.return_type.is_pyobject:
1186 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1188 code.put_finish_refcount_context()
1191 code.putln("PyGILState_Release(_save);")
1193 if not self.return_type.is_void:
1194 code.putln("return %s;" % Naming.retval_cname)
1197 # ----- Go back and insert temp variable declarations
1198 tempvardecl_code.put_temp_declarations(code.funcstate)
1199 # ----- Python version
1200 code.exit_cfunc_scope()
1202 self.py_func.generate_function_definitions(env, code)
1203 self.generate_wrapper_functions(code)
1205 def declare_argument(self, env, arg):
1206 if arg.type.is_void:
1207 error(arg.pos, "Invalid use of 'void'")
1208 elif not arg.type.is_complete() and not arg.type.is_array:
1210 "Argument type '%s' is incomplete" % arg.type)
1211 return env.declare_arg(arg.name, arg.type, arg.pos)
1213 def generate_wrapper_functions(self, code):
1216 def generate_execution_code(self, code):
1217 # Evaluate and store argument default values
1218 for arg in self.args:
1219 default = arg.default
1221 if not default.is_literal:
1222 default.generate_evaluation_code(code)
1223 default.make_owned_reference(code)
1224 result = default.result_as(arg.type)
1227 arg.calculate_default_value_code(code),
1229 if arg.type.is_pyobject:
1230 code.put_giveref(default.result())
1231 default.generate_post_assignment_code(code)
1232 default.free_temps(code)
1233 # For Python class methods, create and store function object
1235 self.assmt.generate_execution_code(code)
1238 # Special code for the __getbuffer__ function
1240 def getbuffer_init(self, code):
1241 info = self.local_scope.arg_entries[1].cname
1242 # Python 3.0 betas have a bug in memoryview which makes it call
1243 # getbuffer with a NULL parameter. For now we work around this;
1244 # the following line should be removed when this bug is fixed.
1245 code.putln("if (%s == NULL) return 0;" % info)
1246 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1247 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1249 def getbuffer_error_cleanup(self, code):
1250 info = self.local_scope.arg_entries[1].cname
1251 code.put_gotref("%s->obj" % info)
1252 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1255 def getbuffer_normal_cleanup(self, code):
1256 info = self.local_scope.arg_entries[1].cname
1257 code.putln("if (%s->obj == Py_None) {" % info)
1258 code.put_gotref("Py_None")
1259 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1262 class CFuncDefNode(FuncDefNode):
1263 # C function definition.
1265 # modifiers ['inline']
1266 # visibility 'private' or 'public' or 'extern'
1267 # base_type CBaseTypeNode
1268 # declarator CDeclaratorNode
1271 # decorators [DecoratorNode] list of decorators
1273 # with_gil boolean Acquire GIL around body
1275 # py_func wrapper for calling from Python
1276 # overridable whether or not this is a cpdef function
1277 # inline_in_pxd whether this is an inline function in a pxd file
1279 child_attrs = ["base_type", "declarator", "body", "py_func"]
1281 inline_in_pxd = False
1283 directive_locals = {}
1285 def unqualified_name(self):
1286 return self.entry.name
1288 def analyse_declarations(self, env):
1289 directive_locals = self.directive_locals = env.directives['locals']
1290 base_type = self.base_type.analyse(env)
1291 # The 2 here is because we need both function and argument names.
1292 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1293 if not type.is_cfunction:
1295 "Suite attached to non-function declaration")
1296 # Remember the actual type according to the function header
1297 # written here, because the type in the symbol table entry
1298 # may be different if we're overriding a C method inherited
1299 # from the base type of an extension type.
1301 type.is_overridable = self.overridable
1302 declarator = self.declarator
1303 while not hasattr(declarator, 'args'):
1304 declarator = declarator.base
1305 self.args = declarator.args
1306 for formal_arg, type_arg in zip(self.args, type.args):
1307 formal_arg.type = type_arg.type
1308 formal_arg.name = type_arg.name
1309 formal_arg.cname = type_arg.cname
1310 name = name_declarator.name
1311 cname = name_declarator.cname
1312 self.entry = env.declare_cfunction(
1313 name, type, self.pos,
1314 cname = cname, visibility = self.visibility,
1315 defining = self.body is not None,
1316 api = self.api, modifiers = self.modifiers)
1317 self.entry.inline_func_in_pxd = self.inline_in_pxd
1318 self.return_type = type.return_type
1320 if self.overridable and not env.is_module_scope:
1321 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1322 # An error will be produced in the cdef function
1323 self.overridable = False
1325 if self.overridable:
1327 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1328 self.py_func = DefNode(pos = self.pos,
1329 name = self.entry.name,
1332 starstar_arg = None,
1334 body = py_func_body,
1336 self.py_func.is_module_scope = env.is_module_scope
1337 self.py_func.analyse_declarations(env)
1338 self.entry.as_variable = self.py_func.entry
1339 # Reset scope entry the above cfunction
1340 env.entries[name] = self.entry
1341 if not env.is_module_scope or Options.lookup_module_cpdef:
1342 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1343 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1345 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1347 args = self.type.args
1348 if omit_optional_args:
1349 args = args[:len(args) - self.type.optional_arg_count]
1350 arg_names = [arg.name for arg in args]
1352 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1354 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1355 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1356 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1357 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)
1358 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1360 def declare_arguments(self, env):
1361 for arg in self.type.args:
1363 error(arg.pos, "Missing argument name")
1364 self.declare_argument(env, arg)
1366 def need_gil_acquisition(self, lenv):
1367 return self.type.with_gil
1369 def gil_check(self, env):
1371 with_gil = type.with_gil
1372 if type.nogil and not with_gil:
1373 if type.return_type.is_pyobject:
1375 "Function with Python return type cannot be declared nogil")
1376 for entry in env.var_entries:
1377 if entry.type.is_pyobject:
1378 error(self.pos, "Function declared nogil has Python locals or temporaries")
1380 def analyse_expressions(self, env):
1381 self.local_scope.directives = env.directives
1382 if self.py_func is not None:
1383 # this will also analyse the default values
1384 self.py_func.analyse_expressions(env)
1386 self.analyse_default_values(env)
1388 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1391 visibility = self.entry.visibility
1392 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1393 arg_decls.append(arg.declaration_code())
1394 if with_dispatch and self.overridable:
1395 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1396 if type.optional_arg_count and with_opt_args:
1397 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1398 if type.has_varargs:
1399 arg_decls.append("...")
1401 arg_decls = ["void"]
1403 cname = self.entry.func_cname
1404 entity = type.function_header_code(cname, ', '.join(arg_decls))
1405 if visibility == 'public':
1406 dll_linkage = "DL_EXPORT"
1409 header = self.return_type.declaration_code(entity,
1410 dll_linkage = dll_linkage)
1411 if visibility == 'extern':
1412 storage_class = "%s " % Naming.extern_c_macro
1413 elif visibility == 'public':
1416 storage_class = "static "
1417 code.putln("%s%s %s {" % (
1419 ' '.join(self.modifiers).upper(), # macro forms
1422 def generate_argument_declarations(self, env, code):
1423 for arg in self.args:
1425 result = arg.calculate_default_value_code(code)
1426 code.putln('%s = %s;' % (
1427 arg.type.declaration_code(arg.cname), result))
1429 def generate_keyword_list(self, code):
1432 def generate_argument_parsing_code(self, env, code):
1434 if self.type.optional_arg_count:
1435 code.putln('if (%s) {' % Naming.optional_args_cname)
1436 for arg in self.args:
1438 # FIXME: simple name prefixing doesn't work when
1439 # argument name mangling is in place
1440 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1441 declarator = arg.declarator
1442 while not hasattr(declarator, 'name'):
1443 declarator = declarator.base
1444 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1446 for _ in range(self.type.optional_arg_count):
1450 def generate_argument_conversion_code(self, code):
1453 def generate_argument_type_tests(self, code):
1454 # Generate type tests for args whose type in a parent
1455 # class is a supertype of the declared type.
1456 for arg in self.type.args:
1457 if arg.needs_type_test:
1458 self.generate_arg_type_test(arg, code)
1460 def generate_arg_type_test(self, arg, code):
1461 # Generate type test for one argument.
1462 if arg.type.typeobj_is_available():
1463 typeptr_cname = arg.type.typeptr_cname
1464 arg_code = "((PyObject *)%s)" % arg.cname
1466 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1471 type.is_builtin_type,
1472 code.error_goto(arg.pos)))
1474 error(arg.pos, "Cannot test type of extern C class "
1475 "without type object name specification")
1477 def error_value(self):
1478 if self.return_type.is_pyobject:
1482 return self.entry.type.exception_value
1484 def caller_will_check_exceptions(self):
1485 return self.entry.type.exception_check
1487 def generate_wrapper_functions(self, code):
1488 # If the C signature of a function has changed, we need to generate
1489 # wrappers to put in the slots here.
1492 func_type = entry.type
1493 while entry.prev_entry is not None:
1495 entry = entry.prev_entry
1496 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1498 self.generate_function_header(code,
1500 with_dispatch = entry.type.is_overridable,
1501 with_opt_args = entry.type.optional_arg_count,
1502 cname = entry.func_cname)
1503 if not self.return_type.is_void:
1505 args = self.type.args
1506 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1507 if entry.type.is_overridable:
1508 arglist.append(Naming.skip_dispatch_cname)
1509 elif func_type.is_overridable:
1511 if entry.type.optional_arg_count:
1512 arglist.append(Naming.optional_args_cname)
1513 elif func_type.optional_arg_count:
1514 arglist.append('NULL')
1515 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1519 class PyArgDeclNode(Node):
1520 # Argument which must be a Python object (used
1521 # for * and ** arguments).
1524 # entry Symtab.Entry
1528 class DecoratorNode(Node):
1531 # decorator NameNode or CallNode
1532 child_attrs = ['decorator']
1535 class DefNode(FuncDefNode):
1536 # A Python function definition.
1538 # name string the Python name of the function
1539 # decorators [DecoratorNode] list of decorators
1540 # args [CArgDeclNode] formal arguments
1541 # star_arg PyArgDeclNode or None * argument
1542 # starstar_arg PyArgDeclNode or None ** argument
1543 # doc EncodedString or None
1546 # The following subnode is constructed internally
1547 # when the def statement is inside a Python class definition.
1549 # assmt AssignmentNode Function construction/assignment
1551 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1555 num_required_kw_args = 0
1556 reqd_kw_flags_cname = "0"
1562 def __init__(self, pos, **kwds):
1563 FuncDefNode.__init__(self, pos, **kwds)
1565 for arg in self.args:
1572 self.num_kwonly_args = k
1573 self.num_required_kw_args = rk
1574 self.num_required_args = r
1576 def as_cfunction(self, cfunc=None, scope=None):
1578 error(self.star_arg.pos, "cdef function cannot have star argument")
1579 if self.starstar_arg:
1580 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1583 for formal_arg in self.args:
1584 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1585 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1587 type = py_object_type,
1588 pos = formal_arg.pos))
1589 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1591 has_varargs = False,
1592 exception_value = None,
1593 exception_check = False,
1596 is_overridable = True)
1597 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1599 cfunc_type = cfunc.type
1600 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1601 error(self.pos, "wrong number of arguments")
1602 error(declarator.pos, "previous declaration here")
1603 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1604 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1605 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1606 formal_arg.type = type_arg.type
1607 formal_arg.name_declarator = name_declarator
1609 if cfunc_type.exception_value is None:
1610 exception_value = None
1612 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1613 declarator = CFuncDeclaratorNode(self.pos,
1614 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1616 has_varargs = False,
1617 exception_check = cfunc_type.exception_check,
1618 exception_value = exception_value,
1619 with_gil = cfunc_type.with_gil,
1620 nogil = cfunc_type.nogil)
1621 return CFuncDefNode(self.pos,
1623 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1624 declarator = declarator,
1627 overridable = cfunc_type.is_overridable,
1629 with_gil = cfunc_type.with_gil,
1630 nogil = cfunc_type.nogil,
1631 visibility = 'private',
1633 directive_locals = getattr(cfunc, 'directive_locals', {}))
1635 def analyse_declarations(self, env):
1636 directive_locals = self.directive_locals = env.directives['locals']
1637 for arg in self.args:
1638 if hasattr(arg, 'name'):
1640 name_declarator = None
1642 base_type = arg.base_type.analyse(env)
1643 name_declarator, type = \
1644 arg.declarator.analyse(base_type, env)
1645 arg.name = name_declarator.name
1646 if arg.name in directive_locals:
1647 type_node = directive_locals[arg.name]
1648 other_type = type_node.analyse_as_type(env)
1649 if other_type is None:
1650 error(type_node.pos, "Not a type")
1651 elif (type is not PyrexTypes.py_object_type
1652 and not type.same_as(other_type)):
1653 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1654 error(type_node.pos, "Previous declaration here")
1657 if name_declarator and name_declarator.cname:
1659 "Python function argument cannot have C name specification")
1660 arg.type = type.as_argument_type()
1662 arg.needs_conversion = 0
1663 arg.needs_type_test = 0
1665 if arg.not_none and not arg.type.is_extension_type:
1667 "Only extension type arguments can have 'not None'")
1668 self.declare_pyfunction(env)
1669 self.analyse_signature(env)
1670 self.return_type = self.entry.signature.return_type()
1672 def analyse_signature(self, env):
1673 any_type_tests_needed = 0
1674 if self.entry.is_special:
1675 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1676 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1677 # Use the simpler calling signature for zero- and one-argument functions.
1678 if self.entry.signature is TypeSlots.pyfunction_signature:
1679 if len(self.args) == 0:
1680 self.entry.signature = TypeSlots.pyfunction_noargs
1681 elif len(self.args) == 1:
1682 if self.args[0].default is None and not self.args[0].kw_only:
1683 self.entry.signature = TypeSlots.pyfunction_onearg
1684 elif self.entry.signature is TypeSlots.pymethod_signature:
1685 if len(self.args) == 1:
1686 self.entry.signature = TypeSlots.unaryfunc
1687 elif len(self.args) == 2:
1688 if self.args[1].default is None and not self.args[1].kw_only:
1689 self.entry.signature = TypeSlots.ibinaryfunc
1690 sig = self.entry.signature
1691 nfixed = sig.num_fixed_args()
1692 for i in range(nfixed):
1693 if i < len(self.args):
1696 if sig.is_self_arg(i):
1698 arg.hdr_type = arg.type = env.parent_type
1699 arg.needs_conversion = 0
1701 arg.hdr_type = sig.fixed_arg_type(i)
1702 if not arg.type.same_as(arg.hdr_type):
1703 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1704 arg.needs_type_test = 1
1705 any_type_tests_needed = 1
1707 arg.needs_conversion = 1
1708 if arg.needs_conversion:
1709 arg.hdr_cname = Naming.arg_prefix + arg.name
1711 arg.hdr_cname = Naming.var_prefix + arg.name
1713 self.bad_signature()
1715 if nfixed < len(self.args):
1716 if not sig.has_generic_args:
1717 self.bad_signature()
1718 for arg in self.args:
1719 if arg.is_generic and \
1720 (arg.type.is_extension_type or arg.type.is_builtin_type):
1721 arg.needs_type_test = 1
1722 any_type_tests_needed = 1
1723 if any_type_tests_needed:
1724 env.use_utility_code(arg_type_test_utility_code)
1726 def bad_signature(self):
1727 sig = self.entry.signature
1728 expected_str = "%d" % sig.num_fixed_args()
1729 if sig.has_generic_args:
1730 expected_str = expected_str + " or more"
1732 if name.startswith("__") and name.endswith("__"):
1733 desc = "Special method"
1737 "%s %s has wrong number of arguments "
1738 "(%d declared, %s expected)" % (
1739 desc, self.name, len(self.args), expected_str))
1741 def signature_has_nongeneric_args(self):
1742 argcount = len(self.args)
1743 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1747 def signature_has_generic_args(self):
1748 return self.entry.signature.has_generic_args
1750 def declare_pyfunction(self, env):
1751 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1753 entry = env.lookup_here(self.name)
1754 if entry and entry.type.is_cfunction and not self.is_wrapper:
1755 warning(self.pos, "Overriding cdef method with def method.", 5)
1756 entry = env.declare_pyfunction(self.name, self.pos)
1758 prefix = env.scope_prefix
1759 entry.func_cname = \
1760 Naming.pyfunc_prefix + prefix + name
1761 entry.pymethdef_cname = \
1762 Naming.pymethdef_prefix + prefix + name
1763 if Options.docstrings:
1764 entry.doc = embed_position(self.pos, self.doc)
1766 Naming.funcdoc_prefix + prefix + name
1770 def declare_arguments(self, env):
1771 for arg in self.args:
1773 error(arg.pos, "Missing argument name")
1774 if arg.needs_conversion:
1775 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1776 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1777 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1778 if arg.type.is_pyobject:
1779 arg.entry.init = "0"
1780 arg.entry.init_to_none = 0
1782 arg.entry = self.declare_argument(env, arg)
1784 arg.entry.is_self_arg = arg.is_self_arg
1786 if arg.is_self_arg or \
1787 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1788 arg.entry.is_declared_generic = 1
1789 self.declare_python_arg(env, self.star_arg)
1790 self.declare_python_arg(env, self.starstar_arg)
1792 def declare_python_arg(self, env, arg):
1794 entry = env.declare_var(arg.name,
1795 PyrexTypes.py_object_type, arg.pos)
1798 entry.init_to_none = 0
1799 entry.xdecref_cleanup = 1
1801 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1803 def analyse_expressions(self, env):
1804 self.local_scope.directives = env.directives
1805 self.analyse_default_values(env)
1806 if env.is_py_class_scope:
1807 self.synthesize_assignment_node(env)
1809 def synthesize_assignment_node(self, env):
1811 self.assmt = SingleAssignmentNode(self.pos,
1812 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1813 rhs = ExprNodes.UnboundMethodNode(self.pos,
1814 function = ExprNodes.PyCFunctionNode(self.pos,
1815 pymethdef_cname = self.entry.pymethdef_cname)))
1816 self.assmt.analyse_declarations(env)
1817 self.assmt.analyse_expressions(env)
1819 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1821 sig = self.entry.signature
1822 if sig.has_dummy_arg:
1823 arg_code_list.append(
1824 "PyObject *%s" % Naming.self_cname)
1825 for arg in self.args:
1826 if not arg.is_generic:
1828 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1830 arg_code_list.append(
1831 arg.hdr_type.declaration_code(arg.hdr_cname))
1832 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1833 arg_code_list.append("PyObject *unused")
1834 if sig.has_generic_args:
1835 arg_code_list.append(
1836 "PyObject *%s, PyObject *%s"
1837 % (Naming.args_cname, Naming.kwds_cname))
1838 arg_code = ", ".join(arg_code_list)
1839 dc = self.return_type.declaration_code(self.entry.func_cname)
1840 header = "static %s(%s)" % (dc, arg_code)
1841 code.putln("%s; /*proto*/" % header)
1844 if self.entry.doc and Options.docstrings:
1845 docstr = self.entry.doc
1846 if not isinstance(docstr, str):
1847 docstr = docstr.utf8encode()
1849 'static char %s[] = "%s";' % (
1850 self.entry.doc_cname,
1851 split_docstring(escape_byte_string(docstr))))
1854 "static PyMethodDef %s = " %
1855 self.entry.pymethdef_cname)
1856 code.put_pymethoddef(self.entry, ";")
1857 code.putln("%s {" % header)
1859 def generate_argument_declarations(self, env, code):
1860 for arg in self.args:
1861 if arg.is_generic: # or arg.needs_conversion:
1862 if arg.needs_conversion:
1863 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1865 code.put_var_declaration(arg.entry)
1867 def generate_keyword_list(self, code):
1868 if self.signature_has_generic_args() and \
1869 self.signature_has_nongeneric_args():
1871 "static PyObject **%s[] = {" %
1872 Naming.pykwdlist_cname)
1873 for arg in self.args:
1875 pystring_cname = code.intern_identifier(arg.name)
1876 code.put('&%s,' % pystring_cname)
1879 def generate_argument_parsing_code(self, env, code):
1880 # Generate PyArg_ParseTuple call for generic
1881 # arguments, if any.
1882 if self.entry.signature.has_dummy_arg:
1883 # get rid of unused argument warning
1884 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1886 old_error_label = code.new_error_label()
1887 our_error_label = code.error_label
1888 end_label = code.new_label("argument_unpacking_done")
1890 has_kwonly_args = self.num_kwonly_args > 0
1891 has_star_or_kw_args = self.star_arg is not None \
1892 or self.starstar_arg is not None or has_kwonly_args
1894 for arg in self.args:
1895 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1896 arg.type.create_from_py_utility_code(env)
1898 if not self.signature_has_generic_args():
1899 if has_star_or_kw_args:
1900 error(self.pos, "This method cannot have * or keyword arguments")
1901 self.generate_argument_conversion_code(code)
1903 elif not self.signature_has_nongeneric_args():
1904 # func(*args) or func(**kw) or func(*args, **kw)
1905 self.generate_stararg_copy_code(code)
1908 positional_args = []
1911 for arg in self.args:
1912 arg_entry = arg.entry
1916 if not arg.is_self_arg:
1918 kw_only_args.append(arg)
1920 positional_args.append(arg)
1922 kw_only_args.append(arg)
1925 error(arg.pos, "Non-default argument following default argument")
1926 elif not arg.is_self_arg:
1927 positional_args.append(arg)
1929 self.generate_tuple_and_keyword_parsing_code(
1930 positional_args, kw_only_args, end_label, code)
1932 code.error_label = old_error_label
1933 if code.label_used(our_error_label):
1934 if not code.label_used(end_label):
1935 code.put_goto(end_label)
1936 code.put_label(our_error_label)
1937 if has_star_or_kw_args:
1938 self.generate_arg_decref(self.star_arg, code)
1939 if self.starstar_arg:
1940 if self.starstar_arg.entry.xdecref_cleanup:
1941 code.put_var_xdecref(self.starstar_arg.entry)
1943 code.put_var_decref(self.starstar_arg.entry)
1944 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1945 code.putln("return %s;" % self.error_value())
1946 if code.label_used(end_label):
1947 code.put_label(end_label)
1949 def generate_arg_assignment(self, arg, item, code):
1950 if arg.type.is_pyobject:
1952 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1953 code.putln("%s = %s;" % (arg.entry.cname, item))
1955 func = arg.type.from_py_function
1957 code.putln("%s = %s(%s); %s" % (
1961 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1963 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1965 def generate_arg_xdecref(self, arg, code):
1967 code.put_var_xdecref(arg.entry)
1969 def generate_arg_decref(self, arg, code):
1971 code.put_var_decref(arg.entry)
1973 def generate_stararg_copy_code(self, code):
1974 if not self.star_arg:
1975 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1976 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1978 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1979 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1982 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1984 if self.starstar_arg:
1986 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1988 kwarg_check = "%s" % Naming.kwds_cname
1990 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1991 Naming.kwds_cname, Naming.kwds_cname)
1993 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1994 kwarg_check, Naming.kwds_cname, self.name,
1995 bool(self.starstar_arg), self.error_value()))
1997 if self.starstar_arg:
1998 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1999 self.starstar_arg.entry.cname,
2002 code.putln("if (unlikely(!%s)) return %s;" % (
2003 self.starstar_arg.entry.cname, self.error_value()))
2004 self.starstar_arg.entry.xdecref_cleanup = 0
2005 code.put_gotref(self.starstar_arg.entry.cname)
2009 code.put_incref(Naming.args_cname, py_object_type)
2010 code.putln("%s = %s;" % (
2011 self.star_arg.entry.cname,
2013 self.star_arg.entry.xdecref_cleanup = 0
2015 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2016 kw_only_args, success_label, code):
2017 argtuple_error_label = code.new_label("argtuple_error")
2019 min_positional_args = self.num_required_args - self.num_required_kw_args
2020 if len(self.args) > 0 and self.args[0].is_self_arg:
2021 min_positional_args -= 1
2022 max_positional_args = len(positional_args)
2023 has_fixed_positional_count = not self.star_arg and \
2024 min_positional_args == max_positional_args
2026 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2027 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2028 if self.num_required_kw_args:
2029 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2031 if self.starstar_arg or self.star_arg:
2032 self.generate_stararg_init_code(max_positional_args, code)
2034 # --- optimised code when we receive keyword arguments
2035 if self.num_required_kw_args:
2036 likely_hint = "likely"
2038 likely_hint = "unlikely"
2039 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2040 self.generate_keyword_unpacking_code(
2041 min_positional_args, max_positional_args,
2042 has_fixed_positional_count,
2043 positional_args, kw_only_args, argtuple_error_label, code)
2045 # --- optimised code when we do not receive any keyword arguments
2046 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2047 # Python raises arg tuple related errors first, so we must
2048 # check the length here
2049 if min_positional_args == max_positional_args and not self.star_arg:
2053 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2054 Naming.args_cname, compare, min_positional_args))
2055 code.put_goto(argtuple_error_label)
2057 if self.num_required_kw_args:
2058 # pure error case: keywords required but not passed
2059 if max_positional_args > min_positional_args and not self.star_arg:
2060 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2061 Naming.args_cname, max_positional_args))
2062 code.put_goto(argtuple_error_label)
2063 code.putln('} else {')
2064 for i, arg in enumerate(kw_only_args):
2066 pystring_cname = code.intern_identifier(arg.name)
2067 # required keyword-only argument missing
2068 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2069 self.name.utf8encode(),
2071 code.putln(code.error_goto(self.pos))
2074 elif min_positional_args == max_positional_args:
2075 # parse the exact number of positional arguments from the
2077 code.putln('} else {')
2078 for i, arg in enumerate(positional_args):
2079 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2080 self.generate_arg_assignment(arg, item, code)
2081 self.generate_arg_default_assignments(code)
2084 # parse the positional arguments from the variable length
2086 code.putln('} else {')
2087 self.generate_arg_default_assignments(code)
2088 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2090 code.putln('default:')
2091 reversed_args = list(enumerate(positional_args))[::-1]
2092 for i, arg in reversed_args:
2093 if i >= min_positional_args-1:
2094 if min_positional_args > 1:
2095 code.putln('case %2d:' % (i+1)) # pure code beautification
2097 code.put('case %2d: ' % (i+1))
2098 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2099 self.generate_arg_assignment(arg, item, code)
2100 if min_positional_args == 0:
2101 code.put('case 0: ')
2102 code.putln('break;')
2104 if min_positional_args:
2105 for i in range(min_positional_args-1, -1, -1):
2106 code.putln('case %2d:' % i)
2107 code.put_goto(argtuple_error_label)
2109 code.put('default: ')
2110 code.put_goto(argtuple_error_label)
2115 if code.label_used(argtuple_error_label):
2116 code.put_goto(success_label)
2117 code.put_label(argtuple_error_label)
2118 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2119 self.name.utf8encode(), has_fixed_positional_count,
2120 min_positional_args, max_positional_args,
2122 code.putln(code.error_goto(self.pos))
2124 def generate_arg_default_assignments(self, code):
2125 for arg in self.args:
2126 if arg.is_generic and arg.default:
2130 arg.calculate_default_value_code(code)))
2132 def generate_stararg_init_code(self, max_positional_args, code):
2133 if self.starstar_arg:
2134 self.starstar_arg.entry.xdecref_cleanup = 0
2135 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2136 self.starstar_arg.entry.cname,
2137 self.starstar_arg.entry.cname,
2138 self.error_value()))
2139 code.put_gotref(self.starstar_arg.entry.cname)
2141 self.star_arg.entry.xdecref_cleanup = 0
2142 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2144 max_positional_args))
2145 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2146 self.star_arg.entry.cname, Naming.args_cname,
2147 max_positional_args, Naming.args_cname))
2148 code.put_gotref(self.star_arg.entry.cname)
2149 if self.starstar_arg:
2151 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2152 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2153 code.putln('return %s;' % self.error_value())
2156 code.putln("if (unlikely(!%s)) return %s;" % (
2157 self.star_arg.entry.cname, self.error_value()))
2158 code.putln('} else {')
2159 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2160 code.put_incref(Naming.empty_tuple, py_object_type)
2163 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2164 has_fixed_positional_count, positional_args,
2165 kw_only_args, argtuple_error_label, code):
2166 all_args = tuple(positional_args) + tuple(kw_only_args)
2167 max_args = len(all_args)
2170 for i, arg in enumerate(all_args):
2171 if arg.default and arg.type.is_pyobject:
2172 default_value = arg.calculate_default_value_code(code)
2173 if arg.type is not PyrexTypes.py_object_type:
2174 default_value = "(PyObject*)"+default_value
2175 default_args.append((i, default_value))
2177 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2179 # it looks funny to separate the init-to-0 from setting the
2180 # default value, but C89 needs this
2181 code.putln("PyObject* values[%d] = {%s};" % (
2182 max_args, ','.join(['0']*max_args)))
2183 for i, default_value in default_args:
2184 code.putln('values[%d] = %s;' % (i, default_value))
2186 # parse the tuple and check that it's not too long
2187 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2189 code.putln('default:')
2190 for i in range(max_positional_args-1, -1, -1):
2191 code.put('case %2d: ' % (i+1))
2192 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2193 i, Naming.args_cname, i))
2194 code.putln('case 0: break;')
2195 if not self.star_arg:
2196 code.put('default: ') # more arguments than allowed
2197 code.put_goto(argtuple_error_label)
2200 # now fill up the positional/required arguments with values
2202 if self.num_required_args or max_positional_args > 0:
2203 last_required_arg = -1
2204 for i, arg in enumerate(all_args):
2206 last_required_arg = i
2207 if last_required_arg < max_positional_args:
2208 last_required_arg = max_positional_args-1
2209 num_required_args = self.num_required_args
2210 if max_positional_args > 0:
2211 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2212 for i, arg in enumerate(all_args[:last_required_arg+1]):
2213 if max_positional_args > 0 and i <= max_positional_args:
2214 if self.star_arg and i == max_positional_args:
2215 code.putln('default:')
2217 code.putln('case %2d:' % i)
2218 pystring_cname = code.intern_identifier(arg.name)
2221 # handled separately below
2223 code.putln('if (kw_args > %d) {' % num_required_args)
2224 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2225 Naming.kwds_cname, pystring_cname))
2226 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2229 num_required_args -= 1
2230 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2231 i, Naming.kwds_cname, pystring_cname))
2232 code.putln('if (likely(values[%d])) kw_args--;' % i);
2233 if i < min_positional_args:
2235 # special case: we know arg 0 is missing
2237 code.put_goto(argtuple_error_label)
2239 # print the correct number of values (args or
2240 # kwargs) that were passed into positional
2241 # arguments up to this point
2242 code.putln('else {')
2243 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2244 self.name.utf8encode(), has_fixed_positional_count,
2245 min_positional_args, max_positional_args, i))
2246 code.putln(code.error_goto(self.pos))
2249 code.putln('else {')
2250 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2251 self.name.utf8encode(), pystring_cname))
2252 code.putln(code.error_goto(self.pos))
2254 if max_positional_args > 0:
2257 if kw_only_args and not self.starstar_arg:
2258 # unpack optional keyword-only arguments
2259 # checking for interned strings in a dict is faster than iterating
2260 # but it's too likely that we must iterate if we expect **kwargs
2262 for i, arg in enumerate(all_args[max_positional_args:]):
2263 if not arg.kw_only or not arg.default:
2265 optional_args.append((i+max_positional_args, arg))
2267 # this mimics an unrolled loop so that we can "break" out of it
2268 code.putln('while (kw_args > 0) {')
2269 code.putln('PyObject* value;')
2270 for i, arg in optional_args:
2271 pystring_cname = code.intern_identifier(arg.name)
2273 'value = PyDict_GetItem(%s, %s);' % (
2274 Naming.kwds_cname, pystring_cname))
2276 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2277 code.putln('break;')
2280 code.putln('if (unlikely(kw_args > 0)) {')
2281 # non-positional/-required kw args left in dict: default args,
2282 # kw-only args, **kwargs or error
2284 # This is sort of a catch-all: except for checking required
2285 # arguments, this will always do the right thing for unpacking
2286 # keyword arguments, so that we can concentrate on optimising
2287 # common cases above.
2288 if max_positional_args == 0:
2291 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2292 Naming.args_cname, max_positional_args,
2293 Naming.args_cname, max_positional_args))
2294 pos_arg_count = "used_pos_args"
2296 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2297 code.globalstate.use_utility_code(parse_keywords_utility_code)
2299 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2301 Naming.pykwdlist_cname,
2302 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2304 self.name.utf8encode()))
2305 code.putln(code.error_goto(self.pos))
2308 # convert arg values to their final type and assign them
2309 for i, arg in enumerate(all_args):
2310 if arg.default and not arg.type.is_pyobject:
2311 code.putln("if (values[%d]) {" % i)
2312 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2313 if arg.default and not arg.type.is_pyobject:
2314 code.putln('} else {')
2318 arg.calculate_default_value_code(code)))
2321 def generate_argument_conversion_code(self, code):
2322 # Generate code to convert arguments from
2323 # signature type to declared type, if needed.
2324 for arg in self.args:
2325 if arg.needs_conversion:
2326 self.generate_arg_conversion(arg, code)
2328 def generate_arg_conversion(self, arg, code):
2329 # Generate conversion code for one argument.
2330 old_type = arg.hdr_type
2332 if old_type.is_pyobject:
2334 code.putln("if (%s) {" % arg.hdr_cname)
2336 code.putln("assert(%s); {" % arg.hdr_cname)
2337 self.generate_arg_conversion_from_pyobject(arg, code)
2339 elif new_type.is_pyobject:
2340 self.generate_arg_conversion_to_pyobject(arg, code)
2342 if new_type.assignable_from(old_type):
2344 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2347 "Cannot convert 1 argument from '%s' to '%s'" %
2348 (old_type, new_type))
2350 def generate_arg_conversion_from_pyobject(self, arg, code):
2352 func = new_type.from_py_function
2353 # copied from CoerceFromPyTypeNode
2355 code.putln("%s = %s(%s); %s" % (
2359 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2362 "Cannot convert Python object argument to type '%s'"
2365 def generate_arg_conversion_to_pyobject(self, arg, code):
2366 old_type = arg.hdr_type
2367 func = old_type.to_py_function
2369 code.putln("%s = %s(%s); %s" % (
2373 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2374 code.put_var_gotref(arg.entry)
2377 "Cannot convert argument of type '%s' to Python object"
2380 def generate_argument_type_tests(self, code):
2381 # Generate type tests for args whose signature
2382 # type is PyObject * and whose declared type is
2383 # a subtype thereof.
2384 for arg in self.args:
2385 if arg.needs_type_test:
2386 self.generate_arg_type_test(arg, code)
2388 def generate_arg_type_test(self, arg, code):
2389 # Generate type test for one argument.
2390 if arg.type.typeobj_is_available():
2391 typeptr_cname = arg.type.typeptr_cname
2392 arg_code = "((PyObject *)%s)" % arg.entry.cname
2394 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2399 arg.type.is_builtin_type,
2400 code.error_goto(arg.pos)))
2402 error(arg.pos, "Cannot test type of extern C class "
2403 "without type object name specification")
2405 def error_value(self):
2406 return self.entry.signature.error_value
2408 def caller_will_check_exceptions(self):
2411 class OverrideCheckNode(StatNode):
2412 # A Node for dispatching to the def method if it
2421 child_attrs = ['body']
2425 def analyse_expressions(self, env):
2426 self.args = env.arg_entries
2427 if self.py_func.is_module_scope:
2432 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2433 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2434 call_node = ExprNodes.SimpleCallNode(self.pos,
2435 function=self.func_node,
2436 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2437 self.body = ReturnStatNode(self.pos, value=call_node)
2438 self.body.analyse_expressions(env)
2440 def generate_execution_code(self, code):
2441 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2442 # Check to see if we are an extension type
2443 if self.py_func.is_module_scope:
2444 self_arg = "((PyObject *)%s)" % Naming.module_cname
2446 self_arg = "((PyObject *)%s)" % self.args[0].cname
2447 code.putln("/* Check if called by wrapper */")
2448 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2449 code.putln("/* Check if overriden in Python */")
2450 if self.py_func.is_module_scope:
2451 code.putln("else {")
2453 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2454 self.func_node.allocate(code)
2455 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2456 # need to get attribute manually--scope would return cdef method
2457 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2458 self.func_node.result(), self_arg, interned_attr_cname, err))
2459 code.put_gotref(self.func_node.py_result())
2460 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2461 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2462 self.func_node.result(), self.py_func.entry.func_cname)
2463 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2464 self.body.generate_execution_code(code)
2466 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2468 self.func_node.release(code)
2470 class ClassDefNode(StatNode, BlockNode):
2473 class PyClassDefNode(ClassDefNode):
2474 # A Python class definition.
2476 # name EncodedString Name of the class
2477 # doc string or None
2478 # body StatNode Attribute definition code
2479 # entry Symtab.Entry
2480 # scope PyClassScope
2482 # The following subnodes are constructed internally:
2484 # dict DictNode Class dictionary
2485 # classobj ClassNode Class object
2486 # target NameNode Variable to assign class object to
2488 child_attrs = ["body", "dict", "classobj", "target"]
2490 def __init__(self, pos, name, bases, doc, body):
2491 StatNode.__init__(self, pos)
2496 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2497 if self.doc and Options.docstrings:
2498 doc = embed_position(self.pos, self.doc)
2499 doc_node = ExprNodes.StringNode(pos, value = doc)
2502 self.classobj = ExprNodes.ClassNode(pos, name = name,
2503 bases = bases, dict = self.dict, doc = doc_node)
2504 self.target = ExprNodes.NameNode(pos, name = name)
2506 def as_cclass(self):
2508 Return this node as if it were declared as an extension class
2510 bases = self.classobj.bases.args
2512 base_class_name = None
2513 base_class_module = None
2514 elif len(bases) == 1:
2517 from ExprNodes import AttributeNode, NameNode
2518 while isinstance(base, AttributeNode):
2519 path.insert(0, base.attribute)
2521 if isinstance(base, NameNode):
2522 path.insert(0, base.name)
2523 base_class_name = path[-1]
2525 base_class_module = u'.'.join(path[:-1])
2527 base_class_module = None
2529 error(self.classobj.bases.args.pos, "Invalid base class")
2531 error(self.classobj.bases.args.pos, "C class may only have one base class")
2534 return CClassDefNode(self.pos,
2535 visibility = 'private',
2537 class_name = self.name,
2538 base_class_module = base_class_module,
2539 base_class_name = base_class_name,
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 # doc string or None
2597 # body StatNode or None
2598 # entry Symtab.Entry
2599 # base_type PyExtensionType or None
2600 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2601 # buffer_defaults_pos
2603 child_attrs = ["body"]
2604 buffer_defaults_node = None
2605 buffer_defaults_pos = None
2606 typedef_flag = False
2608 objstruct_name = None
2611 def analyse_declarations(self, env):
2612 #print "CClassDefNode.analyse_declarations:", self.class_name
2613 #print "...visibility =", self.visibility
2614 #print "...module_name =", self.module_name
2617 if self.buffer_defaults_node:
2618 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2619 env, [], self.buffer_defaults_node,
2620 need_complete=False)
2622 buffer_defaults = None
2624 if env.in_cinclude and not self.objstruct_name:
2625 error(self.pos, "Object struct name specification required for "
2626 "C class defined in 'extern from' block")
2627 self.base_type = None
2628 # Now that module imports are cached, we need to
2629 # import the modules for extern classes.
2630 if self.module_name:
2632 for module in env.cimported_modules:
2633 if module.name == self.module_name:
2634 self.module = module
2635 if self.module is None:
2636 self.module = ModuleScope(self.module_name, None, env.context)
2637 self.module.has_extern_class = 1
2638 env.add_imported_module(self.module)
2640 if self.base_class_name:
2641 if self.base_class_module:
2642 base_class_scope = env.find_module(self.base_class_module, self.pos)
2644 base_class_scope = env
2645 if self.base_class_name == 'object':
2646 # extension classes are special and don't need to inherit from object
2647 if base_class_scope is None or base_class_scope.lookup('object') is None:
2648 self.base_class_name = None
2649 self.base_class_module = None
2650 base_class_scope = None
2651 if base_class_scope:
2652 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2653 if base_class_entry:
2654 if not base_class_entry.is_type:
2655 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2656 elif not base_class_entry.type.is_extension_type:
2657 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2658 elif not base_class_entry.type.is_complete():
2659 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2661 self.base_type = base_class_entry.type
2662 has_body = self.body is not None
2663 if self.module_name and self.visibility != 'extern':
2664 module_path = self.module_name.split(".")
2665 home_scope = env.find_imported_module(module_path, self.pos)
2671 if self.visibility == 'extern':
2672 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2673 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2675 self.entry = home_scope.declare_c_class(
2676 name = self.class_name,
2678 defining = has_body and self.in_pxd,
2679 implementing = has_body and not self.in_pxd,
2680 module_name = self.module_name,
2681 base_type = self.base_type,
2682 objstruct_cname = self.objstruct_name,
2683 typeobj_cname = self.typeobj_name,
2684 visibility = self.visibility,
2685 typedef_flag = self.typedef_flag,
2687 buffer_defaults = buffer_defaults)
2688 if home_scope is not env and self.visibility == 'extern':
2689 env.add_imported_entry(self.class_name, self.entry, pos)
2690 scope = self.entry.type.scope
2691 if scope is not None:
2692 scope.directives = env.directives
2694 if self.doc and Options.docstrings:
2695 scope.doc = embed_position(self.pos, self.doc)
2698 self.body.analyse_declarations(scope)
2702 scope.implemented = 1
2703 env.allocate_vtable_names(self.entry)
2705 def analyse_expressions(self, env):
2707 scope = self.entry.type.scope
2708 self.body.analyse_expressions(scope)
2710 def generate_function_definitions(self, env, code):
2712 self.body.generate_function_definitions(
2713 self.entry.type.scope, code)
2715 def generate_execution_code(self, code):
2716 # This is needed to generate evaluation code for
2717 # default values of method arguments.
2719 self.body.generate_execution_code(code)
2721 def annotate(self, code):
2723 self.body.annotate(code)
2726 class PropertyNode(StatNode):
2727 # Definition of a property in an extension type.
2730 # doc EncodedString or None Doc string
2733 child_attrs = ["body"]
2735 def analyse_declarations(self, env):
2736 entry = env.declare_property(self.name, self.doc, self.pos)
2738 entry.scope.directives = env.directives
2739 self.body.analyse_declarations(entry.scope)
2741 def analyse_expressions(self, env):
2742 self.body.analyse_expressions(env)
2744 def generate_function_definitions(self, env, code):
2745 self.body.generate_function_definitions(env, code)
2747 def generate_execution_code(self, code):
2750 def annotate(self, code):
2751 self.body.annotate(code)
2754 class GlobalNode(StatNode):
2755 # Global variable declaration.
2761 def analyse_declarations(self, env):
2762 for name in self.names:
2763 env.declare_global(name, self.pos)
2765 def analyse_expressions(self, env):
2768 def generate_execution_code(self, code):
2772 class ExprStatNode(StatNode):
2773 # Expression used as a statement.
2777 child_attrs = ["expr"]
2779 def analyse_declarations(self, env):
2781 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2782 func = self.expr.function.as_cython_attribute()
2783 if func == u'declare':
2784 args, kwds = self.expr.explicit_args_kwds()
2786 error(self.expr.pos, "Variable names must be specified.")
2787 for var, type_node in kwds.key_value_pairs:
2788 type = type_node.analyse_as_type(env)
2790 error(type_node.pos, "Unknown type")
2792 env.declare_var(var.value, type, var.pos, is_cdef = True)
2793 self.__class__ = PassStatNode
2795 def analyse_expressions(self, env):
2796 self.expr.analyse_expressions(env)
2798 def generate_execution_code(self, code):
2799 self.expr.generate_evaluation_code(code)
2800 if not self.expr.is_temp and self.expr.result():
2801 code.putln("%s;" % self.expr.result())
2802 self.expr.generate_disposal_code(code)
2803 self.expr.free_temps(code)
2805 def annotate(self, code):
2806 self.expr.annotate(code)
2809 class AssignmentNode(StatNode):
2810 # Abstract base class for assignment nodes.
2812 # The analyse_expressions and generate_execution_code
2813 # phases of assignments are split into two sub-phases
2814 # each, to enable all the right hand sides of a
2815 # parallel assignment to be evaluated before assigning
2816 # to any of the left hand sides.
2818 def analyse_expressions(self, env):
2819 self.analyse_types(env)
2821 # def analyse_expressions(self, env):
2822 # self.analyse_expressions_1(env)
2823 # self.analyse_expressions_2(env)
2825 def generate_execution_code(self, code):
2826 self.generate_rhs_evaluation_code(code)
2827 self.generate_assignment_code(code)
2830 class SingleAssignmentNode(AssignmentNode):
2831 # The simplest case:
2835 # lhs ExprNode Left hand side
2836 # rhs ExprNode Right hand side
2837 # first bool Is this guaranteed the first assignment to lhs?
2839 child_attrs = ["lhs", "rhs"]
2841 declaration_only = False
2843 def analyse_declarations(self, env):
2846 # handle declarations of the form x = cython.foo()
2847 if isinstance(self.rhs, ExprNodes.CallNode):
2848 func_name = self.rhs.function.as_cython_attribute()
2850 args, kwds = self.rhs.explicit_args_kwds()
2852 if func_name in ['declare', 'typedef']:
2853 if len(args) > 2 or kwds is not None:
2854 error(rhs.pos, "Can only declare one type at a time.")
2856 type = args[0].analyse_as_type(env)
2858 error(args[0].pos, "Unknown type")
2861 if func_name == 'declare':
2862 if isinstance(lhs, ExprNodes.NameNode):
2863 vars = [(lhs.name, lhs.pos)]
2864 elif isinstance(lhs, ExprNodes.TupleNode):
2865 vars = [(var.name, var.pos) for var in lhs.args]
2867 error(lhs.pos, "Invalid declaration")
2869 for var, pos in vars:
2870 env.declare_var(var, type, pos, is_cdef = True)
2875 self.declaration_only = True
2877 self.declaration_only = True
2878 if not isinstance(lhs, ExprNodes.NameNode):
2879 error(lhs.pos, "Invalid declaration.")
2880 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2882 elif func_name in ['struct', 'union']:
2883 self.declaration_only = True
2884 if len(args) > 0 or kwds is None:
2885 error(rhs.pos, "Struct or union members must be given by name.")
2888 for member, type_node in kwds.key_value_pairs:
2889 type = type_node.analyse_as_type(env)
2891 error(type_node.pos, "Unknown type")
2893 members.append((member.value, type, member.pos))
2894 if len(members) < len(kwds.key_value_pairs):
2896 if not isinstance(self.lhs, ExprNodes.NameNode):
2897 error(self.lhs.pos, "Invalid declaration.")
2898 name = self.lhs.name
2899 scope = StructOrUnionScope(name)
2900 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2901 for member, type, pos in members:
2902 scope.declare_var(member, type, pos)
2904 if self.declaration_only:
2907 self.lhs.analyse_target_declaration(env)
2909 def analyse_types(self, env, use_temp = 0):
2910 self.rhs.analyse_types(env)
2911 self.lhs.analyse_target_types(env)
2912 self.lhs.gil_assignment_check(env)
2913 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2915 self.rhs = self.rhs.coerce_to_temp(env)
2917 def generate_rhs_evaluation_code(self, code):
2918 self.rhs.generate_evaluation_code(code)
2920 def generate_assignment_code(self, code):
2921 self.lhs.generate_assignment_code(self.rhs, code)
2923 def annotate(self, code):
2924 self.lhs.annotate(code)
2925 self.rhs.annotate(code)
2928 class CascadedAssignmentNode(AssignmentNode):
2929 # An assignment with multiple left hand sides:
2933 # lhs_list [ExprNode] Left hand sides
2934 # rhs ExprNode Right hand sides
2938 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2940 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2941 coerced_rhs_list = None
2943 def analyse_declarations(self, env):
2944 for lhs in self.lhs_list:
2945 lhs.analyse_target_declaration(env)
2947 def analyse_types(self, env, use_temp = 0):
2948 self.rhs.analyse_types(env)
2950 self.rhs = self.rhs.coerce_to_temp(env)
2952 self.rhs = self.rhs.coerce_to_simple(env)
2953 from ExprNodes import CloneNode
2954 self.coerced_rhs_list = []
2955 for lhs in self.lhs_list:
2956 lhs.analyse_target_types(env)
2957 lhs.gil_assignment_check(env)
2958 rhs = CloneNode(self.rhs)
2959 rhs = rhs.coerce_to(lhs.type, env)
2960 self.coerced_rhs_list.append(rhs)
2962 def generate_rhs_evaluation_code(self, code):
2963 self.rhs.generate_evaluation_code(code)
2965 def generate_assignment_code(self, code):
2966 for i in range(len(self.lhs_list)):
2967 lhs = self.lhs_list[i]
2968 rhs = self.coerced_rhs_list[i]
2969 rhs.generate_evaluation_code(code)
2970 lhs.generate_assignment_code(rhs, code)
2971 # Assignment has disposed of the cloned RHS
2972 self.rhs.generate_disposal_code(code)
2973 self.rhs.free_temps(code)
2975 def annotate(self, code):
2976 for i in range(len(self.lhs_list)):
2977 lhs = self.lhs_list[i].annotate(code)
2978 rhs = self.coerced_rhs_list[i].annotate(code)
2979 self.rhs.annotate(code)
2982 class ParallelAssignmentNode(AssignmentNode):
2983 # A combined packing/unpacking assignment:
2987 # This has been rearranged by the parser into
2989 # a = d ; b = e ; c = f
2991 # but we must evaluate all the right hand sides
2992 # before assigning to any of the left hand sides.
2994 # stats [AssignmentNode] The constituent assignments
2996 child_attrs = ["stats"]
2998 def analyse_declarations(self, env):
2999 for stat in self.stats:
3000 stat.analyse_declarations(env)
3002 def analyse_expressions(self, env):
3003 for stat in self.stats:
3004 stat.analyse_types(env, use_temp = 1)
3006 # def analyse_expressions(self, env):
3007 # for stat in self.stats:
3008 # stat.analyse_expressions_1(env, use_temp = 1)
3009 # for stat in self.stats:
3010 # stat.analyse_expressions_2(env)
3012 def generate_execution_code(self, code):
3013 for stat in self.stats:
3014 stat.generate_rhs_evaluation_code(code)
3015 for stat in self.stats:
3016 stat.generate_assignment_code(code)
3018 def annotate(self, code):
3019 for stat in self.stats:
3023 class InPlaceAssignmentNode(AssignmentNode):
3024 # An in place arithmatic operand:
3030 # lhs ExprNode Left hand side
3031 # rhs ExprNode Right hand side
3032 # op char one of "+-*/%^&|"
3033 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3035 # This code is a bit tricky because in order to obey Python
3036 # semantics the sub-expressions (e.g. indices) of the lhs must
3037 # not be evaluated twice. So we must re-use the values calculated
3038 # in evaluation phase for the assignment phase as well.
3039 # Fortunately, the type of the lhs node is fairly constrained
3040 # (it must be a NameNode, AttributeNode, or IndexNode).
3042 child_attrs = ["lhs", "rhs"]
3045 def analyse_declarations(self, env):
3046 self.lhs.analyse_target_declaration(env)
3048 def analyse_types(self, env):
3049 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3050 self.rhs.analyse_types(env)
3051 self.lhs.analyse_target_types(env)
3052 if Options.incref_local_binop and self.dup.type.is_pyobject:
3053 self.dup = self.dup.coerce_to_temp(env)
3055 if self.lhs.type.is_pyobject:
3056 self.rhs = self.rhs.coerce_to_pyobject(env)
3057 elif self.rhs.type.is_pyobject:
3058 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3059 if self.lhs.type.is_pyobject:
3060 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3061 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3063 def generate_execution_code(self, code):
3065 self.rhs.generate_evaluation_code(code)
3066 self.dup.generate_subexpr_evaluation_code(code)
3067 if self.dup.is_temp:
3068 self.dup.allocate_temp_result(code)
3069 # self.dup.generate_result_code is run only if it is not buffer access
3070 if self.operator == "**":
3074 if self.lhs.type.is_pyobject:
3075 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3076 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3077 self.dup.generate_result_code(code)
3078 self.result_value_temp.allocate(code)
3080 "%s = %s(%s, %s%s); %s" % (
3081 self.result_value.result(),
3082 self.py_operation_function(),
3083 self.dup.py_result(),
3084 self.rhs.py_result(),
3086 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3087 code.put_gotref(self.result_value.py_result())
3088 self.result_value.generate_evaluation_code(code) # May be a type check...
3089 self.rhs.generate_disposal_code(code)
3090 self.rhs.free_temps(code)
3091 self.dup.generate_disposal_code(code)
3092 self.dup.free_temps(code)
3093 self.lhs.generate_assignment_code(self.result_value, code)
3094 self.result_value_temp.release(code)
3096 c_op = self.operator
3100 error(self.pos, "No C inplace power operator")
3101 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3102 error(self.pos, "Inplace operators not implemented for complex types.")
3104 # have to do assignment directly to avoid side-effects
3105 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3106 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3108 self.dup.generate_result_code(code)
3109 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3110 self.rhs.generate_disposal_code(code)
3111 self.rhs.free_temps(code)
3112 if self.dup.is_temp:
3113 self.dup.generate_subexpr_disposal_code(code)
3114 self.dup.free_subexpr_temps(code)
3116 def create_dup_node(self, env):
3119 self.dup.analyse_types(env)
3120 if isinstance(self.lhs, ExprNodes.NameNode):
3121 target_lhs = ExprNodes.NameNode(self.dup.pos,
3122 name = self.dup.name,
3123 is_temp = self.dup.is_temp,
3124 entry = self.dup.entry)
3125 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3126 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3127 obj = ExprNodes.CloneNode(self.lhs.obj),
3128 attribute = self.dup.attribute,
3129 is_temp = self.dup.is_temp)
3130 elif isinstance(self.lhs, ExprNodes.IndexNode):
3132 index = ExprNodes.CloneNode(self.lhs.index)
3135 if self.lhs.indices:
3136 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3139 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3140 base = ExprNodes.CloneNode(self.dup.base),
3143 is_temp = self.dup.is_temp)
3146 self.lhs = target_lhs
3149 def py_operation_function(self):
3150 return self.py_functions[self.operator]
3153 "|": "PyNumber_InPlaceOr",
3154 "^": "PyNumber_InPlaceXor",
3155 "&": "PyNumber_InPlaceAnd",
3156 "+": "PyNumber_InPlaceAdd",
3157 "-": "PyNumber_InPlaceSubtract",
3158 "*": "PyNumber_InPlaceMultiply",
3159 "/": "PyNumber_InPlaceDivide",
3160 "%": "PyNumber_InPlaceRemainder",
3161 "<<": "PyNumber_InPlaceLshift",
3162 ">>": "PyNumber_InPlaceRshift",
3163 "**": "PyNumber_InPlacePower",
3164 "//": "PyNumber_InPlaceFloorDivide",
3167 def annotate(self, code):
3168 self.lhs.annotate(code)
3169 self.rhs.annotate(code)
3170 self.dup.annotate(code)
3173 class PrintStatNode(StatNode):
3176 # arg_tuple TupleNode
3177 # append_newline boolean
3179 child_attrs = ["arg_tuple"]
3181 def analyse_expressions(self, env):
3182 self.arg_tuple.analyse_expressions(env)
3183 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3184 env.use_utility_code(printing_utility_code)
3185 if len(self.arg_tuple.args) == 1 and self.append_newline:
3186 env.use_utility_code(printing_one_utility_code)
3188 gil_check = StatNode._gil_check
3189 gil_message = "Python print statement"
3191 def generate_execution_code(self, code):
3192 if len(self.arg_tuple.args) == 1 and self.append_newline:
3193 arg = self.arg_tuple.args[0]
3194 arg.generate_evaluation_code(code)
3197 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3199 code.error_goto(self.pos)))
3200 arg.generate_disposal_code(code)
3201 arg.free_temps(code)
3203 self.arg_tuple.generate_evaluation_code(code)
3205 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3206 self.arg_tuple.py_result(),
3207 self.append_newline,
3208 code.error_goto(self.pos)))
3209 self.arg_tuple.generate_disposal_code(code)
3210 self.arg_tuple.free_temps(code)
3212 def annotate(self, code):
3213 self.arg_tuple.annotate(code)
3216 class ExecStatNode(StatNode):
3221 child_attrs = ["args"]
3223 def analyse_expressions(self, env):
3224 for i, arg in enumerate(self.args):
3225 arg.analyse_expressions(env)
3226 arg = arg.coerce_to_pyobject(env)
3228 env.use_utility_code(Builtin.pyexec_utility_code)
3230 gil_check = StatNode._gil_check
3231 gil_message = "Python exec statement"
3233 def generate_execution_code(self, code):
3235 for arg in self.args:
3236 arg.generate_evaluation_code(code)
3237 args.append( arg.py_result() )
3238 args = tuple(args + ['0', '0'][:3-len(args)])
3239 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3240 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3241 (temp_result,) + args))
3242 for arg in self.args:
3243 arg.generate_disposal_code(code)
3244 arg.free_temps(code)
3246 code.error_goto_if_null(temp_result, self.pos))
3247 code.put_gotref(temp_result)
3248 code.put_decref_clear(temp_result, py_object_type)
3249 code.funcstate.release_temp(temp_result)
3251 def annotate(self, code):
3252 for arg in self.args:
3256 class DelStatNode(StatNode):
3261 child_attrs = ["args"]
3263 def analyse_declarations(self, env):
3264 for arg in self.args:
3265 arg.analyse_target_declaration(env)
3267 def analyse_expressions(self, env):
3268 for arg in self.args:
3269 arg.analyse_target_expression(env, None)
3270 if not arg.type.is_pyobject:
3271 error(arg.pos, "Deletion of non-Python object")
3272 #arg.release_target_temp(env)
3274 def gil_check(self, env):
3275 for arg in self.args:
3276 if arg.type.is_pyobject:
3277 self._gil_check(env)
3279 gil_message = "Deleting Python object"
3281 def generate_execution_code(self, code):
3282 for arg in self.args:
3283 if arg.type.is_pyobject:
3284 arg.generate_deletion_code(code)
3285 # else error reported earlier
3287 def annotate(self, code):
3288 for arg in self.args:
3292 class PassStatNode(StatNode):
3297 def analyse_expressions(self, env):
3300 def generate_execution_code(self, code):
3304 class BreakStatNode(StatNode):
3308 def analyse_expressions(self, env):
3311 def generate_execution_code(self, code):
3312 if not code.break_label:
3313 error(self.pos, "break statement not inside loop")
3315 code.put_goto(code.break_label)
3318 class ContinueStatNode(StatNode):
3322 def analyse_expressions(self, env):
3325 def generate_execution_code(self, code):
3326 if code.funcstate.in_try_finally:
3327 error(self.pos, "continue statement inside try of try...finally")
3328 elif not code.continue_label:
3329 error(self.pos, "continue statement not inside loop")
3331 code.put_goto(code.continue_label)
3334 class ReturnStatNode(StatNode):
3337 # value ExprNode or None
3338 # return_type PyrexType
3340 child_attrs = ["value"]
3342 def analyse_expressions(self, env):
3343 return_type = env.return_type
3344 self.return_type = return_type
3346 error(self.pos, "Return not inside a function body")
3349 self.value.analyse_types(env)
3350 if return_type.is_void or return_type.is_returncode:
3351 error(self.value.pos,
3352 "Return with value in void function")
3354 self.value = self.value.coerce_to(env.return_type, env)
3356 if (not return_type.is_void
3357 and not return_type.is_pyobject
3358 and not return_type.is_returncode):
3359 error(self.pos, "Return value required")
3361 def gil_check(self, env):
3362 if self.return_type.is_pyobject:
3363 self._gil_check(env)
3365 gil_message = "Returning Python object"
3367 def generate_execution_code(self, code):
3368 code.mark_pos(self.pos)
3369 if not self.return_type:
3370 # error reported earlier
3372 if self.return_type.is_pyobject:
3373 code.put_xdecref(Naming.retval_cname,
3376 self.value.generate_evaluation_code(code)
3377 self.value.make_owned_reference(code)
3380 Naming.retval_cname,
3381 self.value.result_as(self.return_type)))
3382 self.value.generate_post_assignment_code(code)
3383 self.value.free_temps(code)
3385 if self.return_type.is_pyobject:
3386 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3387 elif self.return_type.is_returncode:
3390 Naming.retval_cname,
3391 self.return_type.default_value))
3392 for cname, type in code.funcstate.temps_holding_reference():
3393 code.put_decref_clear(cname, type)
3394 code.put_goto(code.return_label)
3396 def annotate(self, code):
3398 self.value.annotate(code)
3401 class RaiseStatNode(StatNode):
3404 # exc_type ExprNode or None
3405 # exc_value ExprNode or None
3406 # exc_tb ExprNode or None
3408 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3410 def analyse_expressions(self, env):
3412 self.exc_type.analyse_types(env)
3413 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3415 self.exc_value.analyse_types(env)
3416 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3418 self.exc_tb.analyse_types(env)
3419 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3420 env.use_utility_code(raise_utility_code)
3421 env.use_utility_code(restore_exception_utility_code)
3423 gil_check = StatNode._gil_check
3424 gil_message = "Raising exception"
3426 def generate_execution_code(self, code):
3428 self.exc_type.generate_evaluation_code(code)
3429 type_code = self.exc_type.py_result()
3433 self.exc_value.generate_evaluation_code(code)
3434 value_code = self.exc_value.py_result()
3438 self.exc_tb.generate_evaluation_code(code)
3439 tb_code = self.exc_tb.py_result()
3442 if self.exc_type or self.exc_value or self.exc_tb:
3444 "__Pyx_Raise(%s, %s, %s);" % (
3451 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3453 obj.generate_disposal_code(code)
3454 obj.free_temps(code)
3456 code.error_goto(self.pos))
3458 def annotate(self, code):
3460 self.exc_type.annotate(code)
3462 self.exc_value.annotate(code)
3464 self.exc_tb.annotate(code)
3467 class ReraiseStatNode(StatNode):
3471 def analyse_expressions(self, env):
3472 env.use_utility_code(raise_utility_code)
3473 env.use_utility_code(restore_exception_utility_code)
3475 gil_check = StatNode._gil_check
3476 gil_message = "Raising exception"
3478 def generate_execution_code(self, code):
3479 vars = code.funcstate.exc_vars
3481 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3482 code.putln(code.error_goto(self.pos))
3484 error(self.pos, "Reraise not inside except clause")
3487 class AssertStatNode(StatNode):
3491 # value ExprNode or None
3493 child_attrs = ["cond", "value"]
3495 def analyse_expressions(self, env):
3496 self.cond = self.cond.analyse_boolean_expression(env)
3498 self.value.analyse_types(env)
3499 self.value = self.value.coerce_to_pyobject(env)
3501 gil_check = StatNode._gil_check
3502 gil_message = "Raising exception"
3504 def generate_execution_code(self, code):
3505 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3506 self.cond.generate_evaluation_code(code)
3508 "if (unlikely(!%s)) {" %
3511 self.value.generate_evaluation_code(code)
3513 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3514 self.value.py_result())
3515 self.value.generate_disposal_code(code)
3516 self.value.free_temps(code)
3519 "PyErr_SetNone(PyExc_AssertionError);")
3521 code.error_goto(self.pos))
3524 self.cond.generate_disposal_code(code)
3525 self.cond.free_temps(code)
3526 code.putln("#endif")
3528 def annotate(self, code):
3529 self.cond.annotate(code)
3531 self.value.annotate(code)
3534 class IfStatNode(StatNode):
3537 # if_clauses [IfClauseNode]
3538 # else_clause StatNode or None
3540 child_attrs = ["if_clauses", "else_clause"]
3542 def analyse_control_flow(self, env):
3543 env.start_branching(self.pos)
3544 for if_clause in self.if_clauses:
3545 if_clause.analyse_control_flow(env)
3546 env.next_branch(if_clause.end_pos())
3547 if self.else_clause:
3548 self.else_clause.analyse_control_flow(env)
3549 env.finish_branching(self.end_pos())
3551 def analyse_declarations(self, env):
3552 for if_clause in self.if_clauses:
3553 if_clause.analyse_declarations(env)
3554 if self.else_clause:
3555 self.else_clause.analyse_declarations(env)
3557 def analyse_expressions(self, env):
3558 for if_clause in self.if_clauses:
3559 if_clause.analyse_expressions(env)
3560 if self.else_clause:
3561 self.else_clause.analyse_expressions(env)
3563 def generate_execution_code(self, code):
3564 code.mark_pos(self.pos)
3565 end_label = code.new_label()
3566 for if_clause in self.if_clauses:
3567 if_clause.generate_execution_code(code, end_label)
3568 if self.else_clause:
3569 code.putln("/*else*/ {")
3570 self.else_clause.generate_execution_code(code)
3572 code.put_label(end_label)
3574 def annotate(self, code):
3575 for if_clause in self.if_clauses:
3576 if_clause.annotate(code)
3577 if self.else_clause:
3578 self.else_clause.annotate(code)
3581 class IfClauseNode(Node):
3582 # if or elif clause in an if statement
3584 # condition ExprNode
3587 child_attrs = ["condition", "body"]
3589 def analyse_control_flow(self, env):
3590 self.body.analyse_control_flow(env)
3592 def analyse_declarations(self, env):
3593 self.condition.analyse_declarations(env)
3594 self.body.analyse_declarations(env)
3596 def analyse_expressions(self, env):
3598 self.condition.analyse_temp_boolean_expression(env)
3599 self.body.analyse_expressions(env)
3601 def generate_execution_code(self, code, end_label):
3602 self.condition.generate_evaluation_code(code)
3605 self.condition.result())
3606 self.condition.generate_disposal_code(code)
3607 self.condition.free_temps(code)
3608 self.body.generate_execution_code(code)
3612 code.put_goto(end_label)
3615 def annotate(self, code):
3616 self.condition.annotate(code)
3617 self.body.annotate(code)
3620 class SwitchCaseNode(StatNode):
3621 # Generated in the optimization of an if-elif-else node
3623 # conditions [ExprNode]
3626 child_attrs = ['conditions', 'body']
3628 def generate_execution_code(self, code):
3629 for cond in self.conditions:
3630 code.mark_pos(cond.pos)
3631 cond.generate_evaluation_code(code)
3632 code.putln("case %s:" % cond.result())
3633 self.body.generate_execution_code(code)
3634 code.putln("break;")
3636 def annotate(self, code):
3637 for cond in self.conditions:
3639 self.body.annotate(code)
3641 class SwitchStatNode(StatNode):
3642 # Generated in the optimization of an if-elif-else node
3645 # cases [SwitchCaseNode]
3646 # else_clause StatNode or None
3648 child_attrs = ['test', 'cases', 'else_clause']
3650 def generate_execution_code(self, code):
3651 code.putln("switch (%s) {" % self.test.result())
3652 for case in self.cases:
3653 case.generate_execution_code(code)
3654 if self.else_clause is not None:
3655 code.putln("default:")
3656 self.else_clause.generate_execution_code(code)
3657 code.putln("break;")
3660 def annotate(self, code):
3661 self.test.annotate(code)
3662 for case in self.cases:
3664 if self.else_clause is not None:
3665 self.else_clause.annotate(code)
3667 class LoopNode(object):
3669 def analyse_control_flow(self, env):
3670 env.start_branching(self.pos)
3671 self.body.analyse_control_flow(env)
3672 env.next_branch(self.body.end_pos())
3673 if self.else_clause:
3674 self.else_clause.analyse_control_flow(env)
3675 env.finish_branching(self.end_pos())
3678 class WhileStatNode(LoopNode, StatNode):
3681 # condition ExprNode
3683 # else_clause StatNode
3685 child_attrs = ["condition", "body", "else_clause"]
3687 def analyse_declarations(self, env):
3688 self.body.analyse_declarations(env)
3689 if self.else_clause:
3690 self.else_clause.analyse_declarations(env)
3692 def analyse_expressions(self, env):
3694 self.condition.analyse_temp_boolean_expression(env)
3695 self.body.analyse_expressions(env)
3696 if self.else_clause:
3697 self.else_clause.analyse_expressions(env)
3699 def generate_execution_code(self, code):
3700 old_loop_labels = code.new_loop_labels()
3703 self.condition.generate_evaluation_code(code)
3704 self.condition.generate_disposal_code(code)
3707 self.condition.result())
3708 self.condition.free_temps(code)
3709 self.body.generate_execution_code(code)
3710 code.put_label(code.continue_label)
3712 break_label = code.break_label
3713 code.set_loop_labels(old_loop_labels)
3714 if self.else_clause:
3715 code.putln("/*else*/ {")
3716 self.else_clause.generate_execution_code(code)
3718 code.put_label(break_label)
3720 def annotate(self, code):
3721 self.condition.annotate(code)
3722 self.body.annotate(code)
3723 if self.else_clause:
3724 self.else_clause.annotate(code)
3727 def ForStatNode(pos, **kw):
3728 if 'iterator' in kw:
3729 return ForInStatNode(pos, **kw)
3731 return ForFromStatNode(pos, **kw)
3733 class ForInStatNode(LoopNode, StatNode):
3737 # iterator IteratorNode
3739 # else_clause StatNode
3740 # item NextNode used internally
3742 child_attrs = ["target", "iterator", "body", "else_clause"]
3745 def analyse_declarations(self, env):
3746 self.target.analyse_target_declaration(env)
3747 self.body.analyse_declarations(env)
3748 if self.else_clause:
3749 self.else_clause.analyse_declarations(env)
3751 def analyse_expressions(self, env):
3753 self.target.analyse_target_types(env)
3754 self.iterator.analyse_expressions(env)
3755 self.item = ExprNodes.NextNode(self.iterator, env)
3756 self.item = self.item.coerce_to(self.target.type, env)
3757 self.body.analyse_expressions(env)
3758 if self.else_clause:
3759 self.else_clause.analyse_expressions(env)
3761 def generate_execution_code(self, code):
3762 old_loop_labels = code.new_loop_labels()
3763 self.iterator.allocate_counter_temp(code)
3764 self.iterator.generate_evaluation_code(code)
3767 self.item.generate_evaluation_code(code)
3768 self.target.generate_assignment_code(self.item, code)
3769 self.body.generate_execution_code(code)
3770 code.put_label(code.continue_label)
3773 break_label = code.break_label
3774 code.set_loop_labels(old_loop_labels)
3775 if self.else_clause:
3776 code.putln("/*else*/ {")
3777 self.else_clause.generate_execution_code(code)
3779 code.put_label(break_label)
3780 self.iterator.release_counter_temp(code)
3781 self.iterator.generate_disposal_code(code)
3782 self.iterator.free_temps(code)
3784 def annotate(self, code):
3785 self.target.annotate(code)
3786 self.iterator.annotate(code)
3787 self.body.annotate(code)
3788 if self.else_clause:
3789 self.else_clause.annotate(code)
3790 self.item.annotate(code)
3793 class ForFromStatNode(LoopNode, StatNode):
3794 # for name from expr rel name rel expr
3801 # step ExprNode or None
3803 # else_clause StatNode or None
3809 # loopvar_node ExprNode (usually a NameNode or temp node)
3810 # py_loopvar_node PyTempNode or None
3811 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3813 is_py_target = False
3815 py_loopvar_node = None
3818 def analyse_declarations(self, env):
3819 self.target.analyse_target_declaration(env)
3820 self.body.analyse_declarations(env)
3821 if self.else_clause:
3822 self.else_clause.analyse_declarations(env)
3824 def analyse_expressions(self, env):
3826 self.target.analyse_target_types(env)
3827 self.bound1.analyse_types(env)
3828 self.bound2.analyse_types(env)
3829 if self.step is not None:
3830 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3831 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3832 self.step.analyse_types(env)
3834 target_type = self.target.type
3835 if self.target.type.is_numeric:
3836 loop_type = self.target.type
3838 loop_type = PyrexTypes.c_int_type
3839 if not self.bound1.type.is_pyobject:
3840 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3841 if not self.bound2.type.is_pyobject:
3842 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3843 if self.step is not None and not self.step.type.is_pyobject:
3844 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3845 self.bound1 = self.bound1.coerce_to(loop_type, env)
3846 self.bound2 = self.bound2.coerce_to(loop_type, env)
3847 if not self.bound2.is_literal:
3848 self.bound2 = self.bound2.coerce_to_temp(env)
3849 if self.step is not None:
3850 self.step = self.step.coerce_to(loop_type, env)
3851 if not self.step.is_literal:
3852 self.step = self.step.coerce_to_temp(env)
3854 target_type = self.target.type
3855 if not (target_type.is_pyobject or target_type.is_numeric):
3856 error(self.target.pos,
3857 "for-from loop variable must be c numeric type or Python object")
3858 if target_type.is_numeric:
3859 self.is_py_target = False
3860 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3861 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3862 self.loopvar_node = self.target
3863 self.py_loopvar_node = None
3865 self.is_py_target = True
3866 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3867 self.loopvar_node = c_loopvar_node
3868 self.py_loopvar_node = \
3869 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3870 self.body.analyse_expressions(env)
3871 if self.else_clause:
3872 self.else_clause.analyse_expressions(env)
3874 def generate_execution_code(self, code):
3875 old_loop_labels = code.new_loop_labels()
3876 from_range = self.from_range
3877 self.bound1.generate_evaluation_code(code)
3878 self.bound2.generate_evaluation_code(code)
3879 offset, incop = self.relation_table[self.relation1]
3880 if self.step is not None:
3881 self.step.generate_evaluation_code(code)
3882 step = self.step.result()
3883 incop = "%s=%s" % (incop[0], step)
3885 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3886 self.loopvar_node.allocate(code)
3887 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3888 self.py_loopvar_node.allocate(code)
3890 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3892 loopvar_name = self.loopvar_node.result()
3894 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3896 self.bound1.result(), offset,
3897 loopvar_name, self.relation2, self.bound2.result(),
3898 loopvar_name, incop))
3899 if self.py_loopvar_node:
3900 self.py_loopvar_node.generate_evaluation_code(code)
3901 self.target.generate_assignment_code(self.py_loopvar_node, code)
3903 code.putln("%s = %s;" % (
3904 self.target.result(), loopvar_name))
3905 self.body.generate_execution_code(code)
3906 code.put_label(code.continue_label)
3907 if self.py_loopvar_node:
3908 # This mess is to make for..from loops with python targets behave
3909 # exactly like those with C targets with regards to re-assignment
3910 # of the loop variable.
3912 if self.target.entry.is_pyglobal:
3913 # We know target is a NameNode, this is the only ugly case.
3914 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3915 target_node.allocate(code)
3916 interned_cname = code.intern_identifier(self.target.entry.name)
3917 code.putln("/*here*/")
3918 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3919 target_node.result(),
3920 Naming.module_cname,
3922 code.error_goto_if_null(target_node.result(), self.target.pos)))
3923 code.put_gotref(target_node.result())
3925 target_node = self.target
3926 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3927 from_py_node.temp_code = loopvar_name
3928 from_py_node.generate_result_code(code)
3929 if self.target.entry.is_pyglobal:
3930 code.put_decref(target_node.result(), target_node.type)
3931 target_node.release(code)
3933 if self.py_loopvar_node:
3934 # This is potentially wasteful, but we don't want the semantics to
3935 # depend on whether or not the loop is a python type.
3936 self.py_loopvar_node.generate_evaluation_code(code)
3937 self.target.generate_assignment_code(self.py_loopvar_node, code)
3938 break_label = code.break_label
3939 code.set_loop_labels(old_loop_labels)
3940 if self.else_clause:
3941 code.putln("/*else*/ {")
3942 self.else_clause.generate_execution_code(code)
3944 code.put_label(break_label)
3945 self.bound1.generate_disposal_code(code)
3946 self.bound1.free_temps(code)
3947 self.bound2.generate_disposal_code(code)
3948 self.bound2.free_temps(code)
3949 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3950 self.loopvar_node.release(code)
3951 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3952 self.py_loopvar_node.release(code)
3953 if self.step is not None:
3954 self.step.generate_disposal_code(code)
3955 self.step.free_temps(code)
3958 # {relop : (initial offset, increment op)}
3965 def annotate(self, code):
3966 self.target.annotate(code)
3967 self.bound1.annotate(code)
3968 self.bound2.annotate(code)
3970 self.bound2.annotate(code)
3971 self.body.annotate(code)
3972 if self.else_clause:
3973 self.else_clause.annotate(code)
3976 class WithStatNode(StatNode):
3978 Represents a Python with statement.
3980 This is only used at parse tree level; and is not present in
3981 analysis or generation phases.
3983 # manager The with statement manager object
3984 # target Node (lhs expression)
3986 child_attrs = ["manager", "target", "body"]
3988 class TryExceptStatNode(StatNode):
3989 # try .. except statement
3992 # except_clauses [ExceptClauseNode]
3993 # else_clause StatNode or None
3995 child_attrs = ["body", "except_clauses", "else_clause"]
3997 def analyse_control_flow(self, env):
3998 env.start_branching(self.pos)
3999 self.body.analyse_control_flow(env)
4000 successful_try = env.control_flow # grab this for later
4001 env.next_branch(self.body.end_pos())
4002 env.finish_branching(self.body.end_pos())
4004 env.start_branching(self.except_clauses[0].pos)
4005 for except_clause in self.except_clauses:
4006 except_clause.analyse_control_flow(env)
4007 env.next_branch(except_clause.end_pos())
4009 # the else cause it executed only when the try clause finishes
4010 env.control_flow.incoming = successful_try
4011 if self.else_clause:
4012 self.else_clause.analyse_control_flow(env)
4013 env.finish_branching(self.end_pos())
4015 def analyse_declarations(self, env):
4016 self.body.analyse_declarations(env)
4017 for except_clause in self.except_clauses:
4018 except_clause.analyse_declarations(env)
4019 if self.else_clause:
4020 self.else_clause.analyse_declarations(env)
4021 env.use_utility_code(reset_exception_utility_code)
4023 def analyse_expressions(self, env):
4024 self.body.analyse_expressions(env)
4025 default_clause_seen = 0
4026 for except_clause in self.except_clauses:
4027 except_clause.analyse_expressions(env)
4028 if default_clause_seen:
4029 error(except_clause.pos, "default 'except:' must be last")
4030 if not except_clause.pattern:
4031 default_clause_seen = 1
4032 self.has_default_clause = default_clause_seen
4033 if self.else_clause:
4034 self.else_clause.analyse_expressions(env)
4036 gil_check = StatNode._gil_check
4037 gil_message = "Try-except statement"
4039 def generate_execution_code(self, code):
4040 old_return_label = code.return_label
4041 old_break_label = code.break_label
4042 old_continue_label = code.continue_label
4043 old_error_label = code.new_error_label()
4044 our_error_label = code.error_label
4045 except_end_label = code.new_label('exception_handled')
4046 except_error_label = code.new_label('except_error')
4047 except_return_label = code.new_label('except_return')
4048 try_return_label = code.new_label('try_return')
4049 try_break_label = code.new_label('try_break')
4050 try_continue_label = code.new_label('try_continue')
4051 try_end_label = code.new_label('try_end')
4054 code.putln("PyObject %s;" %
4055 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4056 code.putln("__Pyx_ExceptionSave(%s);" %
4057 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4058 for var in Naming.exc_save_vars:
4059 code.put_xgotref(var)
4062 code.return_label = try_return_label
4063 code.break_label = try_break_label
4064 code.continue_label = try_continue_label
4065 self.body.generate_execution_code(code)
4068 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4069 code.error_label = except_error_label
4070 code.return_label = except_return_label
4071 if self.else_clause:
4074 self.else_clause.generate_execution_code(code)
4077 for var in Naming.exc_save_vars:
4078 code.put_xdecref_clear(var, py_object_type)
4079 code.put_goto(try_end_label)
4080 if code.label_used(try_return_label):
4081 code.put_label(try_return_label)
4082 for var in Naming.exc_save_vars:
4083 code.put_xdecref_clear(var, py_object_type)
4084 code.put_goto(old_return_label)
4085 code.put_label(our_error_label)
4086 for temp_name, type in temps_to_clean_up:
4087 code.put_xdecref_clear(temp_name, type)
4088 for except_clause in self.except_clauses:
4089 except_clause.generate_handling_code(code, except_end_label)
4091 error_label_used = code.label_used(except_error_label)
4092 if error_label_used or not self.has_default_clause:
4093 if error_label_used:
4094 code.put_label(except_error_label)
4095 for var in Naming.exc_save_vars:
4096 code.put_xdecref(var, py_object_type)
4097 code.put_goto(old_error_label)
4099 if code.label_used(try_break_label):
4100 code.put_label(try_break_label)
4101 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4102 code.putln("__Pyx_ExceptionReset(%s);" %
4103 ', '.join(Naming.exc_save_vars))
4104 code.put_goto(old_break_label)
4106 if code.label_used(try_continue_label):
4107 code.put_label(try_continue_label)
4108 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4109 code.putln("__Pyx_ExceptionReset(%s);" %
4110 ', '.join(Naming.exc_save_vars))
4111 code.put_goto(old_continue_label)
4113 if code.label_used(except_return_label):
4114 code.put_label(except_return_label)
4115 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4116 code.putln("__Pyx_ExceptionReset(%s);" %
4117 ', '.join(Naming.exc_save_vars))
4118 code.put_goto(old_return_label)
4120 if code.label_used(except_end_label):
4121 code.put_label(except_end_label)
4122 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4123 code.putln("__Pyx_ExceptionReset(%s);" %
4124 ', '.join(Naming.exc_save_vars))
4125 code.put_label(try_end_label)
4128 code.return_label = old_return_label
4129 code.break_label = old_break_label
4130 code.continue_label = old_continue_label
4131 code.error_label = old_error_label
4133 def annotate(self, code):
4134 self.body.annotate(code)
4135 for except_node in self.except_clauses:
4136 except_node.annotate(code)
4137 if self.else_clause:
4138 self.else_clause.annotate(code)
4141 class ExceptClauseNode(Node):
4142 # Part of try ... except statement.
4145 # target ExprNode or None
4147 # excinfo_target NameNode or None optional target for exception info
4148 # match_flag string result of exception match
4149 # exc_value ExcValueNode used internally
4150 # function_name string qualified name of enclosing function
4151 # exc_vars (string * 3) local exception variables
4153 # excinfo_target is never set by the parser, but can be set by a transform
4154 # in order to extract more extensive information about the exception as a
4155 # sys.exc_info()-style tuple into a target variable
4157 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4160 excinfo_target = None
4162 def analyse_declarations(self, env):
4164 self.target.analyse_target_declaration(env)
4165 if self.excinfo_target is not None:
4166 self.excinfo_target.analyse_target_declaration(env)
4167 self.body.analyse_declarations(env)
4169 def analyse_expressions(self, env):
4171 genv = env.global_scope()
4172 self.function_name = env.qualified_name
4174 self.pattern.analyse_expressions(env)
4175 self.pattern = self.pattern.coerce_to_pyobject(env)
4178 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4179 self.target.analyse_target_expression(env, self.exc_value)
4180 if self.excinfo_target is not None:
4182 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4183 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4184 self.excinfo_tuple.analyse_expressions(env)
4185 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4187 self.body.analyse_expressions(env)
4189 def generate_handling_code(self, code, end_label):
4190 code.mark_pos(self.pos)
4192 self.pattern.generate_evaluation_code(code)
4194 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4196 "%s = PyErr_ExceptionMatches(%s);" % (
4198 self.pattern.py_result()))
4199 self.pattern.generate_disposal_code(code)
4200 self.pattern.free_temps(code)
4204 code.funcstate.release_temp(match_flag)
4206 code.putln("/*except:*/ {")
4208 if not getattr(self.body, 'stats', True):
4209 # most simple case: no exception variable, empty body (pass)
4210 # => reset the exception state, done
4211 code.putln("PyErr_Restore(0,0,0);")
4212 code.put_goto(end_label)
4216 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4219 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4220 # We always have to fetch the exception value even if
4221 # there is no target, because this also normalises the
4222 # exception and stores it in the thread state.
4223 code.globalstate.use_utility_code(get_exception_utility_code)
4224 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4225 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4226 code.error_goto(self.pos)))
4230 self.exc_value.set_var(exc_vars[1])
4231 self.exc_value.generate_evaluation_code(code)
4232 self.target.generate_assignment_code(self.exc_value, code)
4233 if self.excinfo_target is not None:
4234 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4235 node.set_var(tempvar)
4236 self.excinfo_tuple.generate_evaluation_code(code)
4237 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4239 old_break_label, old_continue_label = code.break_label, code.continue_label
4240 code.break_label = code.new_label('except_break')
4241 code.continue_label = code.new_label('except_continue')
4243 old_exc_vars = code.funcstate.exc_vars
4244 code.funcstate.exc_vars = exc_vars
4245 self.body.generate_execution_code(code)
4246 code.funcstate.exc_vars = old_exc_vars
4247 for var in exc_vars:
4248 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4249 code.put_goto(end_label)
4251 if code.label_used(code.break_label):
4252 code.put_label(code.break_label)
4253 for var in exc_vars:
4254 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4255 code.put_goto(old_break_label)
4256 code.break_label = old_break_label
4258 if code.label_used(code.continue_label):
4259 code.put_label(code.continue_label)
4260 for var in exc_vars:
4261 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4262 code.put_goto(old_continue_label)
4263 code.continue_label = old_continue_label
4265 for temp in exc_vars:
4266 code.funcstate.release_temp(temp)
4271 def annotate(self, code):
4273 self.pattern.annotate(code)
4275 self.target.annotate(code)
4276 self.body.annotate(code)
4279 class TryFinallyStatNode(StatNode):
4280 # try ... finally statement
4283 # finally_clause StatNode
4285 # The plan is that we funnel all continue, break
4286 # return and error gotos into the beginning of the
4287 # finally block, setting a variable to remember which
4288 # one we're doing. At the end of the finally block, we
4289 # switch on the variable to figure out where to go.
4290 # In addition, if we're doing an error, we save the
4291 # exception on entry to the finally block and restore
4294 child_attrs = ["body", "finally_clause"]
4296 preserve_exception = 1
4298 disallow_continue_in_try_finally = 0
4299 # There doesn't seem to be any point in disallowing
4300 # continue in the try block, since we have no problem
4303 def create_analysed(pos, env, body, finally_clause):
4304 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4306 create_analysed = staticmethod(create_analysed)
4308 def analyse_control_flow(self, env):
4309 env.start_branching(self.pos)
4310 self.body.analyse_control_flow(env)
4311 env.next_branch(self.body.end_pos())
4312 env.finish_branching(self.body.end_pos())
4313 self.finally_clause.analyse_control_flow(env)
4315 def analyse_declarations(self, env):
4316 self.body.analyse_declarations(env)
4317 self.finally_clause.analyse_declarations(env)
4319 def analyse_expressions(self, env):
4320 self.body.analyse_expressions(env)
4321 self.finally_clause.analyse_expressions(env)
4323 gil_check = StatNode._gil_check
4324 gil_message = "Try-finally statement"
4326 def generate_execution_code(self, code):
4327 old_error_label = code.error_label
4328 old_labels = code.all_new_labels()
4329 new_labels = code.get_all_labels()
4330 new_error_label = code.error_label
4331 catch_label = code.new_label()
4334 if self.disallow_continue_in_try_finally:
4335 was_in_try_finally = code.funcstate.in_try_finally
4336 code.funcstate.in_try_finally = 1
4337 self.body.generate_execution_code(code)
4338 if self.disallow_continue_in_try_finally:
4339 code.funcstate.in_try_finally = was_in_try_finally
4342 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4346 error_label_used = 0
4347 for i, new_label in enumerate(new_labels):
4348 if new_label in code.labels_used:
4349 cases_used.append(i)
4350 if new_label == new_error_label:
4351 error_label_used = 1
4352 error_label_case = i
4356 if error_label_used and self.preserve_exception:
4358 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4360 "int %s;" % Naming.exc_lineno_name)
4361 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4362 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4363 code.putln(exc_var_init_zero)
4365 exc_var_init_zero = None
4366 code.use_label(catch_label)
4368 "__pyx_why = 0; goto %s;" % catch_label)
4369 for i in cases_used:
4370 new_label = new_labels[i]
4371 #if new_label and new_label != "<try>":
4372 if new_label == new_error_label and self.preserve_exception:
4373 self.put_error_catcher(code,
4374 new_error_label, i+1, catch_label, temps_to_clean_up)
4376 code.put('%s: ' % new_label)
4377 if exc_var_init_zero:
4378 code.putln(exc_var_init_zero)
4379 code.putln("__pyx_why = %s; goto %s;" % (
4382 code.put_label(catch_label)
4383 code.set_all_labels(old_labels)
4384 if error_label_used:
4385 code.new_error_label()
4386 finally_error_label = code.error_label
4387 self.finally_clause.generate_execution_code(code)
4388 if error_label_used:
4389 if finally_error_label in code.labels_used and self.preserve_exception:
4390 over_label = code.new_label()
4391 code.put_goto(over_label);
4392 code.put_label(finally_error_label)
4393 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4394 for var in Naming.exc_vars:
4395 code.putln("Py_XDECREF(%s);" % var)
4397 code.put_goto(old_error_label)
4398 code.put_label(over_label)
4399 code.error_label = old_error_label
4402 "switch (__pyx_why) {")
4403 for i in cases_used:
4404 old_label = old_labels[i]
4405 if old_label == old_error_label and self.preserve_exception:
4406 self.put_error_uncatcher(code, i+1, old_error_label)
4408 code.use_label(old_label)
4410 "case %s: goto %s;" % (
4418 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4419 code.globalstate.use_utility_code(restore_exception_utility_code)
4426 for temp_name, type in temps_to_clean_up:
4427 code.put_xdecref_clear(temp_name, type)
4429 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4433 Naming.exc_lineno_name, Naming.lineno_cname))
4437 code.put_goto(catch_label)
4441 def put_error_uncatcher(self, code, i, error_label):
4442 code.globalstate.use_utility_code(restore_exception_utility_code)
4447 "__Pyx_ErrRestore(%s, %s, %s);" %
4451 Naming.lineno_cname, Naming.exc_lineno_name))
4452 for var in Naming.exc_vars:
4456 code.put_goto(error_label)
4460 def annotate(self, code):
4461 self.body.annotate(code)
4462 self.finally_clause.annotate(code)
4465 class GILStatNode(TryFinallyStatNode):
4466 # 'with gil' or 'with nogil' statement
4468 # state string 'gil' or 'nogil'
4472 preserve_exception = 0
4474 def __init__(self, pos, state, body):
4476 TryFinallyStatNode.__init__(self, pos,
4478 finally_clause = GILExitNode(pos, state = state))
4480 def analyse_expressions(self, env):
4481 env.use_utility_code(force_init_threads_utility_code)
4482 was_nogil = env.nogil
4484 TryFinallyStatNode.analyse_expressions(self, env)
4485 env.nogil = was_nogil
4487 def gil_check(self, env):
4490 def generate_execution_code(self, code):
4491 code.mark_pos(self.pos)
4492 if self.state == 'gil':
4493 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4495 code.putln("{ PyThreadState *_save;")
4496 code.putln("Py_UNBLOCK_THREADS")
4497 TryFinallyStatNode.generate_execution_code(self, code)
4501 class GILExitNode(StatNode):
4502 # Used as the 'finally' block in a GILStatNode
4504 # state string 'gil' or 'nogil'
4508 def analyse_expressions(self, env):
4511 def generate_execution_code(self, code):
4512 if self.state == 'gil':
4513 code.putln("PyGILState_Release();")
4515 code.putln("Py_BLOCK_THREADS")
4518 class CImportStatNode(StatNode):
4521 # module_name string Qualified name of module being imported
4522 # as_name string or None Name specified in "as" clause, if any
4526 def analyse_declarations(self, env):
4527 if not env.is_module_scope:
4528 error(self.pos, "cimport only allowed at module level")
4530 module_scope = env.find_module(self.module_name, self.pos)
4531 if "." in self.module_name:
4532 names = [EncodedString(name) for name in self.module_name.split(".")]
4534 top_module_scope = env.context.find_submodule(top_name)
4535 module_scope = top_module_scope
4536 for name in names[1:]:
4537 submodule_scope = module_scope.find_submodule(name)
4538 module_scope.declare_module(name, submodule_scope, self.pos)
4539 module_scope = submodule_scope
4541 env.declare_module(self.as_name, module_scope, self.pos)
4543 env.declare_module(top_name, top_module_scope, self.pos)
4545 name = self.as_name or self.module_name
4546 env.declare_module(name, module_scope, self.pos)
4548 def analyse_expressions(self, env):
4551 def generate_execution_code(self, code):
4555 class FromCImportStatNode(StatNode):
4556 # from ... cimport statement
4558 # module_name string Qualified name of module
4559 # imported_names [(pos, name, as_name, kind)] Names to be imported
4563 def analyse_declarations(self, env):
4564 if not env.is_module_scope:
4565 error(self.pos, "cimport only allowed at module level")
4567 module_scope = env.find_module(self.module_name, self.pos)
4568 env.add_imported_module(module_scope)
4569 for pos, name, as_name, kind in self.imported_names:
4571 for local_name, entry in module_scope.entries.items():
4572 env.add_imported_entry(local_name, entry, pos)
4574 entry = module_scope.lookup(name)
4576 if kind and not self.declaration_matches(entry, kind):
4577 entry.redeclared(pos)
4579 if kind == 'struct' or kind == 'union':
4580 entry = module_scope.declare_struct_or_union(name,
4581 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4582 elif kind == 'class':
4583 entry = module_scope.declare_c_class(name, pos = pos,
4584 module_name = self.module_name)
4586 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4587 if submodule_scope.parent_module is module_scope:
4588 env.declare_module(as_name or name, submodule_scope, self.pos)
4590 error(pos, "Name '%s' not declared in module '%s'"
4591 % (name, self.module_name))
4594 local_name = as_name or name
4595 env.add_imported_entry(local_name, entry, pos)
4597 def declaration_matches(self, entry, kind):
4598 if not entry.is_type:
4602 if not type.is_extension_type:
4605 if not type.is_struct_or_union:
4607 if kind != type.kind:
4611 def analyse_expressions(self, env):
4614 def generate_execution_code(self, code):
4618 class FromImportStatNode(StatNode):
4619 # from ... import statement
4622 # items [(string, NameNode)]
4623 # interned_items [(string, NameNode, ExprNode)]
4624 # item PyTempNode used internally
4625 # import_star boolean used internally
4627 child_attrs = ["module"]
4630 def analyse_declarations(self, env):
4631 for name, target in self.items:
4633 if not env.is_module_scope:
4634 error(self.pos, "import * only allowed at module level")
4636 env.has_import_star = 1
4637 self.import_star = 1
4639 target.analyse_target_declaration(env)
4641 def analyse_expressions(self, env):
4643 self.module.analyse_expressions(env)
4644 self.item = ExprNodes.PyTempNode(self.pos, env)
4645 self.interned_items = []
4646 for name, target in self.items:
4648 for _, entry in env.entries.items():
4649 if not entry.is_type and entry.type.is_extension_type:
4650 env.use_utility_code(ExprNodes.type_test_utility_code)
4653 entry = env.lookup(target.name)
4654 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4655 continue # already cimported
4656 target.analyse_target_expression(env, None)
4657 if target.type is py_object_type:
4660 coerced_item = self.item.coerce_to(target.type, env)
4661 self.interned_items.append(
4662 (name, target, coerced_item))
4664 def generate_execution_code(self, code):
4665 self.module.generate_evaluation_code(code)
4666 if self.import_star:
4668 'if (%s(%s) < 0) %s;' % (
4670 self.module.py_result(),
4671 code.error_goto(self.pos)))
4672 self.item.allocate(code)
4673 for name, target, coerced_item in self.interned_items:
4674 cname = code.intern_identifier(name)
4676 '%s = PyObject_GetAttr(%s, %s); %s' % (
4678 self.module.py_result(),
4680 code.error_goto_if_null(self.item.result(), self.pos)))
4681 code.put_gotref(self.item.py_result())
4682 if coerced_item is None:
4683 target.generate_assignment_code(self.item, code)
4685 coerced_item.allocate_temp_result(code)
4686 coerced_item.generate_result_code(code)
4687 target.generate_assignment_code(coerced_item, code)
4688 if self.item.result() != coerced_item.result():
4689 code.put_decref_clear(self.item.result(), self.item.type)
4690 self.item.release(code)
4691 self.module.generate_disposal_code(code)
4692 self.module.free_temps(code)
4696 #------------------------------------------------------------------------------------
4698 # Runtime support code
4700 #------------------------------------------------------------------------------------
4702 utility_function_predeclarations = \
4705 #define INLINE __inline__
4707 #define INLINE __inline
4712 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4716 static int %(skip_dispatch_cname)s = 0;
4718 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4720 if Options.gcc_branch_hints:
4721 branch_prediction_macros = \
4724 /* Test for GCC > 2.95 */
4725 #if __GNUC__ > 2 || \
4726 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4727 #define likely(x) __builtin_expect(!!(x), 1)
4728 #define unlikely(x) __builtin_expect(!!(x), 0)
4729 #else /* __GNUC__ > 2 ... */
4730 #define likely(x) (x)
4731 #define unlikely(x) (x)
4732 #endif /* __GNUC__ > 2 ... */
4733 #else /* __GNUC__ */
4734 #define likely(x) (x)
4735 #define unlikely(x) (x)
4736 #endif /* __GNUC__ */
4739 branch_prediction_macros = \
4741 #define likely(x) (x)
4742 #define unlikely(x) (x)
4745 #get_name_predeclaration = \
4746 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4748 #get_name_interned_predeclaration = \
4749 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4751 #------------------------------------------------------------------------------------
4753 printing_utility_code = UtilityCode(
4755 static int __Pyx_Print(PyObject *, int); /*proto*/
4756 #if PY_MAJOR_VERSION >= 3
4757 static PyObject* %s = 0;
4758 static PyObject* %s = 0;
4760 """ % (Naming.print_function, Naming.print_function_kwargs),
4762 #if PY_MAJOR_VERSION < 3
4763 static PyObject *__Pyx_GetStdout(void) {
4764 PyObject *f = PySys_GetObject((char *)"stdout");
4766 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4771 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4776 if (!(f = __Pyx_GetStdout()))
4778 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4779 if (PyFile_SoftSpace(f, 1)) {
4780 if (PyFile_WriteString(" ", f) < 0)
4783 v = PyTuple_GET_ITEM(arg_tuple, i);
4784 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4786 if (PyString_Check(v)) {
4787 char *s = PyString_AsString(v);
4788 Py_ssize_t len = PyString_Size(v);
4790 isspace(Py_CHARMASK(s[len-1])) &&
4792 PyFile_SoftSpace(f, 0);
4796 if (PyFile_WriteString("\n", f) < 0)
4798 PyFile_SoftSpace(f, 0);
4803 #else /* Python 3 has a print function */
4805 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4806 PyObject* kwargs = 0;
4807 PyObject* result = 0;
4808 PyObject* end_string;
4809 if (!%(PRINT_FUNCTION)s) {
4810 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4811 if (!%(PRINT_FUNCTION)s)
4815 if (!%(PRINT_KWARGS)s) {
4816 %(PRINT_KWARGS)s = PyDict_New();
4817 if (!%(PRINT_KWARGS)s)
4819 end_string = PyUnicode_FromStringAndSize(" ", 1);
4822 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4823 Py_DECREF(end_string);
4826 Py_DECREF(end_string);
4828 kwargs = %(PRINT_KWARGS)s;
4830 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4838 """ % {'BUILTINS' : Naming.builtins_cname,
4839 'PRINT_FUNCTION' : Naming.print_function,
4840 'PRINT_KWARGS' : Naming.print_function_kwargs}
4844 printing_one_utility_code = UtilityCode(
4846 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4849 #if PY_MAJOR_VERSION < 3
4851 static int __Pyx_PrintOne(PyObject *o) {
4853 if (!(f = __Pyx_GetStdout()))
4855 if (PyFile_SoftSpace(f, 0)) {
4856 if (PyFile_WriteString(" ", f) < 0)
4859 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4861 if (PyFile_WriteString("\n", f) < 0)
4864 /* the line below is just to avoid compiler
4865 * compiler warnings about unused functions */
4866 return __Pyx_Print(NULL, 0);
4869 #else /* Python 3 has a print function */
4871 static int __Pyx_PrintOne(PyObject *o) {
4873 PyObject* arg_tuple = PyTuple_New(1);
4874 if (unlikely(!arg_tuple))
4877 PyTuple_SET_ITEM(arg_tuple, 0, o);
4878 res = __Pyx_Print(arg_tuple, 1);
4879 Py_DECREF(arg_tuple);
4885 requires=[printing_utility_code])
4889 #------------------------------------------------------------------------------------
4891 # The following function is based on do_raise() from ceval.c.
4893 raise_utility_code = UtilityCode(
4895 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4898 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4902 /* First, check the traceback argument, replacing None with NULL. */
4903 if (tb == Py_None) {
4907 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4908 PyErr_SetString(PyExc_TypeError,
4909 "raise: arg 3 must be a traceback or None");
4912 /* Next, replace a missing value with None */
4913 if (value == NULL) {
4917 #if PY_VERSION_HEX < 0x02050000
4918 if (!PyClass_Check(type))
4920 if (!PyType_Check(type))
4923 /* Raising an instance. The value should be a dummy. */
4924 if (value != Py_None) {
4925 PyErr_SetString(PyExc_TypeError,
4926 "instance exception may not have a separate value");
4929 /* Normalize to raise <class>, <instance> */
4932 #if PY_VERSION_HEX < 0x02050000
4933 if (PyInstance_Check(type)) {
4934 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4939 PyErr_SetString(PyExc_TypeError,
4940 "raise: exception must be an old-style class or instance");
4944 type = (PyObject*) Py_TYPE(type);
4946 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4947 PyErr_SetString(PyExc_TypeError,
4948 "raise: exception class must be a subclass of BaseException");
4953 __Pyx_ErrRestore(type, value, tb);
4963 #------------------------------------------------------------------------------------
4965 reraise_utility_code = UtilityCode(
4967 static void __Pyx_ReRaise(void); /*proto*/
4970 static void __Pyx_ReRaise(void) {
4971 PyThreadState *tstate = PyThreadState_GET();
4972 PyObject* tmp_type = tstate->curexc_type;
4973 PyObject* tmp_value = tstate->curexc_value;
4974 PyObject* tmp_tb = tstate->curexc_traceback;
4975 tstate->curexc_type = tstate->exc_type;
4976 tstate->curexc_value = tstate->exc_value;
4977 tstate->curexc_traceback = tstate->exc_traceback;
4978 tstate->exc_type = 0;
4979 tstate->exc_value = 0;
4980 tstate->exc_traceback = 0;
4981 Py_XDECREF(tmp_type);
4982 Py_XDECREF(tmp_value);
4987 #------------------------------------------------------------------------------------
4989 arg_type_test_utility_code = UtilityCode(
4991 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4992 const char *name, int exact); /*proto*/
4995 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4996 const char *name, int exact)
4999 PyErr_Format(PyExc_SystemError, "Missing type object");
5002 if (none_allowed && obj == Py_None) return 1;
5004 if (Py_TYPE(obj) == type) return 1;
5007 if (PyObject_TypeCheck(obj, type)) return 1;
5009 PyErr_Format(PyExc_TypeError,
5010 "Argument '%s' has incorrect type (expected %s, got %s)",
5011 name, type->tp_name, Py_TYPE(obj)->tp_name);
5016 #------------------------------------------------------------------------------------
5018 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5019 # many or too few positional arguments were found. This handles
5020 # Py_ssize_t formatting correctly.
5022 raise_argtuple_invalid_utility_code = UtilityCode(
5024 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5025 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5028 static void __Pyx_RaiseArgtupleInvalid(
5029 const char* func_name,
5033 Py_ssize_t num_found)
5035 Py_ssize_t num_expected;
5036 const char *number, *more_or_less;
5038 if (num_found < num_min) {
5039 num_expected = num_min;
5040 more_or_less = "at least";
5042 num_expected = num_max;
5043 more_or_less = "at most";
5046 more_or_less = "exactly";
5048 number = (num_expected == 1) ? "" : "s";
5049 PyErr_Format(PyExc_TypeError,
5050 #if PY_VERSION_HEX < 0x02050000
5051 "%s() takes %s %d positional argument%s (%d given)",
5053 "%s() takes %s %zd positional argument%s (%zd given)",
5055 func_name, more_or_less, num_expected, number, num_found);
5059 raise_keyword_required_utility_code = UtilityCode(
5061 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5064 static INLINE void __Pyx_RaiseKeywordRequired(
5065 const char* func_name,
5068 PyErr_Format(PyExc_TypeError,
5069 #if PY_MAJOR_VERSION >= 3
5070 "%s() needs keyword-only argument %U", func_name, kw_name);
5072 "%s() needs keyword-only argument %s", func_name,
5073 PyString_AS_STRING(kw_name));
5078 raise_double_keywords_utility_code = UtilityCode(
5080 static void __Pyx_RaiseDoubleKeywordsError(
5081 const char* func_name, PyObject* kw_name); /*proto*/
5084 static void __Pyx_RaiseDoubleKeywordsError(
5085 const char* func_name,
5088 PyErr_Format(PyExc_TypeError,
5089 #if PY_MAJOR_VERSION >= 3
5090 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5092 "%s() got multiple values for keyword argument '%s'", func_name,
5093 PyString_AS_STRING(kw_name));
5098 #------------------------------------------------------------------------------------
5100 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5101 # were passed to a function, or if any keywords were passed to a
5102 # function that does not accept them.
5104 keyword_string_check_utility_code = UtilityCode(
5106 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5107 const char* function_name, int kw_allowed); /*proto*/
5110 static INLINE int __Pyx_CheckKeywordStrings(
5112 const char* function_name,
5117 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5118 #if PY_MAJOR_VERSION < 3
5119 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5121 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5123 goto invalid_keyword_type;
5125 if ((!kw_allowed) && unlikely(key))
5126 goto invalid_keyword;
5128 invalid_keyword_type:
5129 PyErr_Format(PyExc_TypeError,
5130 "%s() keywords must be strings", function_name);
5133 PyErr_Format(PyExc_TypeError,
5134 #if PY_MAJOR_VERSION < 3
5135 "%s() got an unexpected keyword argument '%s'",
5136 function_name, PyString_AsString(key));
5138 "%s() got an unexpected keyword argument '%U'",
5139 function_name, key);
5145 #------------------------------------------------------------------------------------
5147 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5148 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5149 # keywords will raise an invalid keyword error.
5151 # Three kinds of errors are checked: 1) non-string keywords, 2)
5152 # unexpected keywords and 3) overlap with positional arguments.
5154 # If num_posargs is greater 0, it denotes the number of positional
5155 # arguments that were passed and that must therefore not appear
5156 # amongst the keywords as well.
5158 # This method does not check for required keyword arguments.
5161 parse_keywords_utility_code = UtilityCode(
5163 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5164 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5165 const char* function_name); /*proto*/
5168 static int __Pyx_ParseOptionalKeywords(
5170 PyObject **argnames[],
5173 Py_ssize_t num_pos_args,
5174 const char* function_name)
5176 PyObject *key = 0, *value = 0;
5179 PyObject*** first_kw_arg = argnames + num_pos_args;
5181 while (PyDict_Next(kwds, &pos, &key, &value)) {
5182 name = first_kw_arg;
5183 while (*name && (**name != key)) name++;
5185 values[name-argnames] = value;
5187 #if PY_MAJOR_VERSION < 3
5188 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5190 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5192 goto invalid_keyword_type;
5194 for (name = first_kw_arg; *name; name++) {
5195 #if PY_MAJOR_VERSION >= 3
5196 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5197 PyUnicode_Compare(**name, key) == 0) break;
5199 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5200 _PyString_Eq(**name, key)) break;
5204 values[name-argnames] = value;
5206 /* unexpected keyword found */
5207 for (name=argnames; name != first_kw_arg; name++) {
5208 if (**name == key) goto arg_passed_twice;
5209 #if PY_MAJOR_VERSION >= 3
5210 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5211 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5213 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5214 _PyString_Eq(**name, key)) goto arg_passed_twice;
5218 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5220 goto invalid_keyword;
5228 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5230 invalid_keyword_type:
5231 PyErr_Format(PyExc_TypeError,
5232 "%s() keywords must be strings", function_name);
5235 PyErr_Format(PyExc_TypeError,
5236 #if PY_MAJOR_VERSION < 3
5237 "%s() got an unexpected keyword argument '%s'",
5238 function_name, PyString_AsString(key));
5240 "%s() got an unexpected keyword argument '%U'",
5241 function_name, key);
5248 #------------------------------------------------------------------------------------
5250 traceback_utility_code = UtilityCode(
5252 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5255 #include "compile.h"
5256 #include "frameobject.h"
5257 #include "traceback.h"
5259 static void __Pyx_AddTraceback(const char *funcname) {
5260 PyObject *py_srcfile = 0;
5261 PyObject *py_funcname = 0;
5262 PyObject *py_globals = 0;
5263 PyObject *empty_string = 0;
5264 PyCodeObject *py_code = 0;
5265 PyFrameObject *py_frame = 0;
5267 #if PY_MAJOR_VERSION < 3
5268 py_srcfile = PyString_FromString(%(FILENAME)s);
5270 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5272 if (!py_srcfile) goto bad;
5274 #if PY_MAJOR_VERSION < 3
5275 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5277 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5281 #if PY_MAJOR_VERSION < 3
5282 py_funcname = PyString_FromString(funcname);
5284 py_funcname = PyUnicode_FromString(funcname);
5287 if (!py_funcname) goto bad;
5288 py_globals = PyModule_GetDict(%(GLOBALS)s);
5289 if (!py_globals) goto bad;
5290 #if PY_MAJOR_VERSION < 3
5291 empty_string = PyString_FromStringAndSize("", 0);
5293 empty_string = PyBytes_FromStringAndSize("", 0);
5295 if (!empty_string) goto bad;
5296 py_code = PyCode_New(
5297 0, /*int argcount,*/
5298 #if PY_MAJOR_VERSION >= 3
5299 0, /*int kwonlyargcount,*/
5302 0, /*int stacksize,*/
5304 empty_string, /*PyObject *code,*/
5305 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5306 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5307 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5308 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5309 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5310 py_srcfile, /*PyObject *filename,*/
5311 py_funcname, /*PyObject *name,*/
5312 %(LINENO)s, /*int firstlineno,*/
5313 empty_string /*PyObject *lnotab*/
5315 if (!py_code) goto bad;
5316 py_frame = PyFrame_New(
5317 PyThreadState_GET(), /*PyThreadState *tstate,*/
5318 py_code, /*PyCodeObject *code,*/
5319 py_globals, /*PyObject *globals,*/
5320 0 /*PyObject *locals*/
5322 if (!py_frame) goto bad;
5323 py_frame->f_lineno = %(LINENO)s;
5324 PyTraceBack_Here(py_frame);
5326 Py_XDECREF(py_srcfile);
5327 Py_XDECREF(py_funcname);
5328 Py_XDECREF(empty_string);
5329 Py_XDECREF(py_code);
5330 Py_XDECREF(py_frame);
5333 'FILENAME': Naming.filename_cname,
5334 'LINENO': Naming.lineno_cname,
5335 'CFILENAME': Naming.cfilenm_cname,
5336 'CLINENO': Naming.clineno_cname,
5337 'GLOBALS': Naming.module_cname,
5338 'EMPTY_TUPLE' : Naming.empty_tuple,
5341 restore_exception_utility_code = UtilityCode(
5343 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5344 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5347 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5348 PyObject *tmp_type, *tmp_value, *tmp_tb;
5349 PyThreadState *tstate = PyThreadState_GET();
5351 #if PY_MAJOR_VERSION >= 3
5352 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5353 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5354 tmp_type = tstate->exc_type;
5355 tmp_value = tstate->exc_value;
5356 tmp_tb = tstate->exc_traceback;
5357 PyErr_NormalizeException(&type, &value, &tb);
5358 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5359 tstate->exc_type = 0;
5360 tstate->exc_value = 0;
5361 tstate->exc_traceback = 0;
5362 PyException_SetContext(value, tmp_value);
5363 Py_DECREF(tmp_type);
5368 tmp_type = tstate->curexc_type;
5369 tmp_value = tstate->curexc_value;
5370 tmp_tb = tstate->curexc_traceback;
5371 tstate->curexc_type = type;
5372 tstate->curexc_value = value;
5373 tstate->curexc_traceback = tb;
5374 Py_XDECREF(tmp_type);
5375 Py_XDECREF(tmp_value);
5379 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5380 PyThreadState *tstate = PyThreadState_GET();
5381 *type = tstate->curexc_type;
5382 *value = tstate->curexc_value;
5383 *tb = tstate->curexc_traceback;
5385 tstate->curexc_type = 0;
5386 tstate->curexc_value = 0;
5387 tstate->curexc_traceback = 0;
5392 #------------------------------------------------------------------------------------
5394 unraisable_exception_utility_code = UtilityCode(
5396 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5399 static void __Pyx_WriteUnraisable(const char *name) {
5400 PyObject *old_exc, *old_val, *old_tb;
5402 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5403 #if PY_MAJOR_VERSION < 3
5404 ctx = PyString_FromString(name);
5406 ctx = PyUnicode_FromString(name);
5408 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5410 PyErr_WriteUnraisable(Py_None);
5412 PyErr_WriteUnraisable(ctx);
5417 requires=[restore_exception_utility_code])
5419 #------------------------------------------------------------------------------------
5421 set_vtable_utility_code = UtilityCode(
5423 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5426 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5427 PyObject *pycobj = 0;
5430 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5433 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5446 #------------------------------------------------------------------------------------
5448 get_vtable_utility_code = UtilityCode(
5450 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5453 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5457 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5460 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5461 if (!*(void **)vtabptr)
5474 #------------------------------------------------------------------------------------
5476 init_string_tab_utility_code = UtilityCode(
5478 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5481 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5483 #if PY_MAJOR_VERSION < 3
5484 if (t->is_unicode && (!t->is_identifier)) {
5485 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5486 } else if (t->intern) {
5487 *t->p = PyString_InternFromString(t->s);
5489 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5491 #else /* Python 3+ has unicode identifiers */
5492 if (t->is_identifier || (t->is_unicode && t->intern)) {
5493 *t->p = PyUnicode_InternFromString(t->s);
5494 } else if (t->is_unicode) {
5495 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5497 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5508 #------------------------------------------------------------------------------------
5510 get_exception_utility_code = UtilityCode(
5512 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5515 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5516 PyObject *tmp_type, *tmp_value, *tmp_tb;
5517 PyThreadState *tstate = PyThreadState_GET();
5518 *type = tstate->curexc_type;
5519 *value = tstate->curexc_value;
5520 *tb = tstate->curexc_traceback;
5521 tstate->curexc_type = 0;
5522 tstate->curexc_value = 0;
5523 tstate->curexc_traceback = 0;
5524 PyErr_NormalizeException(type, value, tb);
5525 if (PyErr_Occurred())
5530 tmp_type = tstate->exc_type;
5531 tmp_value = tstate->exc_value;
5532 tmp_tb = tstate->exc_traceback;
5533 tstate->exc_type = *type;
5534 tstate->exc_value = *value;
5535 tstate->exc_traceback = *tb;
5536 /* Make sure tstate is in a consistent state when we XDECREF
5537 these objects (XDECREF may run arbitrary code). */
5538 Py_XDECREF(tmp_type);
5539 Py_XDECREF(tmp_value);
5551 #------------------------------------------------------------------------------------
5553 reset_exception_utility_code = UtilityCode(
5555 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5556 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5559 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5560 PyThreadState *tstate = PyThreadState_GET();
5561 *type = tstate->exc_type;
5562 *value = tstate->exc_value;
5563 *tb = tstate->exc_traceback;
5569 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5570 PyObject *tmp_type, *tmp_value, *tmp_tb;
5571 PyThreadState *tstate = PyThreadState_GET();
5572 tmp_type = tstate->exc_type;
5573 tmp_value = tstate->exc_value;
5574 tmp_tb = tstate->exc_traceback;
5575 tstate->exc_type = type;
5576 tstate->exc_value = value;
5577 tstate->exc_traceback = tb;
5578 Py_XDECREF(tmp_type);
5579 Py_XDECREF(tmp_value);
5584 #------------------------------------------------------------------------------------
5586 force_init_threads_utility_code = UtilityCode(
5588 #ifndef __PYX_FORCE_INIT_THREADS
5589 #if PY_VERSION_HEX < 0x02040200
5590 #define __PYX_FORCE_INIT_THREADS 1
5592 #define __PYX_FORCE_INIT_THREADS 0
5597 #------------------------------------------------------------------------------------