2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix
17 from Code import UtilityCode
18 from StringEncoding import EncodedString, escape_byte_string, split_docstring
23 absolute_path_length = 0
25 def relative_position(pos):
27 We embed the relative filename in the generated C file, since we
28 don't want to have to regnerate and compile all the source code
29 whenever the Python install directory moves (which could happen,
30 e.g,. when distributing binaries.)
33 a position tuple -- (absolute filename, line number column position)
41 global absolute_path_length
42 if absolute_path_length==0:
43 absolute_path_length = len(os.path.abspath(os.getcwd()))
44 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
46 def embed_position(pos, docstring):
47 if not Options.embed_pos_in_docstring:
49 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
52 return EncodedString(pos_line)
54 # make sure we can encode the filename in the docstring encoding
55 # otherwise make the docstring a unicode string
56 encoding = docstring.encoding
57 if encoding is not None:
59 encoded_bytes = pos_line.encode(encoding)
60 except UnicodeEncodeError:
64 # reuse the string encoding of the original docstring
65 doc = EncodedString(pos_line)
67 doc = EncodedString(pos_line + u'\n' + docstring)
68 doc.encoding = encoding
72 from Code import CCodeWriter
73 from types import FunctionType
75 def write_func_call(func):
77 if len(args) > 1 and isinstance(args[1], CCodeWriter):
78 # here we annotate the code with this function call
79 # but only if new code is generated
81 marker = ' /* %s -> %s.%s %s */' % (
82 ' ' * code.call_level,
83 node.__class__.__name__,
86 pristine = code.buffer.stream.tell()
88 start = code.buffer.stream.tell()
90 res = func(*args, **kwds)
92 if start == code.buffer.stream.tell():
93 code.buffer.stream.seek(pristine)
95 marker = marker.replace('->', '<-')
99 return func(*args, **kwds)
102 class VerboseCodeWriter(type):
103 # Set this as a metaclass to trace function calls in code.
104 # This slows down code generation and makes much larger files.
105 def __new__(cls, name, bases, attrs):
107 for mname, m in attrs.items():
108 if isinstance(m, FunctionType):
109 attrs[mname] = write_func_call(m)
110 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
114 # pos (string, int, int) Source file position
115 # is_name boolean Is a NameNode
116 # is_literal boolean Is a ConstNode
118 if DebugFlags.debug_trace_code_generation:
119 __metaclass__ = VerboseCodeWriter
125 # All descandants should set child_attrs to a list of the attributes
126 # containing nodes considered "children" in the tree. Each such attribute
127 # can either contain a single node or a list of nodes. See Visitor.py.
130 def __init__(self, pos, **kw):
132 self.__dict__.update(kw)
134 gil_message = "Operation"
138 def gil_error(self, env=None):
139 error(self.pos, "%s not allowed without gil" % self.gil_message)
141 def clone_node(self):
142 """Clone the node. This is defined as a shallow copy, except for member lists
143 amongst the child attributes (from get_child_accessors) which are also
144 copied. Lists containing child nodes are thus seen as a way for the node
145 to hold multiple children directly; the list is not treated as a seperate
146 level in the tree."""
147 result = copy.copy(self)
148 for attrname in result.child_attrs:
149 value = getattr(result, attrname)
150 if isinstance(value, list):
151 setattr(result, attrname, [x for x in value])
156 # There are 4 phases of parse tree processing, applied in order to
157 # all the statements in a given scope-block:
159 # (0) analyse_control_flow
160 # Create the control flow tree into which state can be asserted and
163 # (1) analyse_declarations
164 # Make symbol table entries for all declarations at the current
165 # level, both explicit (def, cdef, etc.) and implicit (assignment
166 # to an otherwise undeclared name).
168 # (2) analyse_expressions
169 # Determine the result types of expressions and fill in the
170 # 'type' attribute of each ExprNode. Insert coercion nodes into the
171 # tree where needed to convert to and from Python objects.
172 # Allocate temporary locals for intermediate results. Fill
173 # in the 'result_code' attribute of each ExprNode with a C code
177 # Emit C code for all declarations, statements and expressions.
178 # Recursively applies the 3 processing phases to the bodies of
182 def analyse_control_flow(self, env):
185 def analyse_declarations(self, env):
188 def analyse_expressions(self, env):
189 raise InternalError("analyse_expressions not implemented for %s" % \
190 self.__class__.__name__)
192 def generate_code(self, code):
193 raise InternalError("generate_code not implemented for %s" % \
194 self.__class__.__name__)
196 def annotate(self, code):
197 # mro does the wrong thing
198 if isinstance(self, BlockNode):
199 self.body.annotate(code)
204 except AttributeError:
206 if not self.child_attrs:
209 for attr in self.child_attrs:
210 child = getattr(self, attr)
211 # Sometimes lists, sometimes nodes
214 elif isinstance(child, list):
216 pos = max(pos, c.end_pos())
218 pos = max(pos, child.end_pos())
222 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
224 return "<...nesting level cutoff...>"
225 if encountered is None:
227 if id(self) in encountered:
228 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
229 encountered.add(id(self))
231 def dump_child(x, level):
232 if isinstance(x, Node):
233 return x.dump(level, filter_out, cutoff-1, encountered)
234 elif isinstance(x, list):
235 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
240 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
242 return "<%s (%d)>" % (self.__class__.__name__, id(self))
245 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
246 for key, value in attrs:
247 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
248 res += "%s>" % indent
251 class CompilerDirectivesNode(Node):
253 Sets compiler directives for the children nodes
255 # directives {string:value} A dictionary holding the right value for
256 # *all* possible directives.
258 child_attrs = ["body"]
260 def analyse_control_flow(self, env):
262 env.directives = self.directives
263 self.body.analyse_control_flow(env)
266 def analyse_declarations(self, env):
268 env.directives = self.directives
269 self.body.analyse_declarations(env)
272 def analyse_expressions(self, env):
274 env.directives = self.directives
275 self.body.analyse_expressions(env)
278 def generate_function_definitions(self, env, code):
279 env_old = env.directives
280 code_old = code.globalstate.directives
281 code.globalstate.directives = self.directives
282 self.body.generate_function_definitions(env, code)
283 env.directives = env_old
284 code.globalstate.directives = code_old
286 def generate_execution_code(self, code):
287 old = code.globalstate.directives
288 code.globalstate.directives = self.directives
289 self.body.generate_execution_code(code)
290 code.globalstate.directives = old
292 def annotate(self, code):
293 old = code.globalstate.directives
294 code.globalstate.directives = self.directives
295 self.body.annotate(code)
296 code.globalstate.directives = old
298 class BlockNode(object):
299 # Mixin class for nodes representing a declaration block.
301 def generate_cached_builtins_decls(self, env, code):
302 entries = env.global_scope().undeclared_cached_builtins
303 for entry in entries:
304 code.globalstate.add_cached_builtin_decl(entry)
308 class StatListNode(Node):
309 # stats a list of StatNode
311 child_attrs = ["stats"]
313 def create_analysed(pos, env, *args, **kw):
314 node = StatListNode(pos, *args, **kw)
315 return node # No node-specific analysis necesarry
316 create_analysed = staticmethod(create_analysed)
318 def analyse_control_flow(self, env):
319 for stat in self.stats:
320 stat.analyse_control_flow(env)
322 def analyse_declarations(self, env):
323 #print "StatListNode.analyse_declarations" ###
324 for stat in self.stats:
325 stat.analyse_declarations(env)
327 def analyse_expressions(self, env):
328 #print "StatListNode.analyse_expressions" ###
329 for stat in self.stats:
330 stat.analyse_expressions(env)
332 def generate_function_definitions(self, env, code):
333 #print "StatListNode.generate_function_definitions" ###
334 for stat in self.stats:
335 stat.generate_function_definitions(env, code)
337 def generate_execution_code(self, code):
338 #print "StatListNode.generate_execution_code" ###
339 for stat in self.stats:
340 code.mark_pos(stat.pos)
341 stat.generate_execution_code(code)
343 def annotate(self, code):
344 for stat in self.stats:
348 class StatNode(Node):
350 # Code generation for statements is split into the following subphases:
352 # (1) generate_function_definitions
353 # Emit C code for the definitions of any structs,
354 # unions, enums and functions defined in the current
357 # (2) generate_execution_code
358 # Emit C code for executable statements.
361 def generate_function_definitions(self, env, code):
364 def generate_execution_code(self, code):
365 raise InternalError("generate_execution_code not implemented for %s" % \
366 self.__class__.__name__)
369 class CDefExternNode(StatNode):
370 # include_file string or None
373 child_attrs = ["body"]
375 def analyse_declarations(self, env):
376 if self.include_file:
377 env.add_include_file(self.include_file)
378 old_cinclude_flag = env.in_cinclude
380 self.body.analyse_declarations(env)
381 env.in_cinclude = old_cinclude_flag
383 def analyse_expressions(self, env):
386 def generate_execution_code(self, code):
389 def annotate(self, code):
390 self.body.annotate(code)
393 class CDeclaratorNode(Node):
394 # Part of a C declaration.
396 # Processing during analyse_declarations phase:
399 # Returns (name, type) pair where name is the
400 # CNameDeclaratorNode of the name being declared
401 # and type is the type it is being declared as.
403 # calling_convention string Calling convention of CFuncDeclaratorNode
404 # for which this is a base
408 calling_convention = ""
411 class CNameDeclaratorNode(CDeclaratorNode):
412 # name string The Pyrex name being declared
413 # cname string or None C name, if specified
414 # default ExprNode or None the value assigned on declaration
416 child_attrs = ['default']
420 def analyse(self, base_type, env, nonempty = 0):
421 if nonempty and self.name == '':
422 # May have mistaken the name for the type.
423 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
424 error(self.pos, "Missing argument name")
425 elif base_type.is_void:
426 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
428 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
429 base_type = py_object_type
430 self.type = base_type
431 return self, base_type
433 class CPtrDeclaratorNode(CDeclaratorNode):
434 # base CDeclaratorNode
436 child_attrs = ["base"]
438 def analyse(self, base_type, env, nonempty = 0):
439 if base_type.is_pyobject:
441 "Pointer base type cannot be a Python object")
442 ptr_type = PyrexTypes.c_ptr_type(base_type)
443 return self.base.analyse(ptr_type, env, nonempty = nonempty)
445 class CArrayDeclaratorNode(CDeclaratorNode):
446 # base CDeclaratorNode
449 child_attrs = ["base", "dimension"]
451 def analyse(self, base_type, env, nonempty = 0):
453 self.dimension.analyse_const_expression(env)
454 if not self.dimension.type.is_int:
455 error(self.dimension.pos, "Array dimension not integer")
456 size = self.dimension.get_constant_c_result_code()
465 if not base_type.is_complete():
467 "Array element type '%s' is incomplete" % base_type)
468 if base_type.is_pyobject:
470 "Array element cannot be a Python object")
471 if base_type.is_cfunction:
473 "Array element cannot be a function")
474 array_type = PyrexTypes.c_array_type(base_type, size)
475 return self.base.analyse(array_type, env, nonempty = nonempty)
478 class CFuncDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
480 # args [CArgDeclNode]
481 # has_varargs boolean
482 # exception_value ConstNode
483 # exception_check boolean True if PyErr_Occurred check needed
484 # nogil boolean Can be called without gil
485 # with_gil boolean Acquire gil around function body
487 child_attrs = ["base", "args", "exception_value"]
490 optional_arg_count = 0
492 def analyse(self, return_type, env, nonempty = 0):
496 for arg_node in self.args:
497 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
498 name = name_declarator.name
499 if name_declarator.cname:
501 "Function argument cannot have C name specification")
502 # Turn *[] argument into **
504 type = PyrexTypes.c_ptr_type(type.base_type)
505 # Catch attempted C-style func(void) decl
507 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
508 func_type_args.append(
509 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
511 self.optional_arg_count += 1
512 elif self.optional_arg_count:
513 error(self.pos, "Non-default argument follows default argument")
515 if self.optional_arg_count:
516 scope = StructOrUnionScope()
517 arg_count_member = '%sn' % Naming.pyrex_prefix
518 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
519 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
520 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
521 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
522 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
527 cname = struct_cname)
528 self.op_args_struct.defined_in_pxd = 1
529 self.op_args_struct.used = 1
533 if self.exception_check == '+':
534 env.add_include_file('stdexcept')
535 if return_type.is_pyobject \
536 and (self.exception_value or self.exception_check) \
537 and self.exception_check != '+':
539 "Exception clause not allowed for function returning Python object")
541 if self.exception_value:
542 self.exception_value.analyse_const_expression(env)
543 exc_val = self.exception_value.get_constant_c_result_code()
544 if self.exception_check == '+':
545 exc_val_type = self.exception_value.type
546 if not exc_val_type.is_error and \
547 not exc_val_type.is_pyobject and \
548 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
549 error(self.exception_value.pos,
550 "Exception value must be a Python exception or cdef function with no arguments.")
552 if not return_type.assignable_from(self.exception_value.type):
553 error(self.exception_value.pos,
554 "Exception value incompatible with function return type")
555 exc_check = self.exception_check
556 if return_type.is_array:
558 "Function cannot return an array")
559 if return_type.is_cfunction:
561 "Function cannot return a function")
562 func_type = PyrexTypes.CFuncType(
563 return_type, func_type_args, self.has_varargs,
564 optional_arg_count = self.optional_arg_count,
565 exception_value = exc_val, exception_check = exc_check,
566 calling_convention = self.base.calling_convention,
567 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
568 if self.optional_arg_count:
569 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
570 callspec = env.directives['callspec']
572 current = func_type.calling_convention
573 if current and current != callspec:
574 error(self.pos, "cannot have both '%s' and '%s' "
575 "calling conventions" % (current, callspec))
576 func_type.calling_convention = callspec
577 return self.base.analyse(func_type, env)
580 class CArgDeclNode(Node):
581 # Item in a function declaration argument list.
583 # base_type CBaseTypeNode
584 # declarator CDeclaratorNode
585 # not_none boolean Tagged with 'not None'
586 # default ExprNode or None
587 # default_value PyObjectConst constant for default value
588 # is_self_arg boolean Is the "self" arg of an extension type method
589 # is_kw_only boolean Is a keyword-only argument
591 child_attrs = ["base_type", "declarator", "default"]
596 name_declarator = None
599 def analyse(self, env, nonempty = 0):
600 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
601 if self.type is None:
602 # The parser may missinterpret names as types...
604 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
606 self.declarator.name = self.base_type.name
607 self.base_type.name = None
608 self.base_type.is_basic_c_type = False
611 could_be_name = False
612 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
613 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
614 self.declarator.name = self.base_type.arg_name
615 return self.declarator.analyse(base_type, env, nonempty = nonempty)
617 return self.name_declarator, self.type
619 def calculate_default_value_code(self, code):
620 if self.default_value is None:
622 if self.default.is_literal:
623 # will not output any code, just assign the result_code
624 self.default.generate_evaluation_code(code)
625 return self.type.cast_code(self.default.result())
626 self.default_value = code.get_argument_default_const(self.type)
627 return self.default_value
629 def annotate(self, code):
631 self.default.annotate(code)
634 class CBaseTypeNode(Node):
635 # Abstract base class for C base type nodes.
637 # Processing during analyse_declarations phase:
644 class CAnalysedBaseTypeNode(Node):
649 def analyse(self, env, could_be_name = False):
652 class CSimpleBaseTypeNode(CBaseTypeNode):
654 # module_path [string] Qualifying name components
655 # is_basic_c_type boolean
659 # is_self_arg boolean Is self argument of C method
662 arg_name = None # in case the argument name was interpreted as a type
664 def analyse(self, env, could_be_name = False):
665 # Return type descriptor.
666 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
668 if self.is_basic_c_type:
669 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
671 error(self.pos, "Unrecognised type modifier combination")
672 elif self.name == "object" and not self.module_path:
673 type = py_object_type
674 elif self.name is None:
675 if self.is_self_arg and env.is_c_class_scope:
676 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
677 type = env.parent_type
679 type = py_object_type
682 scope = env.find_imported_module(self.module_path, self.pos)
686 if scope.is_c_class_scope:
687 scope = scope.global_scope()
688 entry = scope.lookup(self.name)
689 if entry and entry.is_type:
692 if self.is_self_arg and env.is_c_class_scope:
693 type = env.parent_type
695 type = py_object_type
696 self.arg_name = self.name
698 error(self.pos, "'%s' is not a type identifier" % self.name)
700 if not type.is_numeric or type.is_complex:
701 error(self.pos, "can only complexify c numeric types")
702 type = PyrexTypes.CComplexType(type)
703 type.create_declaration_utility_code(env)
707 return PyrexTypes.error_type
709 class CBufferAccessTypeNode(CBaseTypeNode):
711 # positional_args [ExprNode] List of positional arguments
712 # keyword_args DictNode Keyword arguments
713 # base_type_node CBaseTypeNode
716 # type PyrexType.BufferType ...containing the right options
719 child_attrs = ["base_type_node", "positional_args",
720 "keyword_args", "dtype_node"]
726 def analyse(self, env, could_be_name = False):
727 base_type = self.base_type_node.analyse(env)
728 if base_type.is_error: return base_type
731 options = Buffer.analyse_buffer_options(
734 self.positional_args,
736 base_type.buffer_defaults)
738 if sys.version_info[0] < 3:
739 # Py 2.x enforces byte strings as keyword arguments ...
740 options = dict([ (name.encode('ASCII'), value)
741 for name, value in options.iteritems() ])
743 self.type = PyrexTypes.BufferType(base_type, **options)
746 class CComplexBaseTypeNode(CBaseTypeNode):
747 # base_type CBaseTypeNode
748 # declarator CDeclaratorNode
750 child_attrs = ["base_type", "declarator"]
752 def analyse(self, env, could_be_name = False):
753 base = self.base_type.analyse(env, could_be_name)
754 _, type = self.declarator.analyse(base, env)
758 class CVarDefNode(StatNode):
759 # C variable definition or forward/extern function declaration.
761 # visibility 'private' or 'public' or 'extern'
762 # base_type CBaseTypeNode
763 # declarators [CDeclaratorNode]
766 # need_properties [entry]
768 # decorators [cython.locals(...)] or None
769 # directive_locals { string : NameNode } locals defined by cython.locals(...)
771 child_attrs = ["base_type", "declarators"]
775 directive_locals = {}
777 def analyse_declarations(self, env, dest_scope = None):
780 self.dest_scope = dest_scope
781 base_type = self.base_type.analyse(env)
783 # If the field is an external typedef, we cannot be sure about the type,
784 # so do conversion ourself rather than rely on the CPython mechanism (through
785 # a property; made in AnalyseDeclarationsTransform).
786 if (dest_scope.is_c_class_scope
787 and self.visibility == 'public'
788 and base_type.is_pyobject
789 and (base_type.is_builtin_type or base_type.is_extension_type)):
790 self.need_properties = []
792 visibility = 'private'
794 need_property = False
795 visibility = self.visibility
797 for declarator in self.declarators:
798 name_declarator, type = declarator.analyse(base_type, env)
799 if not type.is_complete():
800 if not (self.visibility == 'extern' and type.is_array):
801 error(declarator.pos,
802 "Variable type '%s' is incomplete" % type)
803 if self.visibility == 'extern' and type.is_pyobject:
804 error(declarator.pos,
805 "Python object cannot be declared extern")
806 name = name_declarator.name
807 cname = name_declarator.cname
809 error(declarator.pos, "Missing name in declaration.")
811 if type.is_cfunction:
812 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
813 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
815 if entry is not None:
816 entry.directive_locals = self.directive_locals
818 if self.directive_locals:
819 s.error("Decorators can only be followed by functions")
820 if self.in_pxd and self.visibility != 'extern':
822 "Only 'extern' C variable declaration allowed in .pxd file")
823 entry = dest_scope.declare_var(name, type, declarator.pos,
824 cname = cname, visibility = visibility, is_cdef = 1)
826 self.need_properties.append(entry)
827 entry.needs_property = 1
830 class CStructOrUnionDefNode(StatNode):
832 # cname string or None
833 # kind "struct" or "union"
834 # typedef_flag boolean
835 # visibility "public" or "private"
837 # attributes [CVarDefNode] or None
841 child_attrs = ["attributes"]
843 def analyse_declarations(self, env):
845 if self.visibility == 'extern' and self.packed:
846 error(self.pos, "Cannot declare extern struct as 'packed'")
847 if self.attributes is not None:
848 scope = StructOrUnionScope(self.name)
849 self.entry = env.declare_struct_or_union(
850 self.name, self.kind, scope, self.typedef_flag, self.pos,
851 self.cname, visibility = self.visibility, packed = self.packed)
852 if self.attributes is not None:
853 if self.in_pxd and not env.in_cinclude:
854 self.entry.defined_in_pxd = 1
855 for attr in self.attributes:
856 attr.analyse_declarations(env, scope)
857 if self.visibility != 'extern':
858 need_typedef_indirection = False
859 for attr in scope.var_entries:
862 type = type.base_type
863 if type == self.entry.type:
864 error(attr.pos, "Struct cannot contain itself as a member.")
865 if self.typedef_flag:
867 type = type.base_type
868 if type == self.entry.type:
869 need_typedef_indirection = True
870 if need_typedef_indirection:
871 # C can't handle typedef structs that refer to themselves.
872 struct_entry = self.entry
873 self.entry = env.declare_typedef(
874 self.name, struct_entry.type, self.pos,
875 cname = self.cname, visibility='ignore')
876 struct_entry.type.typedef_flag = False
877 # FIXME: this might be considered a hack ;-)
878 struct_entry.cname = struct_entry.type.cname = \
879 '_' + self.entry.type.typedef_cname
881 def analyse_expressions(self, env):
884 def generate_execution_code(self, code):
888 class CEnumDefNode(StatNode):
889 # name string or None
890 # cname string or None
891 # items [CEnumDefItemNode]
892 # typedef_flag boolean
893 # visibility "public" or "private"
897 child_attrs = ["items"]
899 def analyse_declarations(self, env):
900 self.entry = env.declare_enum(self.name, self.pos,
901 cname = self.cname, typedef_flag = self.typedef_flag,
902 visibility = self.visibility)
903 if self.items is not None:
904 if self.in_pxd and not env.in_cinclude:
905 self.entry.defined_in_pxd = 1
906 for item in self.items:
907 item.analyse_declarations(env, self.entry)
909 def analyse_expressions(self, env):
912 def generate_execution_code(self, code):
913 if self.visibility == 'public':
914 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
915 for item in self.entry.enum_values:
916 code.putln("%s = PyInt_FromLong(%s); %s" % (
919 code.error_goto_if_null(temp, item.pos)))
920 code.put_gotref(temp)
921 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
925 code.error_goto(item.pos)))
926 code.put_decref_clear(temp, PyrexTypes.py_object_type)
927 code.funcstate.release_temp(temp)
930 class CEnumDefItemNode(StatNode):
932 # cname string or None
933 # value ExprNode or None
935 child_attrs = ["value"]
937 def analyse_declarations(self, env, enum_entry):
939 self.value.analyse_const_expression(env)
940 if not self.value.type.is_int:
941 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
942 self.value.analyse_const_expression(env)
943 entry = env.declare_const(self.name, enum_entry.type,
944 self.value, self.pos, cname = self.cname,
945 visibility = enum_entry.visibility)
946 enum_entry.enum_values.append(entry)
949 class CTypeDefNode(StatNode):
950 # base_type CBaseTypeNode
951 # declarator CDeclaratorNode
952 # visibility "public" or "private"
955 child_attrs = ["base_type", "declarator"]
957 def analyse_declarations(self, env):
958 base = self.base_type.analyse(env)
959 name_declarator, type = self.declarator.analyse(base, env)
960 name = name_declarator.name
961 cname = name_declarator.cname
962 entry = env.declare_typedef(name, type, self.pos,
963 cname = cname, visibility = self.visibility)
964 if self.in_pxd and not env.in_cinclude:
965 entry.defined_in_pxd = 1
967 def analyse_expressions(self, env):
969 def generate_execution_code(self, code):
973 class FuncDefNode(StatNode, BlockNode):
974 # Base class for function definition nodes.
976 # return_type PyrexType
977 # #filename string C name of filename string const
979 # needs_closure boolean Whether or not this function has inner functions/classes/yield
980 # directive_locals { string : NameNode } locals defined by cython.locals(...)
984 needs_closure = False
987 def analyse_default_values(self, env):
988 genv = env.global_scope()
990 for arg in self.args:
994 arg.default.analyse_types(env)
995 arg.default = arg.default.coerce_to(arg.type, genv)
998 "This argument cannot have a default value")
1003 error(arg.pos, "Non-default argument following default argument")
1005 def need_gil_acquisition(self, lenv):
1008 def create_local_scope(self, env):
1010 while env.is_py_class_scope or env.is_c_class_scope:
1011 env = env.outer_scope
1012 if self.needs_closure:
1013 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1015 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1016 lenv.return_type = self.return_type
1017 type = self.entry.type
1018 if type.is_cfunction:
1019 lenv.nogil = type.nogil and not type.with_gil
1020 self.local_scope = lenv
1021 lenv.directives = env.directives
1024 def generate_function_definitions(self, env, code):
1027 lenv = self.local_scope
1029 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1030 self.entry.scope.is_c_class_scope)
1032 if code.globalstate.directives['profile'] is None:
1033 profile = 'inline' not in self.modifiers and not lenv.nogil
1035 profile = code.globalstate.directives['profile']
1036 if profile and lenv.nogil:
1037 error(self.pos, "Cannot profile nogil function.")
1039 code.globalstate.use_utility_code(trace_utility_code)
1041 # Generate C code for header and body of function
1042 code.enter_cfunc_scope()
1043 code.return_from_error_cleanup_label = code.new_label()
1045 # ----- Top-level constants used by this function
1046 code.mark_pos(self.pos)
1047 self.generate_cached_builtins_decls(lenv, code)
1048 # ----- Function header
1051 self.py_func.generate_function_header(code,
1052 with_pymethdef = env.is_py_class_scope,
1054 self.generate_function_header(code,
1055 with_pymethdef = env.is_py_class_scope)
1056 # ----- Local variable declarations
1057 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1058 self.generate_argument_declarations(lenv, code)
1059 if self.needs_closure:
1060 code.putln("/* TODO: declare and create scope object */")
1061 code.put_var_declarations(lenv.var_entries)
1063 if not self.return_type.is_void:
1064 if self.return_type.is_pyobject:
1068 (self.return_type.declaration_code(
1069 Naming.retval_cname),
1071 tempvardecl_code = code.insertion_point()
1072 self.generate_keyword_list(code)
1073 # ----- Extern library function declarations
1074 lenv.generate_library_function_declarations(code)
1075 # ----- GIL acquisition
1076 acquire_gil = self.acquire_gil
1078 env.use_utility_code(force_init_threads_utility_code)
1079 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1080 # ----- Automatic lead-ins for certain special functions
1082 code.put_trace_call(self.entry.name, self.pos)
1084 code.put_setup_refcount_context(self.entry.name)
1085 if is_getbuffer_slot:
1086 self.getbuffer_init(code)
1087 # ----- Fetch arguments
1088 self.generate_argument_parsing_code(env, code)
1089 # If an argument is assigned to in the body, we must
1090 # incref it to properly keep track of refcounts.
1091 for entry in lenv.arg_entries:
1092 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1093 code.put_var_incref(entry)
1094 # ----- Initialise local variables
1095 for entry in lenv.var_entries:
1096 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1097 code.put_init_var_to_py_none(entry)
1098 # ----- Initialise local buffer auxiliary variables
1099 for entry in lenv.var_entries + lenv.arg_entries:
1100 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1101 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1102 # ----- Check and convert arguments
1103 self.generate_argument_type_tests(code)
1104 # ----- Acquire buffer arguments
1105 for entry in lenv.arg_entries:
1106 if entry.type.is_buffer:
1107 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1108 # ----- Function body
1109 self.body.generate_execution_code(code)
1110 # ----- Default return value
1112 if self.return_type.is_pyobject:
1113 #if self.return_type.is_extension_type:
1114 # lhs = "(PyObject *)%s" % Naming.retval_cname
1116 lhs = Naming.retval_cname
1117 code.put_init_to_py_none(lhs, self.return_type)
1119 val = self.return_type.default_value
1121 code.putln("%s = %s;" % (Naming.retval_cname, val))
1122 # ----- Error cleanup
1123 if code.error_label in code.labels_used:
1124 code.put_goto(code.return_label)
1125 code.put_label(code.error_label)
1126 for cname, type in code.funcstate.all_managed_temps():
1127 code.put_xdecref(cname, type)
1129 # Clean up buffers -- this calls a Python function
1130 # so need to save and restore error state
1131 buffers_present = len(lenv.buffer_entries) > 0
1133 code.globalstate.use_utility_code(restore_exception_utility_code)
1134 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1135 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1136 for entry in lenv.buffer_entries:
1137 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1138 #code.putln("%s = 0;" % entry.cname)
1139 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1141 err_val = self.error_value()
1142 exc_check = self.caller_will_check_exceptions()
1143 if err_val is not None or exc_check:
1144 # TODO: Fix exception tracing (though currently unused by cProfile).
1145 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1146 # code.put_trace_exception()
1147 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1149 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1150 % self.entry.qualified_name, 0)
1152 '__Pyx_WriteUnraisable("%s");' %
1153 self.entry.qualified_name)
1154 env.use_utility_code(unraisable_exception_utility_code)
1155 env.use_utility_code(restore_exception_utility_code)
1156 default_retval = self.return_type.default_value
1157 if err_val is None and default_retval:
1158 err_val = default_retval
1159 if err_val is not None:
1162 Naming.retval_cname,
1165 if is_getbuffer_slot:
1166 self.getbuffer_error_cleanup(code)
1168 # If we are using the non-error cleanup section we should
1169 # jump past it if we have an error. The if-test below determine
1170 # whether this section is used.
1171 if buffers_present or is_getbuffer_slot:
1172 code.put_goto(code.return_from_error_cleanup_label)
1175 # ----- Non-error return cleanup
1176 code.put_label(code.return_label)
1177 for entry in lenv.buffer_entries:
1179 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1180 if is_getbuffer_slot:
1181 self.getbuffer_normal_cleanup(code)
1182 # ----- Return cleanup for both error and no-error return
1183 code.put_label(code.return_from_error_cleanup_label)
1184 if not Options.init_local_none:
1185 for entry in lenv.var_entries:
1186 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1187 entry.xdecref_cleanup = 1
1188 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1189 # Decref any increfed args
1190 for entry in lenv.arg_entries:
1191 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1192 code.put_var_decref(entry)
1194 # code.putln("/* TODO: decref scope object */")
1196 # This code is duplicated in ModuleNode.generate_module_init_func
1198 default_retval = self.return_type.default_value
1199 err_val = self.error_value()
1200 if err_val is None and default_retval:
1201 err_val = default_retval
1202 if self.return_type.is_pyobject:
1203 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1205 code.put_finish_refcount_context()
1207 if self.entry.is_special and self.entry.name == "__hash__":
1208 # Returning -1 for __hash__ is supposed to signal an error
1209 # We do as Python instances and coerce -1 into -2.
1210 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1213 if self.return_type.is_pyobject:
1214 code.put_trace_return(Naming.retval_cname)
1216 code.put_trace_return("Py_None")
1219 code.putln("PyGILState_Release(_save);")
1221 if not self.return_type.is_void:
1222 code.putln("return %s;" % Naming.retval_cname)
1225 # ----- Go back and insert temp variable declarations
1226 tempvardecl_code.put_temp_declarations(code.funcstate)
1227 # ----- Python version
1228 code.exit_cfunc_scope()
1230 self.py_func.generate_function_definitions(env, code)
1231 self.generate_wrapper_functions(code)
1233 def declare_argument(self, env, arg):
1234 if arg.type.is_void:
1235 error(arg.pos, "Invalid use of 'void'")
1236 elif not arg.type.is_complete() and not arg.type.is_array:
1238 "Argument type '%s' is incomplete" % arg.type)
1239 return env.declare_arg(arg.name, arg.type, arg.pos)
1241 def generate_wrapper_functions(self, code):
1244 def generate_execution_code(self, code):
1245 # Evaluate and store argument default values
1246 for arg in self.args:
1247 default = arg.default
1249 if not default.is_literal:
1250 default.generate_evaluation_code(code)
1251 default.make_owned_reference(code)
1252 result = default.result_as(arg.type)
1255 arg.calculate_default_value_code(code),
1257 if arg.type.is_pyobject:
1258 code.put_giveref(default.result())
1259 default.generate_post_assignment_code(code)
1260 default.free_temps(code)
1261 # For Python class methods, create and store function object
1263 self.assmt.generate_execution_code(code)
1266 # Special code for the __getbuffer__ function
1268 def getbuffer_init(self, code):
1269 info = self.local_scope.arg_entries[1].cname
1270 # Python 3.0 betas have a bug in memoryview which makes it call
1271 # getbuffer with a NULL parameter. For now we work around this;
1272 # the following line should be removed when this bug is fixed.
1273 code.putln("if (%s == NULL) return 0;" % info)
1274 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1275 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1277 def getbuffer_error_cleanup(self, code):
1278 info = self.local_scope.arg_entries[1].cname
1279 code.put_gotref("%s->obj" % info)
1280 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1283 def getbuffer_normal_cleanup(self, code):
1284 info = self.local_scope.arg_entries[1].cname
1285 code.putln("if (%s->obj == Py_None) {" % info)
1286 code.put_gotref("Py_None")
1287 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1290 class CFuncDefNode(FuncDefNode):
1291 # C function definition.
1293 # modifiers ['inline']
1294 # visibility 'private' or 'public' or 'extern'
1295 # base_type CBaseTypeNode
1296 # declarator CDeclaratorNode
1299 # decorators [DecoratorNode] list of decorators
1301 # with_gil boolean Acquire GIL around body
1303 # py_func wrapper for calling from Python
1304 # overridable whether or not this is a cpdef function
1305 # inline_in_pxd whether this is an inline function in a pxd file
1307 child_attrs = ["base_type", "declarator", "body", "py_func"]
1309 inline_in_pxd = False
1311 directive_locals = {}
1313 def unqualified_name(self):
1314 return self.entry.name
1316 def analyse_declarations(self, env):
1317 self.directive_locals.update(env.directives['locals'])
1318 base_type = self.base_type.analyse(env)
1319 # The 2 here is because we need both function and argument names.
1320 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1321 if not type.is_cfunction:
1323 "Suite attached to non-function declaration")
1324 # Remember the actual type according to the function header
1325 # written here, because the type in the symbol table entry
1326 # may be different if we're overriding a C method inherited
1327 # from the base type of an extension type.
1329 type.is_overridable = self.overridable
1330 declarator = self.declarator
1331 while not hasattr(declarator, 'args'):
1332 declarator = declarator.base
1333 self.args = declarator.args
1334 for formal_arg, type_arg in zip(self.args, type.args):
1335 formal_arg.type = type_arg.type
1336 formal_arg.name = type_arg.name
1337 formal_arg.cname = type_arg.cname
1338 name = name_declarator.name
1339 cname = name_declarator.cname
1340 self.entry = env.declare_cfunction(
1341 name, type, self.pos,
1342 cname = cname, visibility = self.visibility,
1343 defining = self.body is not None,
1344 api = self.api, modifiers = self.modifiers)
1345 self.entry.inline_func_in_pxd = self.inline_in_pxd
1346 self.return_type = type.return_type
1348 if self.overridable and not env.is_module_scope:
1349 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1350 # An error will be produced in the cdef function
1351 self.overridable = False
1353 if self.overridable:
1355 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1356 self.py_func = DefNode(pos = self.pos,
1357 name = self.entry.name,
1360 starstar_arg = None,
1362 body = py_func_body,
1364 self.py_func.is_module_scope = env.is_module_scope
1365 self.py_func.analyse_declarations(env)
1366 self.entry.as_variable = self.py_func.entry
1367 # Reset scope entry the above cfunction
1368 env.entries[name] = self.entry
1369 if not env.is_module_scope or Options.lookup_module_cpdef:
1370 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1371 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1373 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1375 args = self.type.args
1376 if omit_optional_args:
1377 args = args[:len(args) - self.type.optional_arg_count]
1378 arg_names = [arg.name for arg in args]
1380 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1382 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1383 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1384 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1385 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)
1386 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1388 def declare_arguments(self, env):
1389 for arg in self.type.args:
1391 error(arg.pos, "Missing argument name")
1392 self.declare_argument(env, arg)
1394 def need_gil_acquisition(self, lenv):
1395 return self.type.with_gil
1397 def nogil_check(self, env):
1399 with_gil = type.with_gil
1400 if type.nogil and not with_gil:
1401 if type.return_type.is_pyobject:
1403 "Function with Python return type cannot be declared nogil")
1404 for entry in self.local_scope.var_entries:
1405 if entry.type.is_pyobject:
1406 error(self.pos, "Function declared nogil has Python locals or temporaries")
1408 def analyse_expressions(self, env):
1409 self.local_scope.directives = env.directives
1410 if self.py_func is not None:
1411 # this will also analyse the default values
1412 self.py_func.analyse_expressions(env)
1414 self.analyse_default_values(env)
1415 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1417 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1420 visibility = self.entry.visibility
1421 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1422 arg_decls.append(arg.declaration_code())
1423 if with_dispatch and self.overridable:
1424 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1425 if type.optional_arg_count and with_opt_args:
1426 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1427 if type.has_varargs:
1428 arg_decls.append("...")
1430 arg_decls = ["void"]
1432 cname = self.entry.func_cname
1433 entity = type.function_header_code(cname, ', '.join(arg_decls))
1434 if visibility == 'public':
1435 dll_linkage = "DL_EXPORT"
1438 header = self.return_type.declaration_code(entity,
1439 dll_linkage = dll_linkage)
1440 if visibility == 'extern':
1441 storage_class = "%s " % Naming.extern_c_macro
1442 elif visibility == 'public':
1445 storage_class = "static "
1446 code.putln("%s%s %s {" % (
1448 ' '.join(self.modifiers).upper(), # macro forms
1451 def generate_argument_declarations(self, env, code):
1452 for arg in self.args:
1454 result = arg.calculate_default_value_code(code)
1455 code.putln('%s = %s;' % (
1456 arg.type.declaration_code(arg.cname), result))
1458 def generate_keyword_list(self, code):
1461 def generate_argument_parsing_code(self, env, code):
1463 if self.type.optional_arg_count:
1464 code.putln('if (%s) {' % Naming.optional_args_cname)
1465 for arg in self.args:
1467 # FIXME: simple name prefixing doesn't work when
1468 # argument name mangling is in place
1469 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1470 declarator = arg.declarator
1471 while not hasattr(declarator, 'name'):
1472 declarator = declarator.base
1473 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1475 for _ in range(self.type.optional_arg_count):
1479 def generate_argument_conversion_code(self, code):
1482 def generate_argument_type_tests(self, code):
1483 # Generate type tests for args whose type in a parent
1484 # class is a supertype of the declared type.
1485 for arg in self.type.args:
1486 if arg.needs_type_test:
1487 self.generate_arg_type_test(arg, code)
1489 def generate_arg_type_test(self, arg, code):
1490 # Generate type test for one argument.
1491 if arg.type.typeobj_is_available():
1492 typeptr_cname = arg.type.typeptr_cname
1493 arg_code = "((PyObject *)%s)" % arg.cname
1495 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1500 type.is_builtin_type,
1501 code.error_goto(arg.pos)))
1503 error(arg.pos, "Cannot test type of extern C class "
1504 "without type object name specification")
1506 def error_value(self):
1507 if self.return_type.is_pyobject:
1511 return self.entry.type.exception_value
1513 def caller_will_check_exceptions(self):
1514 return self.entry.type.exception_check
1516 def generate_wrapper_functions(self, code):
1517 # If the C signature of a function has changed, we need to generate
1518 # wrappers to put in the slots here.
1521 func_type = entry.type
1522 while entry.prev_entry is not None:
1524 entry = entry.prev_entry
1525 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1527 self.generate_function_header(code,
1529 with_dispatch = entry.type.is_overridable,
1530 with_opt_args = entry.type.optional_arg_count,
1531 cname = entry.func_cname)
1532 if not self.return_type.is_void:
1534 args = self.type.args
1535 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1536 if entry.type.is_overridable:
1537 arglist.append(Naming.skip_dispatch_cname)
1538 elif func_type.is_overridable:
1540 if entry.type.optional_arg_count:
1541 arglist.append(Naming.optional_args_cname)
1542 elif func_type.optional_arg_count:
1543 arglist.append('NULL')
1544 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1548 class PyArgDeclNode(Node):
1549 # Argument which must be a Python object (used
1550 # for * and ** arguments).
1553 # entry Symtab.Entry
1557 class DecoratorNode(Node):
1560 # decorator NameNode or CallNode
1561 child_attrs = ['decorator']
1564 class DefNode(FuncDefNode):
1565 # A Python function definition.
1567 # name string the Python name of the function
1568 # decorators [DecoratorNode] list of decorators
1569 # args [CArgDeclNode] formal arguments
1570 # star_arg PyArgDeclNode or None * argument
1571 # starstar_arg PyArgDeclNode or None ** argument
1572 # doc EncodedString or None
1575 # The following subnode is constructed internally
1576 # when the def statement is inside a Python class definition.
1578 # assmt AssignmentNode Function construction/assignment
1580 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1584 num_required_kw_args = 0
1585 reqd_kw_flags_cname = "0"
1592 def __init__(self, pos, **kwds):
1593 FuncDefNode.__init__(self, pos, **kwds)
1595 for arg in self.args:
1602 self.num_kwonly_args = k
1603 self.num_required_kw_args = rk
1604 self.num_required_args = r
1606 def as_cfunction(self, cfunc=None, scope=None):
1608 error(self.star_arg.pos, "cdef function cannot have star argument")
1609 if self.starstar_arg:
1610 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1613 for formal_arg in self.args:
1614 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1615 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1617 type = py_object_type,
1618 pos = formal_arg.pos))
1619 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1621 has_varargs = False,
1622 exception_value = None,
1623 exception_check = False,
1626 is_overridable = True)
1627 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1629 cfunc_type = cfunc.type
1630 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1631 error(self.pos, "wrong number of arguments")
1632 error(declarator.pos, "previous declaration here")
1633 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1634 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1635 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1636 formal_arg.type = type_arg.type
1637 formal_arg.name_declarator = name_declarator
1639 if cfunc_type.exception_value is None:
1640 exception_value = None
1642 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1643 declarator = CFuncDeclaratorNode(self.pos,
1644 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1646 has_varargs = False,
1647 exception_check = cfunc_type.exception_check,
1648 exception_value = exception_value,
1649 with_gil = cfunc_type.with_gil,
1650 nogil = cfunc_type.nogil)
1651 return CFuncDefNode(self.pos,
1653 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1654 declarator = declarator,
1657 overridable = cfunc_type.is_overridable,
1659 with_gil = cfunc_type.with_gil,
1660 nogil = cfunc_type.nogil,
1661 visibility = 'private',
1663 directive_locals = getattr(cfunc, 'directive_locals', {}))
1665 def analyse_declarations(self, env):
1666 directive_locals = self.directive_locals = env.directives['locals']
1667 for arg in self.args:
1668 if hasattr(arg, 'name'):
1670 name_declarator = None
1672 base_type = arg.base_type.analyse(env)
1673 name_declarator, type = \
1674 arg.declarator.analyse(base_type, env)
1675 arg.name = name_declarator.name
1676 if arg.name in directive_locals:
1677 type_node = directive_locals[arg.name]
1678 other_type = type_node.analyse_as_type(env)
1679 if other_type is None:
1680 error(type_node.pos, "Not a type")
1681 elif (type is not PyrexTypes.py_object_type
1682 and not type.same_as(other_type)):
1683 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1684 error(type_node.pos, "Previous declaration here")
1687 if name_declarator and name_declarator.cname:
1689 "Python function argument cannot have C name specification")
1690 arg.type = type.as_argument_type()
1692 arg.needs_conversion = 0
1693 arg.needs_type_test = 0
1695 if arg.not_none and not arg.type.is_extension_type:
1697 "Only extension type arguments can have 'not None'")
1698 self.declare_pyfunction(env)
1699 self.analyse_signature(env)
1700 self.return_type = self.entry.signature.return_type()
1702 def analyse_signature(self, env):
1703 any_type_tests_needed = 0
1704 if self.entry.is_special:
1705 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1706 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1707 # Use the simpler calling signature for zero- and one-argument functions.
1708 if self.entry.signature is TypeSlots.pyfunction_signature:
1709 if len(self.args) == 0:
1710 self.entry.signature = TypeSlots.pyfunction_noargs
1711 elif len(self.args) == 1:
1712 if self.args[0].default is None and not self.args[0].kw_only:
1713 self.entry.signature = TypeSlots.pyfunction_onearg
1714 elif self.entry.signature is TypeSlots.pymethod_signature:
1715 if len(self.args) == 1:
1716 self.entry.signature = TypeSlots.unaryfunc
1717 elif len(self.args) == 2:
1718 if self.args[1].default is None and not self.args[1].kw_only:
1719 self.entry.signature = TypeSlots.ibinaryfunc
1720 sig = self.entry.signature
1721 nfixed = sig.num_fixed_args()
1722 for i in range(nfixed):
1723 if i < len(self.args):
1726 if sig.is_self_arg(i):
1728 arg.hdr_type = arg.type = env.parent_type
1729 arg.needs_conversion = 0
1731 arg.hdr_type = sig.fixed_arg_type(i)
1732 if not arg.type.same_as(arg.hdr_type):
1733 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1734 arg.needs_type_test = 1
1735 any_type_tests_needed = 1
1737 arg.needs_conversion = 1
1738 if arg.needs_conversion:
1739 arg.hdr_cname = Naming.arg_prefix + arg.name
1741 arg.hdr_cname = Naming.var_prefix + arg.name
1743 self.bad_signature()
1745 if nfixed < len(self.args):
1746 if not sig.has_generic_args:
1747 self.bad_signature()
1748 for arg in self.args:
1749 if arg.is_generic and \
1750 (arg.type.is_extension_type or arg.type.is_builtin_type):
1751 arg.needs_type_test = 1
1752 any_type_tests_needed = 1
1753 if any_type_tests_needed:
1754 env.use_utility_code(arg_type_test_utility_code)
1756 def bad_signature(self):
1757 sig = self.entry.signature
1758 expected_str = "%d" % sig.num_fixed_args()
1759 if sig.has_generic_args:
1760 expected_str = expected_str + " or more"
1762 if name.startswith("__") and name.endswith("__"):
1763 desc = "Special method"
1767 "%s %s has wrong number of arguments "
1768 "(%d declared, %s expected)" % (
1769 desc, self.name, len(self.args), expected_str))
1771 def signature_has_nongeneric_args(self):
1772 argcount = len(self.args)
1773 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1777 def signature_has_generic_args(self):
1778 return self.entry.signature.has_generic_args
1780 def declare_pyfunction(self, env):
1781 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1783 entry = env.lookup_here(self.name)
1784 if entry and entry.type.is_cfunction and not self.is_wrapper:
1785 warning(self.pos, "Overriding cdef method with def method.", 5)
1786 entry = env.declare_pyfunction(self.name, self.pos)
1788 prefix = env.scope_prefix
1789 entry.func_cname = \
1790 Naming.pyfunc_prefix + prefix + name
1791 entry.pymethdef_cname = \
1792 Naming.pymethdef_prefix + prefix + name
1793 if Options.docstrings:
1794 entry.doc = embed_position(self.pos, self.doc)
1796 Naming.funcdoc_prefix + prefix + name
1800 def declare_arguments(self, env):
1801 for arg in self.args:
1803 error(arg.pos, "Missing argument name")
1804 if arg.needs_conversion:
1805 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1806 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1807 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1808 if arg.type.is_pyobject:
1809 arg.entry.init = "0"
1810 arg.entry.init_to_none = 0
1812 arg.entry = self.declare_argument(env, arg)
1814 arg.entry.is_self_arg = arg.is_self_arg
1816 if arg.is_self_arg or \
1817 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1818 arg.entry.is_declared_generic = 1
1819 self.declare_python_arg(env, self.star_arg)
1820 self.declare_python_arg(env, self.starstar_arg)
1822 def declare_python_arg(self, env, arg):
1824 entry = env.declare_var(arg.name,
1825 PyrexTypes.py_object_type, arg.pos)
1828 entry.init_to_none = 0
1829 entry.xdecref_cleanup = 1
1831 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1833 def analyse_expressions(self, env):
1834 self.local_scope.directives = env.directives
1835 self.analyse_default_values(env)
1836 if env.is_py_class_scope:
1837 self.synthesize_assignment_node(env)
1839 def synthesize_assignment_node(self, env):
1841 self.assmt = SingleAssignmentNode(self.pos,
1842 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1843 rhs = ExprNodes.UnboundMethodNode(self.pos,
1844 function = ExprNodes.PyCFunctionNode(self.pos,
1845 pymethdef_cname = self.entry.pymethdef_cname)))
1846 self.assmt.analyse_declarations(env)
1847 self.assmt.analyse_expressions(env)
1849 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1851 sig = self.entry.signature
1852 if sig.has_dummy_arg:
1853 arg_code_list.append(
1854 "PyObject *%s" % Naming.self_cname)
1855 for arg in self.args:
1856 if not arg.is_generic:
1858 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1860 arg_code_list.append(
1861 arg.hdr_type.declaration_code(arg.hdr_cname))
1862 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1863 arg_code_list.append("PyObject *unused")
1864 if sig.has_generic_args:
1865 arg_code_list.append(
1866 "PyObject *%s, PyObject *%s"
1867 % (Naming.args_cname, Naming.kwds_cname))
1868 arg_code = ", ".join(arg_code_list)
1869 dc = self.return_type.declaration_code(self.entry.func_cname)
1870 header = "static %s(%s)" % (dc, arg_code)
1871 code.putln("%s; /*proto*/" % header)
1874 if self.entry.doc and Options.docstrings:
1875 docstr = self.entry.doc
1876 if docstr.is_unicode:
1877 docstr = docstr.utf8encode()
1879 'static char %s[] = "%s";' % (
1880 self.entry.doc_cname,
1881 split_docstring(escape_byte_string(docstr))))
1884 "static PyMethodDef %s = " %
1885 self.entry.pymethdef_cname)
1886 code.put_pymethoddef(self.entry, ";")
1887 code.putln("%s {" % header)
1889 def generate_argument_declarations(self, env, code):
1890 for arg in self.args:
1891 if arg.is_generic: # or arg.needs_conversion:
1892 if arg.needs_conversion:
1893 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1895 code.put_var_declaration(arg.entry)
1897 def generate_keyword_list(self, code):
1898 if self.signature_has_generic_args() and \
1899 self.signature_has_nongeneric_args():
1901 "static PyObject **%s[] = {" %
1902 Naming.pykwdlist_cname)
1903 for arg in self.args:
1905 pystring_cname = code.intern_identifier(arg.name)
1906 code.put('&%s,' % pystring_cname)
1909 def generate_argument_parsing_code(self, env, code):
1910 # Generate PyArg_ParseTuple call for generic
1911 # arguments, if any.
1912 if self.entry.signature.has_dummy_arg:
1913 # get rid of unused argument warning
1914 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1916 old_error_label = code.new_error_label()
1917 our_error_label = code.error_label
1918 end_label = code.new_label("argument_unpacking_done")
1920 has_kwonly_args = self.num_kwonly_args > 0
1921 has_star_or_kw_args = self.star_arg is not None \
1922 or self.starstar_arg is not None or has_kwonly_args
1924 for arg in self.args:
1925 if not arg.type.is_pyobject:
1926 done = arg.type.create_from_py_utility_code(env)
1927 if not done: pass # will fail later
1929 if not self.signature_has_generic_args():
1930 if has_star_or_kw_args:
1931 error(self.pos, "This method cannot have * or keyword arguments")
1932 self.generate_argument_conversion_code(code)
1934 elif not self.signature_has_nongeneric_args():
1935 # func(*args) or func(**kw) or func(*args, **kw)
1936 self.generate_stararg_copy_code(code)
1939 positional_args = []
1941 for arg in self.args:
1942 arg_entry = arg.entry
1945 if not arg.is_self_arg:
1947 kw_only_args.append(arg)
1949 positional_args.append(arg)
1951 kw_only_args.append(arg)
1952 elif not arg.is_self_arg:
1953 positional_args.append(arg)
1955 self.generate_tuple_and_keyword_parsing_code(
1956 positional_args, kw_only_args, end_label, code)
1958 code.error_label = old_error_label
1959 if code.label_used(our_error_label):
1960 if not code.label_used(end_label):
1961 code.put_goto(end_label)
1962 code.put_label(our_error_label)
1963 if has_star_or_kw_args:
1964 self.generate_arg_decref(self.star_arg, code)
1965 if self.starstar_arg:
1966 if self.starstar_arg.entry.xdecref_cleanup:
1967 code.put_var_xdecref(self.starstar_arg.entry)
1969 code.put_var_decref(self.starstar_arg.entry)
1970 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1971 code.putln("return %s;" % self.error_value())
1972 if code.label_used(end_label):
1973 code.put_label(end_label)
1975 def generate_arg_assignment(self, arg, item, code):
1976 if arg.type.is_pyobject:
1978 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1979 code.putln("%s = %s;" % (arg.entry.cname, item))
1981 func = arg.type.from_py_function
1983 code.putln("%s = %s(%s); %s" % (
1987 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1989 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1991 def generate_arg_xdecref(self, arg, code):
1993 code.put_var_xdecref(arg.entry)
1995 def generate_arg_decref(self, arg, code):
1997 code.put_var_decref(arg.entry)
1999 def generate_stararg_copy_code(self, code):
2000 if not self.star_arg:
2001 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2002 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2004 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2005 self.name, Naming.args_cname, self.error_value()))
2008 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2010 if self.starstar_arg:
2012 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2014 kwarg_check = "%s" % Naming.kwds_cname
2016 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2017 Naming.kwds_cname, Naming.kwds_cname)
2019 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2020 kwarg_check, Naming.kwds_cname, self.name,
2021 bool(self.starstar_arg), self.error_value()))
2023 if self.starstar_arg:
2024 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2025 self.starstar_arg.entry.cname,
2028 code.putln("if (unlikely(!%s)) return %s;" % (
2029 self.starstar_arg.entry.cname, self.error_value()))
2030 self.starstar_arg.entry.xdecref_cleanup = 0
2031 code.put_gotref(self.starstar_arg.entry.cname)
2035 code.put_incref(Naming.args_cname, py_object_type)
2036 code.putln("%s = %s;" % (
2037 self.star_arg.entry.cname,
2039 self.star_arg.entry.xdecref_cleanup = 0
2041 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2042 kw_only_args, success_label, code):
2043 argtuple_error_label = code.new_label("argtuple_error")
2045 min_positional_args = self.num_required_args - self.num_required_kw_args
2046 if len(self.args) > 0 and self.args[0].is_self_arg:
2047 min_positional_args -= 1
2048 max_positional_args = len(positional_args)
2049 has_fixed_positional_count = not self.star_arg and \
2050 min_positional_args == max_positional_args
2052 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2053 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2054 if self.num_required_kw_args:
2055 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2057 if self.starstar_arg or self.star_arg:
2058 self.generate_stararg_init_code(max_positional_args, code)
2060 # --- optimised code when we receive keyword arguments
2061 if self.num_required_kw_args:
2062 likely_hint = "likely"
2064 likely_hint = "unlikely"
2065 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2066 self.generate_keyword_unpacking_code(
2067 min_positional_args, max_positional_args,
2068 has_fixed_positional_count,
2069 positional_args, kw_only_args, argtuple_error_label, code)
2071 # --- optimised code when we do not receive any keyword arguments
2072 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2073 # Python raises arg tuple related errors first, so we must
2074 # check the length here
2075 if min_positional_args == max_positional_args and not self.star_arg:
2079 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2080 Naming.args_cname, compare, min_positional_args))
2081 code.put_goto(argtuple_error_label)
2083 if self.num_required_kw_args:
2084 # pure error case: keywords required but not passed
2085 if max_positional_args > min_positional_args and not self.star_arg:
2086 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2087 Naming.args_cname, max_positional_args))
2088 code.put_goto(argtuple_error_label)
2089 code.putln('} else {')
2090 for i, arg in enumerate(kw_only_args):
2092 pystring_cname = code.intern_identifier(arg.name)
2093 # required keyword-only argument missing
2094 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2097 code.putln(code.error_goto(self.pos))
2100 elif min_positional_args == max_positional_args:
2101 # parse the exact number of positional arguments from the
2103 code.putln('} else {')
2104 for i, arg in enumerate(positional_args):
2105 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2106 self.generate_arg_assignment(arg, item, code)
2107 self.generate_arg_default_assignments(code)
2110 # parse the positional arguments from the variable length
2112 code.putln('} else {')
2113 self.generate_arg_default_assignments(code)
2114 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2116 code.putln('default:')
2117 reversed_args = list(enumerate(positional_args))[::-1]
2118 for i, arg in reversed_args:
2119 if i >= min_positional_args-1:
2120 if min_positional_args > 1:
2121 code.putln('case %2d:' % (i+1)) # pure code beautification
2123 code.put('case %2d: ' % (i+1))
2124 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2125 self.generate_arg_assignment(arg, item, code)
2126 if min_positional_args == 0:
2127 code.put('case 0: ')
2128 code.putln('break;')
2130 if min_positional_args:
2131 for i in range(min_positional_args-1, -1, -1):
2132 code.putln('case %2d:' % i)
2133 code.put_goto(argtuple_error_label)
2135 code.put('default: ')
2136 code.put_goto(argtuple_error_label)
2141 if code.label_used(argtuple_error_label):
2142 code.put_goto(success_label)
2143 code.put_label(argtuple_error_label)
2144 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2145 self.name, has_fixed_positional_count,
2146 min_positional_args, max_positional_args,
2148 code.putln(code.error_goto(self.pos))
2150 def generate_arg_default_assignments(self, code):
2151 for arg in self.args:
2152 if arg.is_generic and arg.default:
2156 arg.calculate_default_value_code(code)))
2158 def generate_stararg_init_code(self, max_positional_args, code):
2159 if self.starstar_arg:
2160 self.starstar_arg.entry.xdecref_cleanup = 0
2161 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2162 self.starstar_arg.entry.cname,
2163 self.starstar_arg.entry.cname,
2164 self.error_value()))
2165 code.put_gotref(self.starstar_arg.entry.cname)
2167 self.star_arg.entry.xdecref_cleanup = 0
2168 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2170 max_positional_args))
2171 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2172 self.star_arg.entry.cname, Naming.args_cname,
2173 max_positional_args, Naming.args_cname))
2174 code.put_gotref(self.star_arg.entry.cname)
2175 if self.starstar_arg:
2177 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2178 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2179 code.putln('return %s;' % self.error_value())
2182 code.putln("if (unlikely(!%s)) return %s;" % (
2183 self.star_arg.entry.cname, self.error_value()))
2184 code.putln('} else {')
2185 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2186 code.put_incref(Naming.empty_tuple, py_object_type)
2189 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2190 has_fixed_positional_count, positional_args,
2191 kw_only_args, argtuple_error_label, code):
2192 all_args = tuple(positional_args) + tuple(kw_only_args)
2193 max_args = len(all_args)
2196 for i, arg in enumerate(all_args):
2197 if arg.default and arg.type.is_pyobject:
2198 default_value = arg.calculate_default_value_code(code)
2199 if arg.type is not PyrexTypes.py_object_type:
2200 default_value = "(PyObject*)"+default_value
2201 default_args.append((i, default_value))
2203 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2205 # it looks funny to separate the init-to-0 from setting the
2206 # default value, but C89 needs this
2207 code.putln("PyObject* values[%d] = {%s};" % (
2208 max_args, ','.join(['0']*max_args)))
2209 for i, default_value in default_args:
2210 code.putln('values[%d] = %s;' % (i, default_value))
2212 # parse the tuple and check that it's not too long
2213 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2215 code.putln('default:')
2216 for i in range(max_positional_args-1, -1, -1):
2217 code.put('case %2d: ' % (i+1))
2218 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2219 i, Naming.args_cname, i))
2220 code.putln('case 0: break;')
2221 if not self.star_arg:
2222 code.put('default: ') # more arguments than allowed
2223 code.put_goto(argtuple_error_label)
2226 # now fill up the positional/required arguments with values
2228 if self.num_required_args or max_positional_args > 0:
2229 last_required_arg = -1
2230 for i, arg in enumerate(all_args):
2232 last_required_arg = i
2233 if last_required_arg < max_positional_args:
2234 last_required_arg = max_positional_args-1
2235 num_required_args = self.num_required_args
2236 if max_positional_args > 0:
2237 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2238 for i, arg in enumerate(all_args[:last_required_arg+1]):
2239 if max_positional_args > 0 and i <= max_positional_args:
2240 if self.star_arg and i == max_positional_args:
2241 code.putln('default:')
2243 code.putln('case %2d:' % i)
2244 pystring_cname = code.intern_identifier(arg.name)
2247 # handled separately below
2249 code.putln('if (kw_args > %d) {' % num_required_args)
2250 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2251 Naming.kwds_cname, pystring_cname))
2252 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2255 num_required_args -= 1
2256 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2257 i, Naming.kwds_cname, pystring_cname))
2258 code.putln('if (likely(values[%d])) kw_args--;' % i);
2259 if i < min_positional_args:
2261 # special case: we know arg 0 is missing
2263 code.put_goto(argtuple_error_label)
2265 # print the correct number of values (args or
2266 # kwargs) that were passed into positional
2267 # arguments up to this point
2268 code.putln('else {')
2269 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2270 self.name, has_fixed_positional_count,
2271 min_positional_args, max_positional_args, i))
2272 code.putln(code.error_goto(self.pos))
2275 code.putln('else {')
2276 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2277 self.name, pystring_cname))
2278 code.putln(code.error_goto(self.pos))
2280 if max_positional_args > 0:
2283 if kw_only_args and not self.starstar_arg:
2284 # unpack optional keyword-only arguments
2285 # checking for interned strings in a dict is faster than iterating
2286 # but it's too likely that we must iterate if we expect **kwargs
2288 for i, arg in enumerate(all_args[max_positional_args:]):
2289 if not arg.kw_only or not arg.default:
2291 optional_args.append((i+max_positional_args, arg))
2293 # this mimics an unrolled loop so that we can "break" out of it
2294 code.putln('while (kw_args > 0) {')
2295 code.putln('PyObject* value;')
2296 for i, arg in optional_args:
2297 pystring_cname = code.intern_identifier(arg.name)
2299 'value = PyDict_GetItem(%s, %s);' % (
2300 Naming.kwds_cname, pystring_cname))
2302 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2303 code.putln('break;')
2306 code.putln('if (unlikely(kw_args > 0)) {')
2307 # non-positional/-required kw args left in dict: default args,
2308 # kw-only args, **kwargs or error
2310 # This is sort of a catch-all: except for checking required
2311 # arguments, this will always do the right thing for unpacking
2312 # keyword arguments, so that we can concentrate on optimising
2313 # common cases above.
2314 if max_positional_args == 0:
2317 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2318 Naming.args_cname, max_positional_args,
2319 Naming.args_cname, max_positional_args))
2320 pos_arg_count = "used_pos_args"
2322 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2323 code.globalstate.use_utility_code(parse_keywords_utility_code)
2325 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2327 Naming.pykwdlist_cname,
2328 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2331 code.putln(code.error_goto(self.pos))
2334 # convert arg values to their final type and assign them
2335 for i, arg in enumerate(all_args):
2336 if arg.default and not arg.type.is_pyobject:
2337 code.putln("if (values[%d]) {" % i)
2338 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2339 if arg.default and not arg.type.is_pyobject:
2340 code.putln('} else {')
2344 arg.calculate_default_value_code(code)))
2347 def generate_argument_conversion_code(self, code):
2348 # Generate code to convert arguments from
2349 # signature type to declared type, if needed.
2350 for arg in self.args:
2351 if arg.needs_conversion:
2352 self.generate_arg_conversion(arg, code)
2354 def generate_arg_conversion(self, arg, code):
2355 # Generate conversion code for one argument.
2356 old_type = arg.hdr_type
2358 if old_type.is_pyobject:
2360 code.putln("if (%s) {" % arg.hdr_cname)
2362 code.putln("assert(%s); {" % arg.hdr_cname)
2363 self.generate_arg_conversion_from_pyobject(arg, code)
2365 elif new_type.is_pyobject:
2366 self.generate_arg_conversion_to_pyobject(arg, code)
2368 if new_type.assignable_from(old_type):
2370 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2373 "Cannot convert 1 argument from '%s' to '%s'" %
2374 (old_type, new_type))
2376 def generate_arg_conversion_from_pyobject(self, arg, code):
2378 func = new_type.from_py_function
2379 # copied from CoerceFromPyTypeNode
2381 code.putln("%s = %s(%s); %s" % (
2385 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2388 "Cannot convert Python object argument to type '%s'"
2391 def generate_arg_conversion_to_pyobject(self, arg, code):
2392 old_type = arg.hdr_type
2393 func = old_type.to_py_function
2395 code.putln("%s = %s(%s); %s" % (
2399 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2400 code.put_var_gotref(arg.entry)
2403 "Cannot convert argument of type '%s' to Python object"
2406 def generate_argument_type_tests(self, code):
2407 # Generate type tests for args whose signature
2408 # type is PyObject * and whose declared type is
2409 # a subtype thereof.
2410 for arg in self.args:
2411 if arg.needs_type_test:
2412 self.generate_arg_type_test(arg, code)
2414 def generate_arg_type_test(self, arg, code):
2415 # Generate type test for one argument.
2416 if arg.type.typeobj_is_available():
2417 typeptr_cname = arg.type.typeptr_cname
2418 arg_code = "((PyObject *)%s)" % arg.entry.cname
2420 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2425 arg.type.is_builtin_type,
2426 code.error_goto(arg.pos)))
2428 error(arg.pos, "Cannot test type of extern C class "
2429 "without type object name specification")
2431 def error_value(self):
2432 return self.entry.signature.error_value
2434 def caller_will_check_exceptions(self):
2437 class OverrideCheckNode(StatNode):
2438 # A Node for dispatching to the def method if it
2447 child_attrs = ['body']
2451 def analyse_expressions(self, env):
2452 self.args = env.arg_entries
2453 if self.py_func.is_module_scope:
2458 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2459 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2460 call_node = ExprNodes.SimpleCallNode(self.pos,
2461 function=self.func_node,
2462 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2463 self.body = ReturnStatNode(self.pos, value=call_node)
2464 self.body.analyse_expressions(env)
2466 def generate_execution_code(self, code):
2467 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2468 # Check to see if we are an extension type
2469 if self.py_func.is_module_scope:
2470 self_arg = "((PyObject *)%s)" % Naming.module_cname
2472 self_arg = "((PyObject *)%s)" % self.args[0].cname
2473 code.putln("/* Check if called by wrapper */")
2474 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2475 code.putln("/* Check if overriden in Python */")
2476 if self.py_func.is_module_scope:
2477 code.putln("else {")
2479 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2480 self.func_node.allocate(code)
2481 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2482 # need to get attribute manually--scope would return cdef method
2483 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2484 self.func_node.result(), self_arg, interned_attr_cname, err))
2485 code.put_gotref(self.func_node.py_result())
2486 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2487 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2488 self.func_node.result(), self.py_func.entry.func_cname)
2489 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2490 self.body.generate_execution_code(code)
2492 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2494 self.func_node.release(code)
2496 class ClassDefNode(StatNode, BlockNode):
2499 class PyClassDefNode(ClassDefNode):
2500 # A Python class definition.
2502 # name EncodedString Name of the class
2503 # doc string or None
2504 # body StatNode Attribute definition code
2505 # entry Symtab.Entry
2506 # scope PyClassScope
2507 # decorators [DecoratorNode] list of decorators or None
2509 # The following subnodes are constructed internally:
2511 # dict DictNode Class dictionary
2512 # classobj ClassNode Class object
2513 # target NameNode Variable to assign class object to
2515 child_attrs = ["body", "dict", "classobj", "target"]
2518 def __init__(self, pos, name, bases, doc, body, decorators = None):
2519 StatNode.__init__(self, pos)
2523 self.decorators = decorators
2525 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2526 if self.doc and Options.docstrings:
2527 doc = embed_position(self.pos, self.doc)
2528 doc_node = ExprNodes.StringNode(pos, value = doc)
2531 self.classobj = ExprNodes.ClassNode(pos, name = name,
2532 bases = bases, dict = self.dict, doc = doc_node)
2533 self.target = ExprNodes.NameNode(pos, name = name)
2535 def as_cclass(self):
2537 Return this node as if it were declared as an extension class
2539 bases = self.classobj.bases.args
2541 base_class_name = None
2542 base_class_module = None
2543 elif len(bases) == 1:
2546 from ExprNodes import AttributeNode, NameNode
2547 while isinstance(base, AttributeNode):
2548 path.insert(0, base.attribute)
2550 if isinstance(base, NameNode):
2551 path.insert(0, base.name)
2552 base_class_name = path[-1]
2554 base_class_module = u'.'.join(path[:-1])
2556 base_class_module = None
2558 error(self.classobj.bases.args.pos, "Invalid base class")
2560 error(self.classobj.bases.args.pos, "C class may only have one base class")
2563 return CClassDefNode(self.pos,
2564 visibility = 'private',
2566 class_name = self.name,
2567 base_class_module = base_class_module,
2568 base_class_name = base_class_name,
2569 decorators = self.decorators,
2574 def create_scope(self, env):
2576 while env.is_py_class_scope or env.is_c_class_scope:
2577 env = env.outer_scope
2578 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2581 def analyse_declarations(self, env):
2582 self.target.analyse_target_declaration(env)
2583 cenv = self.create_scope(env)
2584 cenv.directives = env.directives
2585 cenv.class_obj_cname = self.target.entry.cname
2586 self.body.analyse_declarations(cenv)
2588 def analyse_expressions(self, env):
2589 self.dict.analyse_expressions(env)
2590 self.classobj.analyse_expressions(env)
2591 genv = env.global_scope()
2593 self.body.analyse_expressions(cenv)
2594 self.target.analyse_target_expression(env, self.classobj)
2596 def generate_function_definitions(self, env, code):
2597 self.body.generate_function_definitions(self.scope, code)
2599 def generate_execution_code(self, code):
2600 code.pyclass_stack.append(self)
2602 self.dict.generate_evaluation_code(code)
2603 self.classobj.generate_evaluation_code(code)
2604 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2605 self.body.generate_execution_code(code)
2606 self.target.generate_assignment_code(self.classobj, code)
2607 self.dict.generate_disposal_code(code)
2608 self.dict.free_temps(code)
2609 code.pyclass_stack.pop()
2612 class CClassDefNode(ClassDefNode):
2613 # An extension type definition.
2615 # visibility 'private' or 'public' or 'extern'
2616 # typedef_flag boolean
2618 # module_name string or None For import of extern type objects
2619 # class_name string Unqualified name of class
2620 # as_name string or None Name to declare as in this scope
2621 # base_class_module string or None Module containing the base class
2622 # base_class_name string or None Name of the base class
2623 # objstruct_name string or None Specified C name of object struct
2624 # typeobj_name string or None Specified C name of type object
2625 # in_pxd boolean Is in a .pxd file
2626 # decorators [DecoratorNode] list of decorators or None
2627 # doc string or None
2628 # body StatNode or None
2629 # entry Symtab.Entry
2630 # base_type PyExtensionType or None
2631 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2632 # buffer_defaults_pos
2634 child_attrs = ["body"]
2635 buffer_defaults_node = None
2636 buffer_defaults_pos = None
2637 typedef_flag = False
2639 objstruct_name = None
2643 def analyse_declarations(self, env):
2644 #print "CClassDefNode.analyse_declarations:", self.class_name
2645 #print "...visibility =", self.visibility
2646 #print "...module_name =", self.module_name
2649 if self.buffer_defaults_node:
2650 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2651 env, [], self.buffer_defaults_node,
2652 need_complete=False)
2654 buffer_defaults = None
2656 if env.in_cinclude and not self.objstruct_name:
2657 error(self.pos, "Object struct name specification required for "
2658 "C class defined in 'extern from' block")
2659 self.base_type = None
2660 # Now that module imports are cached, we need to
2661 # import the modules for extern classes.
2662 if self.module_name:
2664 for module in env.cimported_modules:
2665 if module.name == self.module_name:
2666 self.module = module
2667 if self.module is None:
2668 self.module = ModuleScope(self.module_name, None, env.context)
2669 self.module.has_extern_class = 1
2670 env.add_imported_module(self.module)
2672 if self.base_class_name:
2673 if self.base_class_module:
2674 base_class_scope = env.find_module(self.base_class_module, self.pos)
2676 base_class_scope = env
2677 if self.base_class_name == 'object':
2678 # extension classes are special and don't need to inherit from object
2679 if base_class_scope is None or base_class_scope.lookup('object') is None:
2680 self.base_class_name = None
2681 self.base_class_module = None
2682 base_class_scope = None
2683 if base_class_scope:
2684 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2685 if base_class_entry:
2686 if not base_class_entry.is_type:
2687 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2688 elif not base_class_entry.type.is_extension_type:
2689 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2690 elif not base_class_entry.type.is_complete():
2691 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2693 self.base_type = base_class_entry.type
2694 has_body = self.body is not None
2695 if self.module_name and self.visibility != 'extern':
2696 module_path = self.module_name.split(".")
2697 home_scope = env.find_imported_module(module_path, self.pos)
2703 if self.visibility == 'extern':
2704 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2705 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2707 self.entry = home_scope.declare_c_class(
2708 name = self.class_name,
2710 defining = has_body and self.in_pxd,
2711 implementing = has_body and not self.in_pxd,
2712 module_name = self.module_name,
2713 base_type = self.base_type,
2714 objstruct_cname = self.objstruct_name,
2715 typeobj_cname = self.typeobj_name,
2716 visibility = self.visibility,
2717 typedef_flag = self.typedef_flag,
2719 buffer_defaults = buffer_defaults)
2720 if home_scope is not env and self.visibility == 'extern':
2721 env.add_imported_entry(self.class_name, self.entry, pos)
2722 scope = self.entry.type.scope
2723 if scope is not None:
2724 scope.directives = env.directives
2726 if self.doc and Options.docstrings:
2727 scope.doc = embed_position(self.pos, self.doc)
2730 self.body.analyse_declarations(scope)
2734 scope.implemented = 1
2735 env.allocate_vtable_names(self.entry)
2737 def analyse_expressions(self, env):
2739 scope = self.entry.type.scope
2740 self.body.analyse_expressions(scope)
2742 def generate_function_definitions(self, env, code):
2744 self.body.generate_function_definitions(
2745 self.entry.type.scope, code)
2747 def generate_execution_code(self, code):
2748 # This is needed to generate evaluation code for
2749 # default values of method arguments.
2751 self.body.generate_execution_code(code)
2753 def annotate(self, code):
2755 self.body.annotate(code)
2758 class PropertyNode(StatNode):
2759 # Definition of a property in an extension type.
2762 # doc EncodedString or None Doc string
2765 child_attrs = ["body"]
2767 def analyse_declarations(self, env):
2768 entry = env.declare_property(self.name, self.doc, self.pos)
2770 entry.scope.directives = env.directives
2771 self.body.analyse_declarations(entry.scope)
2773 def analyse_expressions(self, env):
2774 self.body.analyse_expressions(env)
2776 def generate_function_definitions(self, env, code):
2777 self.body.generate_function_definitions(env, code)
2779 def generate_execution_code(self, code):
2782 def annotate(self, code):
2783 self.body.annotate(code)
2786 class GlobalNode(StatNode):
2787 # Global variable declaration.
2793 def analyse_declarations(self, env):
2794 for name in self.names:
2795 env.declare_global(name, self.pos)
2797 def analyse_expressions(self, env):
2800 def generate_execution_code(self, code):
2804 class ExprStatNode(StatNode):
2805 # Expression used as a statement.
2809 child_attrs = ["expr"]
2811 def analyse_declarations(self, env):
2813 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2814 func = self.expr.function.as_cython_attribute()
2815 if func == u'declare':
2816 args, kwds = self.expr.explicit_args_kwds()
2818 error(self.expr.pos, "Variable names must be specified.")
2819 for var, type_node in kwds.key_value_pairs:
2820 type = type_node.analyse_as_type(env)
2822 error(type_node.pos, "Unknown type")
2824 env.declare_var(var.value, type, var.pos, is_cdef = True)
2825 self.__class__ = PassStatNode
2827 def analyse_expressions(self, env):
2828 self.expr.analyse_expressions(env)
2830 def generate_execution_code(self, code):
2831 self.expr.generate_evaluation_code(code)
2832 if not self.expr.is_temp and self.expr.result():
2833 code.putln("%s;" % self.expr.result())
2834 self.expr.generate_disposal_code(code)
2835 self.expr.free_temps(code)
2837 def annotate(self, code):
2838 self.expr.annotate(code)
2841 class AssignmentNode(StatNode):
2842 # Abstract base class for assignment nodes.
2844 # The analyse_expressions and generate_execution_code
2845 # phases of assignments are split into two sub-phases
2846 # each, to enable all the right hand sides of a
2847 # parallel assignment to be evaluated before assigning
2848 # to any of the left hand sides.
2850 def analyse_expressions(self, env):
2851 self.analyse_types(env)
2853 # def analyse_expressions(self, env):
2854 # self.analyse_expressions_1(env)
2855 # self.analyse_expressions_2(env)
2857 def generate_execution_code(self, code):
2858 self.generate_rhs_evaluation_code(code)
2859 self.generate_assignment_code(code)
2862 class SingleAssignmentNode(AssignmentNode):
2863 # The simplest case:
2867 # lhs ExprNode Left hand side
2868 # rhs ExprNode Right hand side
2869 # first bool Is this guaranteed the first assignment to lhs?
2871 child_attrs = ["lhs", "rhs"]
2873 declaration_only = False
2875 def analyse_declarations(self, env):
2878 # handle declarations of the form x = cython.foo()
2879 if isinstance(self.rhs, ExprNodes.CallNode):
2880 func_name = self.rhs.function.as_cython_attribute()
2882 args, kwds = self.rhs.explicit_args_kwds()
2884 if func_name in ['declare', 'typedef']:
2885 if len(args) > 2 or kwds is not None:
2886 error(rhs.pos, "Can only declare one type at a time.")
2888 type = args[0].analyse_as_type(env)
2890 error(args[0].pos, "Unknown type")
2893 if func_name == 'declare':
2894 if isinstance(lhs, ExprNodes.NameNode):
2895 vars = [(lhs.name, lhs.pos)]
2896 elif isinstance(lhs, ExprNodes.TupleNode):
2897 vars = [(var.name, var.pos) for var in lhs.args]
2899 error(lhs.pos, "Invalid declaration")
2901 for var, pos in vars:
2902 env.declare_var(var, type, pos, is_cdef = True)
2907 self.declaration_only = True
2909 self.declaration_only = True
2910 if not isinstance(lhs, ExprNodes.NameNode):
2911 error(lhs.pos, "Invalid declaration.")
2912 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2914 elif func_name in ['struct', 'union']:
2915 self.declaration_only = True
2916 if len(args) > 0 or kwds is None:
2917 error(rhs.pos, "Struct or union members must be given by name.")
2920 for member, type_node in kwds.key_value_pairs:
2921 type = type_node.analyse_as_type(env)
2923 error(type_node.pos, "Unknown type")
2925 members.append((member.value, type, member.pos))
2926 if len(members) < len(kwds.key_value_pairs):
2928 if not isinstance(self.lhs, ExprNodes.NameNode):
2929 error(self.lhs.pos, "Invalid declaration.")
2930 name = self.lhs.name
2931 scope = StructOrUnionScope(name)
2932 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2933 for member, type, pos in members:
2934 scope.declare_var(member, type, pos)
2936 if self.declaration_only:
2939 self.lhs.analyse_target_declaration(env)
2941 def analyse_types(self, env, use_temp = 0):
2942 self.rhs.analyse_types(env)
2943 self.lhs.analyse_target_types(env)
2944 self.lhs.gil_assignment_check(env)
2945 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2947 self.rhs = self.rhs.coerce_to_temp(env)
2949 def generate_rhs_evaluation_code(self, code):
2950 self.rhs.generate_evaluation_code(code)
2952 def generate_assignment_code(self, code):
2953 self.lhs.generate_assignment_code(self.rhs, code)
2955 def annotate(self, code):
2956 self.lhs.annotate(code)
2957 self.rhs.annotate(code)
2960 class CascadedAssignmentNode(AssignmentNode):
2961 # An assignment with multiple left hand sides:
2965 # lhs_list [ExprNode] Left hand sides
2966 # rhs ExprNode Right hand sides
2970 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2972 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2973 coerced_rhs_list = None
2975 def analyse_declarations(self, env):
2976 for lhs in self.lhs_list:
2977 lhs.analyse_target_declaration(env)
2979 def analyse_types(self, env, use_temp = 0):
2980 self.rhs.analyse_types(env)
2982 self.rhs = self.rhs.coerce_to_temp(env)
2984 self.rhs = self.rhs.coerce_to_simple(env)
2985 from ExprNodes import CloneNode
2986 self.coerced_rhs_list = []
2987 for lhs in self.lhs_list:
2988 lhs.analyse_target_types(env)
2989 lhs.gil_assignment_check(env)
2990 rhs = CloneNode(self.rhs)
2991 rhs = rhs.coerce_to(lhs.type, env)
2992 self.coerced_rhs_list.append(rhs)
2994 def generate_rhs_evaluation_code(self, code):
2995 self.rhs.generate_evaluation_code(code)
2997 def generate_assignment_code(self, code):
2998 for i in range(len(self.lhs_list)):
2999 lhs = self.lhs_list[i]
3000 rhs = self.coerced_rhs_list[i]
3001 rhs.generate_evaluation_code(code)
3002 lhs.generate_assignment_code(rhs, code)
3003 # Assignment has disposed of the cloned RHS
3004 self.rhs.generate_disposal_code(code)
3005 self.rhs.free_temps(code)
3007 def annotate(self, code):
3008 for i in range(len(self.lhs_list)):
3009 lhs = self.lhs_list[i].annotate(code)
3010 rhs = self.coerced_rhs_list[i].annotate(code)
3011 self.rhs.annotate(code)
3014 class ParallelAssignmentNode(AssignmentNode):
3015 # A combined packing/unpacking assignment:
3019 # This has been rearranged by the parser into
3021 # a = d ; b = e ; c = f
3023 # but we must evaluate all the right hand sides
3024 # before assigning to any of the left hand sides.
3026 # stats [AssignmentNode] The constituent assignments
3028 child_attrs = ["stats"]
3030 def analyse_declarations(self, env):
3031 for stat in self.stats:
3032 stat.analyse_declarations(env)
3034 def analyse_expressions(self, env):
3035 for stat in self.stats:
3036 stat.analyse_types(env, use_temp = 1)
3038 # def analyse_expressions(self, env):
3039 # for stat in self.stats:
3040 # stat.analyse_expressions_1(env, use_temp = 1)
3041 # for stat in self.stats:
3042 # stat.analyse_expressions_2(env)
3044 def generate_execution_code(self, code):
3045 for stat in self.stats:
3046 stat.generate_rhs_evaluation_code(code)
3047 for stat in self.stats:
3048 stat.generate_assignment_code(code)
3050 def annotate(self, code):
3051 for stat in self.stats:
3055 class InPlaceAssignmentNode(AssignmentNode):
3056 # An in place arithmatic operand:
3062 # lhs ExprNode Left hand side
3063 # rhs ExprNode Right hand side
3064 # op char one of "+-*/%^&|"
3065 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3067 # This code is a bit tricky because in order to obey Python
3068 # semantics the sub-expressions (e.g. indices) of the lhs must
3069 # not be evaluated twice. So we must re-use the values calculated
3070 # in evaluation phase for the assignment phase as well.
3071 # Fortunately, the type of the lhs node is fairly constrained
3072 # (it must be a NameNode, AttributeNode, or IndexNode).
3074 child_attrs = ["lhs", "rhs"]
3077 def analyse_declarations(self, env):
3078 self.lhs.analyse_target_declaration(env)
3080 def analyse_types(self, env):
3081 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3082 self.rhs.analyse_types(env)
3083 self.lhs.analyse_target_types(env)
3084 if Options.incref_local_binop and self.dup.type.is_pyobject:
3085 self.dup = self.dup.coerce_to_temp(env)
3087 if self.lhs.type.is_pyobject:
3088 self.rhs = self.rhs.coerce_to_pyobject(env)
3089 elif self.rhs.type.is_pyobject:
3090 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3091 if self.lhs.type.is_pyobject:
3092 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3093 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3095 def generate_execution_code(self, code):
3097 self.rhs.generate_evaluation_code(code)
3098 self.dup.generate_subexpr_evaluation_code(code)
3099 if self.dup.is_temp:
3100 self.dup.allocate_temp_result(code)
3101 # self.dup.generate_result_code is run only if it is not buffer access
3102 if self.operator == "**":
3106 if self.lhs.type.is_pyobject:
3107 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3108 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3109 self.dup.generate_result_code(code)
3110 self.result_value_temp.allocate(code)
3112 "%s = %s(%s, %s%s); %s" % (
3113 self.result_value.result(),
3114 self.py_operation_function(),
3115 self.dup.py_result(),
3116 self.rhs.py_result(),
3118 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3119 code.put_gotref(self.result_value.py_result())
3120 self.result_value.generate_evaluation_code(code) # May be a type check...
3121 self.rhs.generate_disposal_code(code)
3122 self.rhs.free_temps(code)
3123 self.dup.generate_disposal_code(code)
3124 self.dup.free_temps(code)
3125 self.lhs.generate_assignment_code(self.result_value, code)
3126 self.result_value_temp.release(code)
3128 c_op = self.operator
3132 error(self.pos, "No C inplace power operator")
3133 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3134 error(self.pos, "Inplace operators not implemented for complex types.")
3136 # have to do assignment directly to avoid side-effects
3137 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3138 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3140 self.dup.generate_result_code(code)
3141 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3142 self.rhs.generate_disposal_code(code)
3143 self.rhs.free_temps(code)
3144 if self.dup.is_temp:
3145 self.dup.generate_subexpr_disposal_code(code)
3146 self.dup.free_subexpr_temps(code)
3148 def create_dup_node(self, env):
3151 self.dup.analyse_types(env)
3152 if isinstance(self.lhs, ExprNodes.NameNode):
3153 target_lhs = ExprNodes.NameNode(self.dup.pos,
3154 name = self.dup.name,
3155 is_temp = self.dup.is_temp,
3156 entry = self.dup.entry)
3157 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3158 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3159 obj = ExprNodes.CloneNode(self.lhs.obj),
3160 attribute = self.dup.attribute,
3161 is_temp = self.dup.is_temp)
3162 elif isinstance(self.lhs, ExprNodes.IndexNode):
3164 index = ExprNodes.CloneNode(self.lhs.index)
3167 if self.lhs.indices:
3168 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3171 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3172 base = ExprNodes.CloneNode(self.dup.base),
3175 is_temp = self.dup.is_temp)
3178 self.lhs = target_lhs
3181 def py_operation_function(self):
3182 return self.py_functions[self.operator]
3185 "|": "PyNumber_InPlaceOr",
3186 "^": "PyNumber_InPlaceXor",
3187 "&": "PyNumber_InPlaceAnd",
3188 "+": "PyNumber_InPlaceAdd",
3189 "-": "PyNumber_InPlaceSubtract",
3190 "*": "PyNumber_InPlaceMultiply",
3191 "/": "PyNumber_InPlaceDivide",
3192 "%": "PyNumber_InPlaceRemainder",
3193 "<<": "PyNumber_InPlaceLshift",
3194 ">>": "PyNumber_InPlaceRshift",
3195 "**": "PyNumber_InPlacePower",
3196 "//": "PyNumber_InPlaceFloorDivide",
3199 def annotate(self, code):
3200 self.lhs.annotate(code)
3201 self.rhs.annotate(code)
3202 self.dup.annotate(code)
3205 class PrintStatNode(StatNode):
3208 # arg_tuple TupleNode
3209 # append_newline boolean
3211 child_attrs = ["arg_tuple"]
3213 def analyse_expressions(self, env):
3214 self.arg_tuple.analyse_expressions(env)
3215 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3216 env.use_utility_code(printing_utility_code)
3217 if len(self.arg_tuple.args) == 1 and self.append_newline:
3218 env.use_utility_code(printing_one_utility_code)
3220 nogil_check = Node.gil_error
3221 gil_message = "Python print statement"
3223 def generate_execution_code(self, code):
3224 if len(self.arg_tuple.args) == 1 and self.append_newline:
3225 arg = self.arg_tuple.args[0]
3226 arg.generate_evaluation_code(code)
3229 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3231 code.error_goto(self.pos)))
3232 arg.generate_disposal_code(code)
3233 arg.free_temps(code)
3235 self.arg_tuple.generate_evaluation_code(code)
3237 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3238 self.arg_tuple.py_result(),
3239 self.append_newline,
3240 code.error_goto(self.pos)))
3241 self.arg_tuple.generate_disposal_code(code)
3242 self.arg_tuple.free_temps(code)
3244 def annotate(self, code):
3245 self.arg_tuple.annotate(code)
3248 class ExecStatNode(StatNode):
3253 child_attrs = ["args"]
3255 def analyse_expressions(self, env):
3256 for i, arg in enumerate(self.args):
3257 arg.analyse_expressions(env)
3258 arg = arg.coerce_to_pyobject(env)
3260 env.use_utility_code(Builtin.pyexec_utility_code)
3262 nogil_check = Node.gil_error
3263 gil_message = "Python exec statement"
3265 def generate_execution_code(self, code):
3267 for arg in self.args:
3268 arg.generate_evaluation_code(code)
3269 args.append( arg.py_result() )
3270 args = tuple(args + ['0', '0'][:3-len(args)])
3271 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3272 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3273 (temp_result,) + args))
3274 for arg in self.args:
3275 arg.generate_disposal_code(code)
3276 arg.free_temps(code)
3278 code.error_goto_if_null(temp_result, self.pos))
3279 code.put_gotref(temp_result)
3280 code.put_decref_clear(temp_result, py_object_type)
3281 code.funcstate.release_temp(temp_result)
3283 def annotate(self, code):
3284 for arg in self.args:
3288 class DelStatNode(StatNode):
3293 child_attrs = ["args"]
3295 def analyse_declarations(self, env):
3296 for arg in self.args:
3297 arg.analyse_target_declaration(env)
3299 def analyse_expressions(self, env):
3300 for arg in self.args:
3301 arg.analyse_target_expression(env, None)
3302 if not arg.type.is_pyobject:
3303 error(arg.pos, "Deletion of non-Python object")
3304 #arg.release_target_temp(env)
3306 def nogil_check(self, env):
3307 for arg in self.args:
3308 if arg.type.is_pyobject:
3311 gil_message = "Deleting Python object"
3313 def generate_execution_code(self, code):
3314 for arg in self.args:
3315 if arg.type.is_pyobject:
3316 arg.generate_deletion_code(code)
3317 # else error reported earlier
3319 def annotate(self, code):
3320 for arg in self.args:
3324 class PassStatNode(StatNode):
3329 def analyse_expressions(self, env):
3332 def generate_execution_code(self, code):
3336 class BreakStatNode(StatNode):
3340 def analyse_expressions(self, env):
3343 def generate_execution_code(self, code):
3344 if not code.break_label:
3345 error(self.pos, "break statement not inside loop")
3347 code.put_goto(code.break_label)
3350 class ContinueStatNode(StatNode):
3354 def analyse_expressions(self, env):
3357 def generate_execution_code(self, code):
3358 if code.funcstate.in_try_finally:
3359 error(self.pos, "continue statement inside try of try...finally")
3360 elif not code.continue_label:
3361 error(self.pos, "continue statement not inside loop")
3363 code.put_goto(code.continue_label)
3366 class ReturnStatNode(StatNode):
3369 # value ExprNode or None
3370 # return_type PyrexType
3372 child_attrs = ["value"]
3374 def analyse_expressions(self, env):
3375 return_type = env.return_type
3376 self.return_type = return_type
3378 error(self.pos, "Return not inside a function body")
3381 self.value.analyse_types(env)
3382 if return_type.is_void or return_type.is_returncode:
3383 error(self.value.pos,
3384 "Return with value in void function")
3386 self.value = self.value.coerce_to(env.return_type, env)
3388 if (not return_type.is_void
3389 and not return_type.is_pyobject
3390 and not return_type.is_returncode):
3391 error(self.pos, "Return value required")
3393 def nogil_check(self, env):
3394 if self.return_type.is_pyobject:
3397 gil_message = "Returning Python object"
3399 def generate_execution_code(self, code):
3400 code.mark_pos(self.pos)
3401 if not self.return_type:
3402 # error reported earlier
3404 if self.return_type.is_pyobject:
3405 code.put_xdecref(Naming.retval_cname,
3408 self.value.generate_evaluation_code(code)
3409 self.value.make_owned_reference(code)
3412 Naming.retval_cname,
3413 self.value.result_as(self.return_type)))
3414 self.value.generate_post_assignment_code(code)
3415 self.value.free_temps(code)
3417 if self.return_type.is_pyobject:
3418 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3419 elif self.return_type.is_returncode:
3422 Naming.retval_cname,
3423 self.return_type.default_value))
3424 for cname, type in code.funcstate.temps_holding_reference():
3425 code.put_decref_clear(cname, type)
3426 code.put_goto(code.return_label)
3428 def annotate(self, code):
3430 self.value.annotate(code)
3433 class RaiseStatNode(StatNode):
3436 # exc_type ExprNode or None
3437 # exc_value ExprNode or None
3438 # exc_tb ExprNode or None
3440 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3442 def analyse_expressions(self, env):
3444 self.exc_type.analyse_types(env)
3445 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3447 self.exc_value.analyse_types(env)
3448 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3450 self.exc_tb.analyse_types(env)
3451 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3452 env.use_utility_code(raise_utility_code)
3453 env.use_utility_code(restore_exception_utility_code)
3455 nogil_check = Node.gil_error
3456 gil_message = "Raising exception"
3458 def generate_execution_code(self, code):
3460 self.exc_type.generate_evaluation_code(code)
3461 type_code = self.exc_type.py_result()
3465 self.exc_value.generate_evaluation_code(code)
3466 value_code = self.exc_value.py_result()
3470 self.exc_tb.generate_evaluation_code(code)
3471 tb_code = self.exc_tb.py_result()
3474 if self.exc_type or self.exc_value or self.exc_tb:
3476 "__Pyx_Raise(%s, %s, %s);" % (
3483 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3485 obj.generate_disposal_code(code)
3486 obj.free_temps(code)
3488 code.error_goto(self.pos))
3490 def annotate(self, code):
3492 self.exc_type.annotate(code)
3494 self.exc_value.annotate(code)
3496 self.exc_tb.annotate(code)
3499 class ReraiseStatNode(StatNode):
3503 def analyse_expressions(self, env):
3504 env.use_utility_code(raise_utility_code)
3505 env.use_utility_code(restore_exception_utility_code)
3507 nogil_check = Node.gil_error
3508 gil_message = "Raising exception"
3510 def generate_execution_code(self, code):
3511 vars = code.funcstate.exc_vars
3513 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3514 code.putln(code.error_goto(self.pos))
3516 error(self.pos, "Reraise not inside except clause")
3519 class AssertStatNode(StatNode):
3523 # value ExprNode or None
3525 child_attrs = ["cond", "value"]
3527 def analyse_expressions(self, env):
3528 self.cond = self.cond.analyse_boolean_expression(env)
3530 self.value.analyse_types(env)
3531 self.value = self.value.coerce_to_pyobject(env)
3533 nogil_check = Node.gil_error
3534 gil_message = "Raising exception"
3536 def generate_execution_code(self, code):
3537 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3538 self.cond.generate_evaluation_code(code)
3540 "if (unlikely(!%s)) {" %
3543 self.value.generate_evaluation_code(code)
3545 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3546 self.value.py_result())
3547 self.value.generate_disposal_code(code)
3548 self.value.free_temps(code)
3551 "PyErr_SetNone(PyExc_AssertionError);")
3553 code.error_goto(self.pos))
3556 self.cond.generate_disposal_code(code)
3557 self.cond.free_temps(code)
3558 code.putln("#endif")
3560 def annotate(self, code):
3561 self.cond.annotate(code)
3563 self.value.annotate(code)
3566 class IfStatNode(StatNode):
3569 # if_clauses [IfClauseNode]
3570 # else_clause StatNode or None
3572 child_attrs = ["if_clauses", "else_clause"]
3574 def analyse_control_flow(self, env):
3575 env.start_branching(self.pos)
3576 for if_clause in self.if_clauses:
3577 if_clause.analyse_control_flow(env)
3578 env.next_branch(if_clause.end_pos())
3579 if self.else_clause:
3580 self.else_clause.analyse_control_flow(env)
3581 env.finish_branching(self.end_pos())
3583 def analyse_declarations(self, env):
3584 for if_clause in self.if_clauses:
3585 if_clause.analyse_declarations(env)
3586 if self.else_clause:
3587 self.else_clause.analyse_declarations(env)
3589 def analyse_expressions(self, env):
3590 for if_clause in self.if_clauses:
3591 if_clause.analyse_expressions(env)
3592 if self.else_clause:
3593 self.else_clause.analyse_expressions(env)
3595 def generate_execution_code(self, code):
3596 code.mark_pos(self.pos)
3597 end_label = code.new_label()
3598 for if_clause in self.if_clauses:
3599 if_clause.generate_execution_code(code, end_label)
3600 if self.else_clause:
3601 code.putln("/*else*/ {")
3602 self.else_clause.generate_execution_code(code)
3604 code.put_label(end_label)
3606 def annotate(self, code):
3607 for if_clause in self.if_clauses:
3608 if_clause.annotate(code)
3609 if self.else_clause:
3610 self.else_clause.annotate(code)
3613 class IfClauseNode(Node):
3614 # if or elif clause in an if statement
3616 # condition ExprNode
3619 child_attrs = ["condition", "body"]
3621 def analyse_control_flow(self, env):
3622 self.body.analyse_control_flow(env)
3624 def analyse_declarations(self, env):
3625 self.condition.analyse_declarations(env)
3626 self.body.analyse_declarations(env)
3628 def analyse_expressions(self, env):
3630 self.condition.analyse_temp_boolean_expression(env)
3631 self.body.analyse_expressions(env)
3633 def generate_execution_code(self, code, end_label):
3634 self.condition.generate_evaluation_code(code)
3637 self.condition.result())
3638 self.condition.generate_disposal_code(code)
3639 self.condition.free_temps(code)
3640 self.body.generate_execution_code(code)
3644 code.put_goto(end_label)
3647 def annotate(self, code):
3648 self.condition.annotate(code)
3649 self.body.annotate(code)
3652 class SwitchCaseNode(StatNode):
3653 # Generated in the optimization of an if-elif-else node
3655 # conditions [ExprNode]
3658 child_attrs = ['conditions', 'body']
3660 def generate_execution_code(self, code):
3661 for cond in self.conditions:
3662 code.mark_pos(cond.pos)
3663 cond.generate_evaluation_code(code)
3664 code.putln("case %s:" % cond.result())
3665 self.body.generate_execution_code(code)
3666 code.putln("break;")
3668 def annotate(self, code):
3669 for cond in self.conditions:
3671 self.body.annotate(code)
3673 class SwitchStatNode(StatNode):
3674 # Generated in the optimization of an if-elif-else node
3677 # cases [SwitchCaseNode]
3678 # else_clause StatNode or None
3680 child_attrs = ['test', 'cases', 'else_clause']
3682 def generate_execution_code(self, code):
3683 code.putln("switch (%s) {" % self.test.result())
3684 for case in self.cases:
3685 case.generate_execution_code(code)
3686 if self.else_clause is not None:
3687 code.putln("default:")
3688 self.else_clause.generate_execution_code(code)
3689 code.putln("break;")
3692 def annotate(self, code):
3693 self.test.annotate(code)
3694 for case in self.cases:
3696 if self.else_clause is not None:
3697 self.else_clause.annotate(code)
3699 class LoopNode(object):
3701 def analyse_control_flow(self, env):
3702 env.start_branching(self.pos)
3703 self.body.analyse_control_flow(env)
3704 env.next_branch(self.body.end_pos())
3705 if self.else_clause:
3706 self.else_clause.analyse_control_flow(env)
3707 env.finish_branching(self.end_pos())
3710 class WhileStatNode(LoopNode, StatNode):
3713 # condition ExprNode
3715 # else_clause StatNode
3717 child_attrs = ["condition", "body", "else_clause"]
3719 def analyse_declarations(self, env):
3720 self.body.analyse_declarations(env)
3721 if self.else_clause:
3722 self.else_clause.analyse_declarations(env)
3724 def analyse_expressions(self, env):
3726 self.condition.analyse_temp_boolean_expression(env)
3727 self.body.analyse_expressions(env)
3728 if self.else_clause:
3729 self.else_clause.analyse_expressions(env)
3731 def generate_execution_code(self, code):
3732 old_loop_labels = code.new_loop_labels()
3735 self.condition.generate_evaluation_code(code)
3736 self.condition.generate_disposal_code(code)
3739 self.condition.result())
3740 self.condition.free_temps(code)
3741 self.body.generate_execution_code(code)
3742 code.put_label(code.continue_label)
3744 break_label = code.break_label
3745 code.set_loop_labels(old_loop_labels)
3746 if self.else_clause:
3747 code.putln("/*else*/ {")
3748 self.else_clause.generate_execution_code(code)
3750 code.put_label(break_label)
3752 def annotate(self, code):
3753 self.condition.annotate(code)
3754 self.body.annotate(code)
3755 if self.else_clause:
3756 self.else_clause.annotate(code)
3759 def ForStatNode(pos, **kw):
3760 if 'iterator' in kw:
3761 return ForInStatNode(pos, **kw)
3763 return ForFromStatNode(pos, **kw)
3765 class ForInStatNode(LoopNode, StatNode):
3769 # iterator IteratorNode
3771 # else_clause StatNode
3772 # item NextNode used internally
3774 child_attrs = ["target", "iterator", "body", "else_clause"]
3777 def analyse_declarations(self, env):
3778 self.target.analyse_target_declaration(env)
3779 self.body.analyse_declarations(env)
3780 if self.else_clause:
3781 self.else_clause.analyse_declarations(env)
3783 def analyse_expressions(self, env):
3785 self.target.analyse_target_types(env)
3786 self.iterator.analyse_expressions(env)
3787 self.item = ExprNodes.NextNode(self.iterator, env)
3788 self.item = self.item.coerce_to(self.target.type, env)
3789 self.body.analyse_expressions(env)
3790 if self.else_clause:
3791 self.else_clause.analyse_expressions(env)
3793 def generate_execution_code(self, code):
3794 old_loop_labels = code.new_loop_labels()
3795 self.iterator.allocate_counter_temp(code)
3796 self.iterator.generate_evaluation_code(code)
3799 self.item.generate_evaluation_code(code)
3800 self.target.generate_assignment_code(self.item, code)
3801 self.body.generate_execution_code(code)
3802 code.put_label(code.continue_label)
3805 break_label = code.break_label
3806 code.set_loop_labels(old_loop_labels)
3807 if self.else_clause:
3808 code.putln("/*else*/ {")
3809 self.else_clause.generate_execution_code(code)
3811 code.put_label(break_label)
3812 self.iterator.release_counter_temp(code)
3813 self.iterator.generate_disposal_code(code)
3814 self.iterator.free_temps(code)
3816 def annotate(self, code):
3817 self.target.annotate(code)
3818 self.iterator.annotate(code)
3819 self.body.annotate(code)
3820 if self.else_clause:
3821 self.else_clause.annotate(code)
3822 self.item.annotate(code)
3825 class ForFromStatNode(LoopNode, StatNode):
3826 # for name from expr rel name rel expr
3833 # step ExprNode or None
3835 # else_clause StatNode or None
3841 # loopvar_node ExprNode (usually a NameNode or temp node)
3842 # py_loopvar_node PyTempNode or None
3843 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3845 is_py_target = False
3847 py_loopvar_node = None
3850 gil_message = "For-loop using object bounds or target"
3852 def nogil_check(self, env):
3853 for x in (self.target, self.bound1, self.bound2):
3854 if x.type.is_pyobject:
3857 def analyse_declarations(self, env):
3858 self.target.analyse_target_declaration(env)
3859 self.body.analyse_declarations(env)
3860 if self.else_clause:
3861 self.else_clause.analyse_declarations(env)
3863 def analyse_expressions(self, env):
3865 self.target.analyse_target_types(env)
3866 self.bound1.analyse_types(env)
3867 self.bound2.analyse_types(env)
3868 if self.step is not None:
3869 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3870 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3871 self.step.analyse_types(env)
3873 target_type = self.target.type
3874 if self.target.type.is_numeric:
3875 loop_type = self.target.type
3877 loop_type = PyrexTypes.c_int_type
3878 if not self.bound1.type.is_pyobject:
3879 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3880 if not self.bound2.type.is_pyobject:
3881 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3882 if self.step is not None and not self.step.type.is_pyobject:
3883 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3884 self.bound1 = self.bound1.coerce_to(loop_type, env)
3885 self.bound2 = self.bound2.coerce_to(loop_type, env)
3886 if not self.bound2.is_literal:
3887 self.bound2 = self.bound2.coerce_to_temp(env)
3888 if self.step is not None:
3889 self.step = self.step.coerce_to(loop_type, env)
3890 if not self.step.is_literal:
3891 self.step = self.step.coerce_to_temp(env)
3893 target_type = self.target.type
3894 if not (target_type.is_pyobject or target_type.is_numeric):
3895 error(self.target.pos,
3896 "for-from loop variable must be c numeric type or Python object")
3897 if target_type.is_numeric:
3898 self.is_py_target = False
3899 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3900 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3901 self.loopvar_node = self.target
3902 self.py_loopvar_node = None
3904 self.is_py_target = True
3905 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3906 self.loopvar_node = c_loopvar_node
3907 self.py_loopvar_node = \
3908 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3909 self.body.analyse_expressions(env)
3910 if self.else_clause:
3911 self.else_clause.analyse_expressions(env)
3913 def generate_execution_code(self, code):
3914 old_loop_labels = code.new_loop_labels()
3915 from_range = self.from_range
3916 self.bound1.generate_evaluation_code(code)
3917 self.bound2.generate_evaluation_code(code)
3918 offset, incop = self.relation_table[self.relation1]
3919 if self.step is not None:
3920 self.step.generate_evaluation_code(code)
3921 step = self.step.result()
3922 incop = "%s=%s" % (incop[0], step)
3924 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3925 self.loopvar_node.allocate(code)
3926 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3927 self.py_loopvar_node.allocate(code)
3929 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3931 loopvar_name = self.loopvar_node.result()
3933 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3935 self.bound1.result(), offset,
3936 loopvar_name, self.relation2, self.bound2.result(),
3937 loopvar_name, incop))
3938 if self.py_loopvar_node:
3939 self.py_loopvar_node.generate_evaluation_code(code)
3940 self.target.generate_assignment_code(self.py_loopvar_node, code)
3942 code.putln("%s = %s;" % (
3943 self.target.result(), loopvar_name))
3944 self.body.generate_execution_code(code)
3945 code.put_label(code.continue_label)
3946 if self.py_loopvar_node:
3947 # This mess is to make for..from loops with python targets behave
3948 # exactly like those with C targets with regards to re-assignment
3949 # of the loop variable.
3951 if self.target.entry.is_pyglobal:
3952 # We know target is a NameNode, this is the only ugly case.
3953 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3954 target_node.allocate(code)
3955 interned_cname = code.intern_identifier(self.target.entry.name)
3956 code.putln("/*here*/")
3957 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3958 target_node.result(),
3959 Naming.module_cname,
3961 code.error_goto_if_null(target_node.result(), self.target.pos)))
3962 code.put_gotref(target_node.result())
3964 target_node = self.target
3965 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3966 from_py_node.temp_code = loopvar_name
3967 from_py_node.generate_result_code(code)
3968 if self.target.entry.is_pyglobal:
3969 code.put_decref(target_node.result(), target_node.type)
3970 target_node.release(code)
3972 if self.py_loopvar_node:
3973 # This is potentially wasteful, but we don't want the semantics to
3974 # depend on whether or not the loop is a python type.
3975 self.py_loopvar_node.generate_evaluation_code(code)
3976 self.target.generate_assignment_code(self.py_loopvar_node, code)
3977 break_label = code.break_label
3978 code.set_loop_labels(old_loop_labels)
3979 if self.else_clause:
3980 code.putln("/*else*/ {")
3981 self.else_clause.generate_execution_code(code)
3983 code.put_label(break_label)
3984 self.bound1.generate_disposal_code(code)
3985 self.bound1.free_temps(code)
3986 self.bound2.generate_disposal_code(code)
3987 self.bound2.free_temps(code)
3988 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3989 self.loopvar_node.release(code)
3990 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3991 self.py_loopvar_node.release(code)
3992 if self.step is not None:
3993 self.step.generate_disposal_code(code)
3994 self.step.free_temps(code)
3997 # {relop : (initial offset, increment op)}
4004 def annotate(self, code):
4005 self.target.annotate(code)
4006 self.bound1.annotate(code)
4007 self.bound2.annotate(code)
4009 self.bound2.annotate(code)
4010 self.body.annotate(code)
4011 if self.else_clause:
4012 self.else_clause.annotate(code)
4015 class WithStatNode(StatNode):
4017 Represents a Python with statement.
4019 This is only used at parse tree level; and is not present in
4020 analysis or generation phases.
4022 # manager The with statement manager object
4023 # target Node (lhs expression)
4025 child_attrs = ["manager", "target", "body"]
4027 class TryExceptStatNode(StatNode):
4028 # try .. except statement
4031 # except_clauses [ExceptClauseNode]
4032 # else_clause StatNode or None
4034 child_attrs = ["body", "except_clauses", "else_clause"]
4036 def analyse_control_flow(self, env):
4037 env.start_branching(self.pos)
4038 self.body.analyse_control_flow(env)
4039 successful_try = env.control_flow # grab this for later
4040 env.next_branch(self.body.end_pos())
4041 env.finish_branching(self.body.end_pos())
4043 env.start_branching(self.except_clauses[0].pos)
4044 for except_clause in self.except_clauses:
4045 except_clause.analyse_control_flow(env)
4046 env.next_branch(except_clause.end_pos())
4048 # the else cause it executed only when the try clause finishes
4049 env.control_flow.incoming = successful_try
4050 if self.else_clause:
4051 self.else_clause.analyse_control_flow(env)
4052 env.finish_branching(self.end_pos())
4054 def analyse_declarations(self, env):
4055 self.body.analyse_declarations(env)
4056 for except_clause in self.except_clauses:
4057 except_clause.analyse_declarations(env)
4058 if self.else_clause:
4059 self.else_clause.analyse_declarations(env)
4060 env.use_utility_code(reset_exception_utility_code)
4062 def analyse_expressions(self, env):
4063 self.body.analyse_expressions(env)
4064 default_clause_seen = 0
4065 for except_clause in self.except_clauses:
4066 except_clause.analyse_expressions(env)
4067 if default_clause_seen:
4068 error(except_clause.pos, "default 'except:' must be last")
4069 if not except_clause.pattern:
4070 default_clause_seen = 1
4071 self.has_default_clause = default_clause_seen
4072 if self.else_clause:
4073 self.else_clause.analyse_expressions(env)
4075 nogil_check = Node.gil_error
4076 gil_message = "Try-except statement"
4078 def generate_execution_code(self, code):
4079 old_return_label = code.return_label
4080 old_break_label = code.break_label
4081 old_continue_label = code.continue_label
4082 old_error_label = code.new_error_label()
4083 our_error_label = code.error_label
4084 except_end_label = code.new_label('exception_handled')
4085 except_error_label = code.new_label('except_error')
4086 except_return_label = code.new_label('except_return')
4087 try_return_label = code.new_label('try_return')
4088 try_break_label = code.new_label('try_break')
4089 try_continue_label = code.new_label('try_continue')
4090 try_end_label = code.new_label('try_end')
4093 code.putln("PyObject %s;" %
4094 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4095 code.putln("__Pyx_ExceptionSave(%s);" %
4096 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4097 for var in Naming.exc_save_vars:
4098 code.put_xgotref(var)
4101 code.return_label = try_return_label
4102 code.break_label = try_break_label
4103 code.continue_label = try_continue_label
4104 self.body.generate_execution_code(code)
4107 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4108 code.error_label = except_error_label
4109 code.return_label = except_return_label
4110 if self.else_clause:
4113 self.else_clause.generate_execution_code(code)
4116 for var in Naming.exc_save_vars:
4117 code.put_xdecref_clear(var, py_object_type)
4118 code.put_goto(try_end_label)
4119 if code.label_used(try_return_label):
4120 code.put_label(try_return_label)
4121 for var in Naming.exc_save_vars:
4122 code.put_xdecref_clear(var, py_object_type)
4123 code.put_goto(old_return_label)
4124 code.put_label(our_error_label)
4125 for temp_name, type in temps_to_clean_up:
4126 code.put_xdecref_clear(temp_name, type)
4127 for except_clause in self.except_clauses:
4128 except_clause.generate_handling_code(code, except_end_label)
4130 error_label_used = code.label_used(except_error_label)
4131 if error_label_used or not self.has_default_clause:
4132 if error_label_used:
4133 code.put_label(except_error_label)
4134 for var in Naming.exc_save_vars:
4135 code.put_xdecref(var, py_object_type)
4136 code.put_goto(old_error_label)
4138 if code.label_used(try_break_label):
4139 code.put_label(try_break_label)
4140 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4141 code.putln("__Pyx_ExceptionReset(%s);" %
4142 ', '.join(Naming.exc_save_vars))
4143 code.put_goto(old_break_label)
4145 if code.label_used(try_continue_label):
4146 code.put_label(try_continue_label)
4147 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4148 code.putln("__Pyx_ExceptionReset(%s);" %
4149 ', '.join(Naming.exc_save_vars))
4150 code.put_goto(old_continue_label)
4152 if code.label_used(except_return_label):
4153 code.put_label(except_return_label)
4154 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4155 code.putln("__Pyx_ExceptionReset(%s);" %
4156 ', '.join(Naming.exc_save_vars))
4157 code.put_goto(old_return_label)
4159 if code.label_used(except_end_label):
4160 code.put_label(except_end_label)
4161 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4162 code.putln("__Pyx_ExceptionReset(%s);" %
4163 ', '.join(Naming.exc_save_vars))
4164 code.put_label(try_end_label)
4167 code.return_label = old_return_label
4168 code.break_label = old_break_label
4169 code.continue_label = old_continue_label
4170 code.error_label = old_error_label
4172 def annotate(self, code):
4173 self.body.annotate(code)
4174 for except_node in self.except_clauses:
4175 except_node.annotate(code)
4176 if self.else_clause:
4177 self.else_clause.annotate(code)
4180 class ExceptClauseNode(Node):
4181 # Part of try ... except statement.
4184 # target ExprNode or None
4186 # excinfo_target NameNode or None optional target for exception info
4187 # match_flag string result of exception match
4188 # exc_value ExcValueNode used internally
4189 # function_name string qualified name of enclosing function
4190 # exc_vars (string * 3) local exception variables
4192 # excinfo_target is never set by the parser, but can be set by a transform
4193 # in order to extract more extensive information about the exception as a
4194 # sys.exc_info()-style tuple into a target variable
4196 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4199 excinfo_target = None
4201 def analyse_declarations(self, env):
4203 self.target.analyse_target_declaration(env)
4204 if self.excinfo_target is not None:
4205 self.excinfo_target.analyse_target_declaration(env)
4206 self.body.analyse_declarations(env)
4208 def analyse_expressions(self, env):
4210 genv = env.global_scope()
4211 self.function_name = env.qualified_name
4213 self.pattern.analyse_expressions(env)
4214 self.pattern = self.pattern.coerce_to_pyobject(env)
4217 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4218 self.target.analyse_target_expression(env, self.exc_value)
4219 if self.excinfo_target is not None:
4221 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4222 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4223 self.excinfo_tuple.analyse_expressions(env)
4224 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4226 self.body.analyse_expressions(env)
4228 def generate_handling_code(self, code, end_label):
4229 code.mark_pos(self.pos)
4231 self.pattern.generate_evaluation_code(code)
4233 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4235 "%s = PyErr_ExceptionMatches(%s);" % (
4237 self.pattern.py_result()))
4238 self.pattern.generate_disposal_code(code)
4239 self.pattern.free_temps(code)
4243 code.funcstate.release_temp(match_flag)
4245 code.putln("/*except:*/ {")
4247 if not getattr(self.body, 'stats', True):
4248 # most simple case: no exception variable, empty body (pass)
4249 # => reset the exception state, done
4250 code.putln("PyErr_Restore(0,0,0);")
4251 code.put_goto(end_label)
4255 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4258 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4259 # We always have to fetch the exception value even if
4260 # there is no target, because this also normalises the
4261 # exception and stores it in the thread state.
4262 code.globalstate.use_utility_code(get_exception_utility_code)
4263 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4264 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4265 code.error_goto(self.pos)))
4269 self.exc_value.set_var(exc_vars[1])
4270 self.exc_value.generate_evaluation_code(code)
4271 self.target.generate_assignment_code(self.exc_value, code)
4272 if self.excinfo_target is not None:
4273 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4274 node.set_var(tempvar)
4275 self.excinfo_tuple.generate_evaluation_code(code)
4276 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4278 old_break_label, old_continue_label = code.break_label, code.continue_label
4279 code.break_label = code.new_label('except_break')
4280 code.continue_label = code.new_label('except_continue')
4282 old_exc_vars = code.funcstate.exc_vars
4283 code.funcstate.exc_vars = exc_vars
4284 self.body.generate_execution_code(code)
4285 code.funcstate.exc_vars = old_exc_vars
4286 for var in exc_vars:
4287 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4288 code.put_goto(end_label)
4290 if code.label_used(code.break_label):
4291 code.put_label(code.break_label)
4292 for var in exc_vars:
4293 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4294 code.put_goto(old_break_label)
4295 code.break_label = old_break_label
4297 if code.label_used(code.continue_label):
4298 code.put_label(code.continue_label)
4299 for var in exc_vars:
4300 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4301 code.put_goto(old_continue_label)
4302 code.continue_label = old_continue_label
4304 for temp in exc_vars:
4305 code.funcstate.release_temp(temp)
4310 def annotate(self, code):
4312 self.pattern.annotate(code)
4314 self.target.annotate(code)
4315 self.body.annotate(code)
4318 class TryFinallyStatNode(StatNode):
4319 # try ... finally statement
4322 # finally_clause StatNode
4324 # The plan is that we funnel all continue, break
4325 # return and error gotos into the beginning of the
4326 # finally block, setting a variable to remember which
4327 # one we're doing. At the end of the finally block, we
4328 # switch on the variable to figure out where to go.
4329 # In addition, if we're doing an error, we save the
4330 # exception on entry to the finally block and restore
4333 child_attrs = ["body", "finally_clause"]
4335 preserve_exception = 1
4337 disallow_continue_in_try_finally = 0
4338 # There doesn't seem to be any point in disallowing
4339 # continue in the try block, since we have no problem
4342 def create_analysed(pos, env, body, finally_clause):
4343 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4345 create_analysed = staticmethod(create_analysed)
4347 def analyse_control_flow(self, env):
4348 env.start_branching(self.pos)
4349 self.body.analyse_control_flow(env)
4350 env.next_branch(self.body.end_pos())
4351 env.finish_branching(self.body.end_pos())
4352 self.finally_clause.analyse_control_flow(env)
4354 def analyse_declarations(self, env):
4355 self.body.analyse_declarations(env)
4356 self.finally_clause.analyse_declarations(env)
4358 def analyse_expressions(self, env):
4359 self.body.analyse_expressions(env)
4360 self.finally_clause.analyse_expressions(env)
4362 nogil_check = Node.gil_error
4363 gil_message = "Try-finally statement"
4365 def generate_execution_code(self, code):
4366 old_error_label = code.error_label
4367 old_labels = code.all_new_labels()
4368 new_labels = code.get_all_labels()
4369 new_error_label = code.error_label
4370 catch_label = code.new_label()
4373 if self.disallow_continue_in_try_finally:
4374 was_in_try_finally = code.funcstate.in_try_finally
4375 code.funcstate.in_try_finally = 1
4376 self.body.generate_execution_code(code)
4377 if self.disallow_continue_in_try_finally:
4378 code.funcstate.in_try_finally = was_in_try_finally
4381 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4385 error_label_used = 0
4386 for i, new_label in enumerate(new_labels):
4387 if new_label in code.labels_used:
4388 cases_used.append(i)
4389 if new_label == new_error_label:
4390 error_label_used = 1
4391 error_label_case = i
4395 if error_label_used and self.preserve_exception:
4397 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4399 "int %s;" % Naming.exc_lineno_name)
4400 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4401 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4402 code.putln(exc_var_init_zero)
4404 exc_var_init_zero = None
4405 code.use_label(catch_label)
4407 "__pyx_why = 0; goto %s;" % catch_label)
4408 for i in cases_used:
4409 new_label = new_labels[i]
4410 #if new_label and new_label != "<try>":
4411 if new_label == new_error_label and self.preserve_exception:
4412 self.put_error_catcher(code,
4413 new_error_label, i+1, catch_label, temps_to_clean_up)
4415 code.put('%s: ' % new_label)
4416 if exc_var_init_zero:
4417 code.putln(exc_var_init_zero)
4418 code.putln("__pyx_why = %s; goto %s;" % (
4421 code.put_label(catch_label)
4422 code.set_all_labels(old_labels)
4423 if error_label_used:
4424 code.new_error_label()
4425 finally_error_label = code.error_label
4426 self.finally_clause.generate_execution_code(code)
4427 if error_label_used:
4428 if finally_error_label in code.labels_used and self.preserve_exception:
4429 over_label = code.new_label()
4430 code.put_goto(over_label);
4431 code.put_label(finally_error_label)
4432 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4433 for var in Naming.exc_vars:
4434 code.putln("Py_XDECREF(%s);" % var)
4436 code.put_goto(old_error_label)
4437 code.put_label(over_label)
4438 code.error_label = old_error_label
4441 "switch (__pyx_why) {")
4442 for i in cases_used:
4443 old_label = old_labels[i]
4444 if old_label == old_error_label and self.preserve_exception:
4445 self.put_error_uncatcher(code, i+1, old_error_label)
4447 code.use_label(old_label)
4449 "case %s: goto %s;" % (
4457 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4458 code.globalstate.use_utility_code(restore_exception_utility_code)
4465 for temp_name, type in temps_to_clean_up:
4466 code.put_xdecref_clear(temp_name, type)
4468 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4472 Naming.exc_lineno_name, Naming.lineno_cname))
4476 code.put_goto(catch_label)
4480 def put_error_uncatcher(self, code, i, error_label):
4481 code.globalstate.use_utility_code(restore_exception_utility_code)
4486 "__Pyx_ErrRestore(%s, %s, %s);" %
4490 Naming.lineno_cname, Naming.exc_lineno_name))
4491 for var in Naming.exc_vars:
4495 code.put_goto(error_label)
4499 def annotate(self, code):
4500 self.body.annotate(code)
4501 self.finally_clause.annotate(code)
4504 class GILStatNode(TryFinallyStatNode):
4505 # 'with gil' or 'with nogil' statement
4507 # state string 'gil' or 'nogil'
4511 preserve_exception = 0
4513 def __init__(self, pos, state, body):
4515 TryFinallyStatNode.__init__(self, pos,
4517 finally_clause = GILExitNode(pos, state = state))
4519 def analyse_expressions(self, env):
4520 env.use_utility_code(force_init_threads_utility_code)
4521 was_nogil = env.nogil
4523 TryFinallyStatNode.analyse_expressions(self, env)
4524 env.nogil = was_nogil
4528 def generate_execution_code(self, code):
4529 code.mark_pos(self.pos)
4530 if self.state == 'gil':
4531 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4533 code.putln("{ PyThreadState *_save;")
4534 code.putln("Py_UNBLOCK_THREADS")
4535 TryFinallyStatNode.generate_execution_code(self, code)
4539 class GILExitNode(StatNode):
4540 # Used as the 'finally' block in a GILStatNode
4542 # state string 'gil' or 'nogil'
4546 def analyse_expressions(self, env):
4549 def generate_execution_code(self, code):
4550 if self.state == 'gil':
4551 code.putln("PyGILState_Release();")
4553 code.putln("Py_BLOCK_THREADS")
4556 class CImportStatNode(StatNode):
4559 # module_name string Qualified name of module being imported
4560 # as_name string or None Name specified in "as" clause, if any
4564 def analyse_declarations(self, env):
4565 if not env.is_module_scope:
4566 error(self.pos, "cimport only allowed at module level")
4568 module_scope = env.find_module(self.module_name, self.pos)
4569 if "." in self.module_name:
4570 names = [EncodedString(name) for name in self.module_name.split(".")]
4572 top_module_scope = env.context.find_submodule(top_name)
4573 module_scope = top_module_scope
4574 for name in names[1:]:
4575 submodule_scope = module_scope.find_submodule(name)
4576 module_scope.declare_module(name, submodule_scope, self.pos)
4577 module_scope = submodule_scope
4579 env.declare_module(self.as_name, module_scope, self.pos)
4581 env.declare_module(top_name, top_module_scope, self.pos)
4583 name = self.as_name or self.module_name
4584 env.declare_module(name, module_scope, self.pos)
4586 def analyse_expressions(self, env):
4589 def generate_execution_code(self, code):
4593 class FromCImportStatNode(StatNode):
4594 # from ... cimport statement
4596 # module_name string Qualified name of module
4597 # imported_names [(pos, name, as_name, kind)] Names to be imported
4601 def analyse_declarations(self, env):
4602 if not env.is_module_scope:
4603 error(self.pos, "cimport only allowed at module level")
4605 module_scope = env.find_module(self.module_name, self.pos)
4606 env.add_imported_module(module_scope)
4607 for pos, name, as_name, kind in self.imported_names:
4609 for local_name, entry in module_scope.entries.items():
4610 env.add_imported_entry(local_name, entry, pos)
4612 entry = module_scope.lookup(name)
4614 if kind and not self.declaration_matches(entry, kind):
4615 entry.redeclared(pos)
4617 if kind == 'struct' or kind == 'union':
4618 entry = module_scope.declare_struct_or_union(name,
4619 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4620 elif kind == 'class':
4621 entry = module_scope.declare_c_class(name, pos = pos,
4622 module_name = self.module_name)
4624 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4625 if submodule_scope.parent_module is module_scope:
4626 env.declare_module(as_name or name, submodule_scope, self.pos)
4628 error(pos, "Name '%s' not declared in module '%s'"
4629 % (name, self.module_name))
4632 local_name = as_name or name
4633 env.add_imported_entry(local_name, entry, pos)
4635 def declaration_matches(self, entry, kind):
4636 if not entry.is_type:
4640 if not type.is_extension_type:
4643 if not type.is_struct_or_union:
4645 if kind != type.kind:
4649 def analyse_expressions(self, env):
4652 def generate_execution_code(self, code):
4656 class FromImportStatNode(StatNode):
4657 # from ... import statement
4660 # items [(string, NameNode)]
4661 # interned_items [(string, NameNode, ExprNode)]
4662 # item PyTempNode used internally
4663 # import_star boolean used internally
4665 child_attrs = ["module"]
4668 def analyse_declarations(self, env):
4669 for name, target in self.items:
4671 if not env.is_module_scope:
4672 error(self.pos, "import * only allowed at module level")
4674 env.has_import_star = 1
4675 self.import_star = 1
4677 target.analyse_target_declaration(env)
4679 def analyse_expressions(self, env):
4681 self.module.analyse_expressions(env)
4682 self.item = ExprNodes.PyTempNode(self.pos, env)
4683 self.interned_items = []
4684 for name, target in self.items:
4686 for _, entry in env.entries.items():
4687 if not entry.is_type and entry.type.is_extension_type:
4688 env.use_utility_code(ExprNodes.type_test_utility_code)
4691 entry = env.lookup(target.name)
4692 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4693 continue # already cimported
4694 target.analyse_target_expression(env, None)
4695 if target.type is py_object_type:
4698 coerced_item = self.item.coerce_to(target.type, env)
4699 self.interned_items.append(
4700 (name, target, coerced_item))
4702 def generate_execution_code(self, code):
4703 self.module.generate_evaluation_code(code)
4704 if self.import_star:
4706 'if (%s(%s) < 0) %s;' % (
4708 self.module.py_result(),
4709 code.error_goto(self.pos)))
4710 self.item.allocate(code)
4711 for name, target, coerced_item in self.interned_items:
4712 cname = code.intern_identifier(name)
4714 '%s = PyObject_GetAttr(%s, %s); %s' % (
4716 self.module.py_result(),
4718 code.error_goto_if_null(self.item.result(), self.pos)))
4719 code.put_gotref(self.item.py_result())
4720 if coerced_item is None:
4721 target.generate_assignment_code(self.item, code)
4723 coerced_item.allocate_temp_result(code)
4724 coerced_item.generate_result_code(code)
4725 target.generate_assignment_code(coerced_item, code)
4726 if self.item.result() != coerced_item.result():
4727 code.put_decref_clear(self.item.result(), self.item.type)
4728 self.item.release(code)
4729 self.module.generate_disposal_code(code)
4730 self.module.free_temps(code)
4734 #------------------------------------------------------------------------------------
4736 # Runtime support code
4738 #------------------------------------------------------------------------------------
4740 utility_function_predeclarations = \
4743 #define INLINE __inline__
4745 #define INLINE __inline
4750 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4754 static int %(skip_dispatch_cname)s = 0;
4756 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4758 if Options.gcc_branch_hints:
4759 branch_prediction_macros = \
4762 /* Test for GCC > 2.95 */
4763 #if __GNUC__ > 2 || \
4764 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4765 #define likely(x) __builtin_expect(!!(x), 1)
4766 #define unlikely(x) __builtin_expect(!!(x), 0)
4767 #else /* __GNUC__ > 2 ... */
4768 #define likely(x) (x)
4769 #define unlikely(x) (x)
4770 #endif /* __GNUC__ > 2 ... */
4771 #else /* __GNUC__ */
4772 #define likely(x) (x)
4773 #define unlikely(x) (x)
4774 #endif /* __GNUC__ */
4777 branch_prediction_macros = \
4779 #define likely(x) (x)
4780 #define unlikely(x) (x)
4783 #get_name_predeclaration = \
4784 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4786 #get_name_interned_predeclaration = \
4787 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4789 #------------------------------------------------------------------------------------
4791 printing_utility_code = UtilityCode(
4793 static int __Pyx_Print(PyObject *, int); /*proto*/
4794 #if PY_MAJOR_VERSION >= 3
4795 static PyObject* %s = 0;
4796 static PyObject* %s = 0;
4798 """ % (Naming.print_function, Naming.print_function_kwargs),
4800 #if PY_MAJOR_VERSION < 3
4801 static PyObject *__Pyx_GetStdout(void) {
4802 PyObject *f = PySys_GetObject((char *)"stdout");
4804 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4809 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4814 if (!(f = __Pyx_GetStdout()))
4816 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4817 if (PyFile_SoftSpace(f, 1)) {
4818 if (PyFile_WriteString(" ", f) < 0)
4821 v = PyTuple_GET_ITEM(arg_tuple, i);
4822 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4824 if (PyString_Check(v)) {
4825 char *s = PyString_AsString(v);
4826 Py_ssize_t len = PyString_Size(v);
4828 isspace(Py_CHARMASK(s[len-1])) &&
4830 PyFile_SoftSpace(f, 0);
4834 if (PyFile_WriteString("\n", f) < 0)
4836 PyFile_SoftSpace(f, 0);
4841 #else /* Python 3 has a print function */
4843 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4844 PyObject* kwargs = 0;
4845 PyObject* result = 0;
4846 PyObject* end_string;
4847 if (!%(PRINT_FUNCTION)s) {
4848 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4849 if (!%(PRINT_FUNCTION)s)
4853 if (!%(PRINT_KWARGS)s) {
4854 %(PRINT_KWARGS)s = PyDict_New();
4855 if (!%(PRINT_KWARGS)s)
4857 end_string = PyUnicode_FromStringAndSize(" ", 1);
4860 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4861 Py_DECREF(end_string);
4864 Py_DECREF(end_string);
4866 kwargs = %(PRINT_KWARGS)s;
4868 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4876 """ % {'BUILTINS' : Naming.builtins_cname,
4877 'PRINT_FUNCTION' : Naming.print_function,
4878 'PRINT_KWARGS' : Naming.print_function_kwargs}
4882 printing_one_utility_code = UtilityCode(
4884 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4887 #if PY_MAJOR_VERSION < 3
4889 static int __Pyx_PrintOne(PyObject *o) {
4891 if (!(f = __Pyx_GetStdout()))
4893 if (PyFile_SoftSpace(f, 0)) {
4894 if (PyFile_WriteString(" ", f) < 0)
4897 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4899 if (PyFile_WriteString("\n", f) < 0)
4902 /* the line below is just to avoid compiler
4903 * compiler warnings about unused functions */
4904 return __Pyx_Print(NULL, 0);
4907 #else /* Python 3 has a print function */
4909 static int __Pyx_PrintOne(PyObject *o) {
4911 PyObject* arg_tuple = PyTuple_New(1);
4912 if (unlikely(!arg_tuple))
4915 PyTuple_SET_ITEM(arg_tuple, 0, o);
4916 res = __Pyx_Print(arg_tuple, 1);
4917 Py_DECREF(arg_tuple);
4923 requires=[printing_utility_code])
4927 #------------------------------------------------------------------------------------
4929 # The following function is based on do_raise() from ceval.c.
4931 raise_utility_code = UtilityCode(
4933 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4936 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4940 /* First, check the traceback argument, replacing None with NULL. */
4941 if (tb == Py_None) {
4945 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4946 PyErr_SetString(PyExc_TypeError,
4947 "raise: arg 3 must be a traceback or None");
4950 /* Next, replace a missing value with None */
4951 if (value == NULL) {
4955 #if PY_VERSION_HEX < 0x02050000
4956 if (!PyClass_Check(type))
4958 if (!PyType_Check(type))
4961 /* Raising an instance. The value should be a dummy. */
4962 if (value != Py_None) {
4963 PyErr_SetString(PyExc_TypeError,
4964 "instance exception may not have a separate value");
4967 /* Normalize to raise <class>, <instance> */
4970 #if PY_VERSION_HEX < 0x02050000
4971 if (PyInstance_Check(type)) {
4972 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4977 PyErr_SetString(PyExc_TypeError,
4978 "raise: exception must be an old-style class or instance");
4982 type = (PyObject*) Py_TYPE(type);
4984 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4985 PyErr_SetString(PyExc_TypeError,
4986 "raise: exception class must be a subclass of BaseException");
4991 __Pyx_ErrRestore(type, value, tb);
5001 #------------------------------------------------------------------------------------
5003 reraise_utility_code = UtilityCode(
5005 static void __Pyx_ReRaise(void); /*proto*/
5008 static void __Pyx_ReRaise(void) {
5009 PyThreadState *tstate = PyThreadState_GET();
5010 PyObject* tmp_type = tstate->curexc_type;
5011 PyObject* tmp_value = tstate->curexc_value;
5012 PyObject* tmp_tb = tstate->curexc_traceback;
5013 tstate->curexc_type = tstate->exc_type;
5014 tstate->curexc_value = tstate->exc_value;
5015 tstate->curexc_traceback = tstate->exc_traceback;
5016 tstate->exc_type = 0;
5017 tstate->exc_value = 0;
5018 tstate->exc_traceback = 0;
5019 Py_XDECREF(tmp_type);
5020 Py_XDECREF(tmp_value);
5025 #------------------------------------------------------------------------------------
5027 arg_type_test_utility_code = UtilityCode(
5029 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5030 const char *name, int exact); /*proto*/
5033 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5034 const char *name, int exact)
5037 PyErr_Format(PyExc_SystemError, "Missing type object");
5040 if (none_allowed && obj == Py_None) return 1;
5042 if (Py_TYPE(obj) == type) return 1;
5045 if (PyObject_TypeCheck(obj, type)) return 1;
5047 PyErr_Format(PyExc_TypeError,
5048 "Argument '%s' has incorrect type (expected %s, got %s)",
5049 name, type->tp_name, Py_TYPE(obj)->tp_name);
5054 #------------------------------------------------------------------------------------
5056 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5057 # many or too few positional arguments were found. This handles
5058 # Py_ssize_t formatting correctly.
5060 raise_argtuple_invalid_utility_code = UtilityCode(
5062 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5063 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5066 static void __Pyx_RaiseArgtupleInvalid(
5067 const char* func_name,
5071 Py_ssize_t num_found)
5073 Py_ssize_t num_expected;
5074 const char *number, *more_or_less;
5076 if (num_found < num_min) {
5077 num_expected = num_min;
5078 more_or_less = "at least";
5080 num_expected = num_max;
5081 more_or_less = "at most";
5084 more_or_less = "exactly";
5086 number = (num_expected == 1) ? "" : "s";
5087 PyErr_Format(PyExc_TypeError,
5088 #if PY_VERSION_HEX < 0x02050000
5089 "%s() takes %s %d positional argument%s (%d given)",
5091 "%s() takes %s %zd positional argument%s (%zd given)",
5093 func_name, more_or_less, num_expected, number, num_found);
5097 raise_keyword_required_utility_code = UtilityCode(
5099 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5102 static INLINE void __Pyx_RaiseKeywordRequired(
5103 const char* func_name,
5106 PyErr_Format(PyExc_TypeError,
5107 #if PY_MAJOR_VERSION >= 3
5108 "%s() needs keyword-only argument %U", func_name, kw_name);
5110 "%s() needs keyword-only argument %s", func_name,
5111 PyString_AS_STRING(kw_name));
5116 raise_double_keywords_utility_code = UtilityCode(
5118 static void __Pyx_RaiseDoubleKeywordsError(
5119 const char* func_name, PyObject* kw_name); /*proto*/
5122 static void __Pyx_RaiseDoubleKeywordsError(
5123 const char* func_name,
5126 PyErr_Format(PyExc_TypeError,
5127 #if PY_MAJOR_VERSION >= 3
5128 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5130 "%s() got multiple values for keyword argument '%s'", func_name,
5131 PyString_AS_STRING(kw_name));
5136 #------------------------------------------------------------------------------------
5138 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5139 # were passed to a function, or if any keywords were passed to a
5140 # function that does not accept them.
5142 keyword_string_check_utility_code = UtilityCode(
5144 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5145 const char* function_name, int kw_allowed); /*proto*/
5148 static INLINE int __Pyx_CheckKeywordStrings(
5150 const char* function_name,
5155 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5156 #if PY_MAJOR_VERSION < 3
5157 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5159 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5161 goto invalid_keyword_type;
5163 if ((!kw_allowed) && unlikely(key))
5164 goto invalid_keyword;
5166 invalid_keyword_type:
5167 PyErr_Format(PyExc_TypeError,
5168 "%s() keywords must be strings", function_name);
5171 PyErr_Format(PyExc_TypeError,
5172 #if PY_MAJOR_VERSION < 3
5173 "%s() got an unexpected keyword argument '%s'",
5174 function_name, PyString_AsString(key));
5176 "%s() got an unexpected keyword argument '%U'",
5177 function_name, key);
5183 #------------------------------------------------------------------------------------
5185 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5186 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5187 # keywords will raise an invalid keyword error.
5189 # Three kinds of errors are checked: 1) non-string keywords, 2)
5190 # unexpected keywords and 3) overlap with positional arguments.
5192 # If num_posargs is greater 0, it denotes the number of positional
5193 # arguments that were passed and that must therefore not appear
5194 # amongst the keywords as well.
5196 # This method does not check for required keyword arguments.
5199 parse_keywords_utility_code = UtilityCode(
5201 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5202 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5203 const char* function_name); /*proto*/
5206 static int __Pyx_ParseOptionalKeywords(
5208 PyObject **argnames[],
5211 Py_ssize_t num_pos_args,
5212 const char* function_name)
5214 PyObject *key = 0, *value = 0;
5217 PyObject*** first_kw_arg = argnames + num_pos_args;
5219 while (PyDict_Next(kwds, &pos, &key, &value)) {
5220 name = first_kw_arg;
5221 while (*name && (**name != key)) name++;
5223 values[name-argnames] = value;
5225 #if PY_MAJOR_VERSION < 3
5226 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5228 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5230 goto invalid_keyword_type;
5232 for (name = first_kw_arg; *name; name++) {
5233 #if PY_MAJOR_VERSION >= 3
5234 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5235 PyUnicode_Compare(**name, key) == 0) break;
5237 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5238 _PyString_Eq(**name, key)) break;
5242 values[name-argnames] = value;
5244 /* unexpected keyword found */
5245 for (name=argnames; name != first_kw_arg; name++) {
5246 if (**name == key) goto arg_passed_twice;
5247 #if PY_MAJOR_VERSION >= 3
5248 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5249 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5251 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5252 _PyString_Eq(**name, key)) goto arg_passed_twice;
5256 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5258 goto invalid_keyword;
5266 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5268 invalid_keyword_type:
5269 PyErr_Format(PyExc_TypeError,
5270 "%s() keywords must be strings", function_name);
5273 PyErr_Format(PyExc_TypeError,
5274 #if PY_MAJOR_VERSION < 3
5275 "%s() got an unexpected keyword argument '%s'",
5276 function_name, PyString_AsString(key));
5278 "%s() got an unexpected keyword argument '%U'",
5279 function_name, key);
5286 #------------------------------------------------------------------------------------
5288 traceback_utility_code = UtilityCode(
5290 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5293 #include "compile.h"
5294 #include "frameobject.h"
5295 #include "traceback.h"
5297 static void __Pyx_AddTraceback(const char *funcname) {
5298 PyObject *py_srcfile = 0;
5299 PyObject *py_funcname = 0;
5300 PyObject *py_globals = 0;
5301 PyCodeObject *py_code = 0;
5302 PyFrameObject *py_frame = 0;
5304 #if PY_MAJOR_VERSION < 3
5305 py_srcfile = PyString_FromString(%(FILENAME)s);
5307 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5309 if (!py_srcfile) goto bad;
5311 #if PY_MAJOR_VERSION < 3
5312 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5314 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5318 #if PY_MAJOR_VERSION < 3
5319 py_funcname = PyString_FromString(funcname);
5321 py_funcname = PyUnicode_FromString(funcname);
5324 if (!py_funcname) goto bad;
5325 py_globals = PyModule_GetDict(%(GLOBALS)s);
5326 if (!py_globals) goto bad;
5327 py_code = PyCode_New(
5328 0, /*int argcount,*/
5329 #if PY_MAJOR_VERSION >= 3
5330 0, /*int kwonlyargcount,*/
5333 0, /*int stacksize,*/
5335 %(EMPTY_BYTES)s, /*PyObject *code,*/
5336 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5337 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5338 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5339 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5340 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5341 py_srcfile, /*PyObject *filename,*/
5342 py_funcname, /*PyObject *name,*/
5343 %(LINENO)s, /*int firstlineno,*/
5344 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5346 if (!py_code) goto bad;
5347 py_frame = PyFrame_New(
5348 PyThreadState_GET(), /*PyThreadState *tstate,*/
5349 py_code, /*PyCodeObject *code,*/
5350 py_globals, /*PyObject *globals,*/
5351 0 /*PyObject *locals*/
5353 if (!py_frame) goto bad;
5354 py_frame->f_lineno = %(LINENO)s;
5355 PyTraceBack_Here(py_frame);
5357 Py_XDECREF(py_srcfile);
5358 Py_XDECREF(py_funcname);
5359 Py_XDECREF(py_code);
5360 Py_XDECREF(py_frame);
5363 'FILENAME': Naming.filename_cname,
5364 'LINENO': Naming.lineno_cname,
5365 'CFILENAME': Naming.cfilenm_cname,
5366 'CLINENO': Naming.clineno_cname,
5367 'GLOBALS': Naming.module_cname,
5368 'EMPTY_TUPLE' : Naming.empty_tuple,
5369 'EMPTY_BYTES' : Naming.empty_bytes,
5372 restore_exception_utility_code = UtilityCode(
5374 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5375 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5378 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5379 PyObject *tmp_type, *tmp_value, *tmp_tb;
5380 PyThreadState *tstate = PyThreadState_GET();
5382 #if PY_MAJOR_VERSION >= 3
5383 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5384 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5385 tmp_type = tstate->exc_type;
5386 tmp_value = tstate->exc_value;
5387 tmp_tb = tstate->exc_traceback;
5388 PyErr_NormalizeException(&type, &value, &tb);
5389 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5390 tstate->exc_type = 0;
5391 tstate->exc_value = 0;
5392 tstate->exc_traceback = 0;
5393 PyException_SetContext(value, tmp_value);
5394 Py_DECREF(tmp_type);
5399 tmp_type = tstate->curexc_type;
5400 tmp_value = tstate->curexc_value;
5401 tmp_tb = tstate->curexc_traceback;
5402 tstate->curexc_type = type;
5403 tstate->curexc_value = value;
5404 tstate->curexc_traceback = tb;
5405 Py_XDECREF(tmp_type);
5406 Py_XDECREF(tmp_value);
5410 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5411 PyThreadState *tstate = PyThreadState_GET();
5412 *type = tstate->curexc_type;
5413 *value = tstate->curexc_value;
5414 *tb = tstate->curexc_traceback;
5416 tstate->curexc_type = 0;
5417 tstate->curexc_value = 0;
5418 tstate->curexc_traceback = 0;
5423 #------------------------------------------------------------------------------------
5425 unraisable_exception_utility_code = UtilityCode(
5427 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5430 static void __Pyx_WriteUnraisable(const char *name) {
5431 PyObject *old_exc, *old_val, *old_tb;
5433 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5434 #if PY_MAJOR_VERSION < 3
5435 ctx = PyString_FromString(name);
5437 ctx = PyUnicode_FromString(name);
5439 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5441 PyErr_WriteUnraisable(Py_None);
5443 PyErr_WriteUnraisable(ctx);
5448 requires=[restore_exception_utility_code])
5450 #------------------------------------------------------------------------------------
5452 set_vtable_utility_code = UtilityCode(
5454 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5457 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5458 PyObject *pycobj = 0;
5461 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5464 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5477 #------------------------------------------------------------------------------------
5479 get_vtable_utility_code = UtilityCode(
5481 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5484 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5488 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5491 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5492 if (!*(void **)vtabptr)
5505 #------------------------------------------------------------------------------------
5507 init_string_tab_utility_code = UtilityCode(
5509 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5512 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5514 #if PY_MAJOR_VERSION < 3
5515 if (t->is_unicode && (!t->is_identifier)) {
5516 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5517 } else if (t->intern) {
5518 *t->p = PyString_InternFromString(t->s);
5520 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5522 #else /* Python 3+ has unicode identifiers */
5523 if (t->is_identifier || (t->is_unicode && t->intern)) {
5524 *t->p = PyUnicode_InternFromString(t->s);
5525 } else if (t->is_unicode) {
5526 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5528 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5539 #------------------------------------------------------------------------------------
5541 get_exception_utility_code = UtilityCode(
5543 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5546 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5547 PyObject *tmp_type, *tmp_value, *tmp_tb;
5548 PyThreadState *tstate = PyThreadState_GET();
5549 *type = tstate->curexc_type;
5550 *value = tstate->curexc_value;
5551 *tb = tstate->curexc_traceback;
5552 tstate->curexc_type = 0;
5553 tstate->curexc_value = 0;
5554 tstate->curexc_traceback = 0;
5555 PyErr_NormalizeException(type, value, tb);
5556 if (PyErr_Occurred())
5561 tmp_type = tstate->exc_type;
5562 tmp_value = tstate->exc_value;
5563 tmp_tb = tstate->exc_traceback;
5564 tstate->exc_type = *type;
5565 tstate->exc_value = *value;
5566 tstate->exc_traceback = *tb;
5567 /* Make sure tstate is in a consistent state when we XDECREF
5568 these objects (XDECREF may run arbitrary code). */
5569 Py_XDECREF(tmp_type);
5570 Py_XDECREF(tmp_value);
5582 #------------------------------------------------------------------------------------
5584 get_exception_tuple_utility_code = UtilityCode(proto="""
5585 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5588 static PyObject *__Pyx_GetExceptionTuple(void) {
5589 PyObject *type = NULL, *value = NULL, *tb = NULL;
5590 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5591 PyObject* exc_info = PyTuple_New(3);
5596 PyTuple_SET_ITEM(exc_info, 0, type);
5597 PyTuple_SET_ITEM(exc_info, 1, value);
5598 PyTuple_SET_ITEM(exc_info, 2, tb);
5605 requires=[get_exception_utility_code])
5607 #------------------------------------------------------------------------------------
5609 reset_exception_utility_code = UtilityCode(
5611 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5612 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5615 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5616 PyThreadState *tstate = PyThreadState_GET();
5617 *type = tstate->exc_type;
5618 *value = tstate->exc_value;
5619 *tb = tstate->exc_traceback;
5625 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5626 PyObject *tmp_type, *tmp_value, *tmp_tb;
5627 PyThreadState *tstate = PyThreadState_GET();
5628 tmp_type = tstate->exc_type;
5629 tmp_value = tstate->exc_value;
5630 tmp_tb = tstate->exc_traceback;
5631 tstate->exc_type = type;
5632 tstate->exc_value = value;
5633 tstate->exc_traceback = tb;
5634 Py_XDECREF(tmp_type);
5635 Py_XDECREF(tmp_value);
5640 #------------------------------------------------------------------------------------
5642 force_init_threads_utility_code = UtilityCode(
5644 #ifndef __PYX_FORCE_INIT_THREADS
5645 #if PY_VERSION_HEX < 0x02040200
5646 #define __PYX_FORCE_INIT_THREADS 1
5648 #define __PYX_FORCE_INIT_THREADS 0
5653 #------------------------------------------------------------------------------------
5655 # Note that cPython ignores PyTrace_EXCEPTION,
5656 # but maybe some other profilers don't.
5658 trace_utility_code = UtilityCode(proto="""
5659 #ifndef CYTHON_TRACING
5660 #define CYTHON_TRACING 1
5663 #ifndef CYTHON_TRACING_REUSE_FRAME
5664 #define CYTHON_TRACING_REUSE_FRAME 0
5669 #include "compile.h"
5670 #include "frameobject.h"
5671 #include "traceback.h"
5673 #if CYTHON_TRACING_REUSE_FRAME
5674 #define CYTHON_FRAME_MODIFIER static
5675 #define CYTHON_FRAME_DEL
5677 #define CYTHON_FRAME_MODIFIER
5678 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
5681 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
5682 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
5683 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
5684 int __Pyx_use_tracing = 0; \\
5685 if (PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5686 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
5689 #define __Pyx_TraceException() \\
5690 if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5691 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
5693 PyThreadState_GET()->c_profilefunc( \\
5694 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
5695 Py_DECREF(exc_info); \\
5699 #define __Pyx_TraceReturn(result) \\
5700 if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5701 PyThreadState_GET()->c_profilefunc( \\
5702 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
5703 CYTHON_FRAME_DEL; \\
5706 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5707 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5710 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
5711 #define __Pyx_TraceException()
5712 #define __Pyx_TraceReturn(result)
5713 #endif /* CYTHON_TRACING */
5716 "FRAME": Naming.frame_cname,
5717 "FRAME_CODE": Naming.frame_code_cname,
5723 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
5724 PyFrameObject** frame,
5725 const char *funcname,
5726 const char *srcfile,
5728 if (*frame == NULL || !CYTHON_TRACING_REUSE_FRAME) {
5729 if (*code == NULL) {
5730 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
5731 if (*code == NULL) return 0;
5733 *frame = PyFrame_New(
5734 PyThreadState_GET(), /*PyThreadState *tstate*/
5735 *code, /*PyCodeObject *code*/
5736 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
5737 0 /*PyObject *locals*/
5739 if (*frame == NULL) return 0;
5742 (*frame)->f_tstate = PyThreadState_GET();
5744 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
5747 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
5748 PyObject *py_srcfile = 0;
5749 PyObject *py_funcname = 0;
5750 PyCodeObject *py_code = 0;
5752 #if PY_MAJOR_VERSION < 3
5753 py_funcname = PyString_FromString(funcname);
5754 py_srcfile = PyString_FromString(srcfile);
5756 py_funcname = PyUnicode_FromString(funcname);
5757 py_srcfile = PyUnicode_FromString(srcfile);
5759 if (!py_funcname | !py_srcfile) goto bad;
5761 py_code = PyCode_New(
5762 0, /*int argcount,*/
5763 #if PY_MAJOR_VERSION >= 3
5764 0, /*int kwonlyargcount,*/
5767 0, /*int stacksize,*/
5769 %(EMPTY_BYTES)s, /*PyObject *code,*/
5770 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5771 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5772 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5773 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5774 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5775 py_srcfile, /*PyObject *filename,*/
5776 py_funcname, /*PyObject *name,*/
5777 firstlineno, /*int firstlineno,*/
5778 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5782 Py_XDECREF(py_srcfile);
5783 Py_XDECREF(py_funcname);
5788 #endif /* CYTHON_TRACING */
5790 'EMPTY_TUPLE' : Naming.empty_tuple,
5791 'EMPTY_BYTES' : Naming.empty_bytes,
5792 "MODULE": Naming.module_cname,