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 generate_execution_code(self, code):
910 if self.visibility == 'public':
911 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
912 for item in self.entry.enum_values:
913 code.putln("%s = PyInt_FromLong(%s); %s" % (
916 code.error_goto_if_null(temp, item.pos)))
917 code.put_gotref(temp)
918 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
922 code.error_goto(item.pos)))
923 code.put_decref_clear(temp, PyrexTypes.py_object_type)
924 code.funcstate.release_temp(temp)
927 class CEnumDefItemNode(StatNode):
929 # cname string or None
930 # value ExprNode or None
932 child_attrs = ["value"]
934 def analyse_declarations(self, env, enum_entry):
936 self.value.analyse_const_expression(env)
937 if not self.value.type.is_int:
938 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
939 self.value.analyse_const_expression(env)
940 entry = env.declare_const(self.name, enum_entry.type,
941 self.value, self.pos, cname = self.cname,
942 visibility = enum_entry.visibility)
943 enum_entry.enum_values.append(entry)
946 class CTypeDefNode(StatNode):
947 # base_type CBaseTypeNode
948 # declarator CDeclaratorNode
949 # visibility "public" or "private"
952 child_attrs = ["base_type", "declarator"]
954 def analyse_declarations(self, env):
955 base = self.base_type.analyse(env)
956 name_declarator, type = self.declarator.analyse(base, env)
957 name = name_declarator.name
958 cname = name_declarator.cname
959 entry = env.declare_typedef(name, type, self.pos,
960 cname = cname, visibility = self.visibility)
961 if self.in_pxd and not env.in_cinclude:
962 entry.defined_in_pxd = 1
964 def analyse_expressions(self, env):
966 def generate_execution_code(self, code):
970 class FuncDefNode(StatNode, BlockNode):
971 # Base class for function definition nodes.
973 # return_type PyrexType
974 # #filename string C name of filename string const
976 # needs_closure boolean Whether or not this function has inner functions/classes/yield
977 # directive_locals { string : NameNode } locals defined by cython.locals(...)
981 needs_closure = False
984 def analyse_default_values(self, env):
985 genv = env.global_scope()
987 for arg in self.args:
991 arg.default.analyse_types(env)
992 arg.default = arg.default.coerce_to(arg.type, genv)
995 "This argument cannot have a default value")
1000 error(arg.pos, "Non-default argument following default argument")
1002 def need_gil_acquisition(self, lenv):
1005 def create_local_scope(self, env):
1007 while env.is_py_class_scope or env.is_c_class_scope:
1008 env = env.outer_scope
1009 if self.needs_closure:
1010 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1012 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1013 lenv.return_type = self.return_type
1014 type = self.entry.type
1015 if type.is_cfunction:
1016 lenv.nogil = type.nogil and not type.with_gil
1017 self.local_scope = lenv
1018 lenv.directives = env.directives
1021 def generate_function_definitions(self, env, code):
1024 lenv = self.local_scope
1026 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1027 self.entry.scope.is_c_class_scope)
1029 if code.globalstate.directives['profile'] is None:
1030 profile = 'inline' not in self.modifiers and not lenv.nogil
1032 profile = code.globalstate.directives['profile']
1033 if profile and lenv.nogil:
1034 error(self.pos, "Cannot profile nogil function.")
1036 code.globalstate.use_utility_code(trace_utility_code)
1038 # Generate C code for header and body of function
1039 code.enter_cfunc_scope()
1040 code.return_from_error_cleanup_label = code.new_label()
1042 # ----- Top-level constants used by this function
1043 code.mark_pos(self.pos)
1044 self.generate_cached_builtins_decls(lenv, code)
1045 # ----- Function header
1048 self.py_func.generate_function_header(code,
1049 with_pymethdef = env.is_py_class_scope,
1051 self.generate_function_header(code,
1052 with_pymethdef = env.is_py_class_scope)
1053 # ----- Local variable declarations
1054 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1055 self.generate_argument_declarations(lenv, code)
1056 if self.needs_closure:
1057 code.putln("/* TODO: declare and create scope object */")
1058 code.put_var_declarations(lenv.var_entries)
1060 if not self.return_type.is_void:
1061 if self.return_type.is_pyobject:
1065 (self.return_type.declaration_code(
1066 Naming.retval_cname),
1068 tempvardecl_code = code.insertion_point()
1069 self.generate_keyword_list(code)
1070 # ----- Extern library function declarations
1071 lenv.generate_library_function_declarations(code)
1072 # ----- GIL acquisition
1073 acquire_gil = self.acquire_gil
1075 env.use_utility_code(force_init_threads_utility_code)
1076 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1077 # ----- Automatic lead-ins for certain special functions
1079 code.put_trace_call(self.entry.name, self.pos)
1081 code.put_setup_refcount_context(self.entry.name)
1082 if is_getbuffer_slot:
1083 self.getbuffer_init(code)
1084 # ----- Fetch arguments
1085 self.generate_argument_parsing_code(env, code)
1086 # If an argument is assigned to in the body, we must
1087 # incref it to properly keep track of refcounts.
1088 for entry in lenv.arg_entries:
1089 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1090 code.put_var_incref(entry)
1091 # ----- Initialise local variables
1092 for entry in lenv.var_entries:
1093 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1094 code.put_init_var_to_py_none(entry)
1095 # ----- Initialise local buffer auxiliary variables
1096 for entry in lenv.var_entries + lenv.arg_entries:
1097 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1098 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1099 # ----- Check and convert arguments
1100 self.generate_argument_type_tests(code)
1101 # ----- Acquire buffer arguments
1102 for entry in lenv.arg_entries:
1103 if entry.type.is_buffer:
1104 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1105 # ----- Function body
1106 self.body.generate_execution_code(code)
1107 # ----- Default return value
1109 if self.return_type.is_pyobject:
1110 #if self.return_type.is_extension_type:
1111 # lhs = "(PyObject *)%s" % Naming.retval_cname
1113 lhs = Naming.retval_cname
1114 code.put_init_to_py_none(lhs, self.return_type)
1116 val = self.return_type.default_value
1118 code.putln("%s = %s;" % (Naming.retval_cname, val))
1119 # ----- Error cleanup
1120 if code.error_label in code.labels_used:
1121 code.put_goto(code.return_label)
1122 code.put_label(code.error_label)
1123 for cname, type in code.funcstate.all_managed_temps():
1124 code.put_xdecref(cname, type)
1126 # Clean up buffers -- this calls a Python function
1127 # so need to save and restore error state
1128 buffers_present = len(lenv.buffer_entries) > 0
1130 code.globalstate.use_utility_code(restore_exception_utility_code)
1131 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1132 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1133 for entry in lenv.buffer_entries:
1134 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1135 #code.putln("%s = 0;" % entry.cname)
1136 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1138 err_val = self.error_value()
1139 exc_check = self.caller_will_check_exceptions()
1140 if err_val is not None or exc_check:
1141 # TODO: Fix exception tracing (though currently unused by cProfile).
1142 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1143 # code.put_trace_exception()
1144 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1146 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1147 % self.entry.qualified_name, 0)
1149 '__Pyx_WriteUnraisable("%s");' %
1150 self.entry.qualified_name)
1151 env.use_utility_code(unraisable_exception_utility_code)
1152 env.use_utility_code(restore_exception_utility_code)
1153 default_retval = self.return_type.default_value
1154 if err_val is None and default_retval:
1155 err_val = default_retval
1156 if err_val is not None:
1159 Naming.retval_cname,
1162 if is_getbuffer_slot:
1163 self.getbuffer_error_cleanup(code)
1165 # If we are using the non-error cleanup section we should
1166 # jump past it if we have an error. The if-test below determine
1167 # whether this section is used.
1168 if buffers_present or is_getbuffer_slot:
1169 code.put_goto(code.return_from_error_cleanup_label)
1172 # ----- Non-error return cleanup
1173 code.put_label(code.return_label)
1174 for entry in lenv.buffer_entries:
1176 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1177 if is_getbuffer_slot:
1178 self.getbuffer_normal_cleanup(code)
1179 # ----- Return cleanup for both error and no-error return
1180 code.put_label(code.return_from_error_cleanup_label)
1181 if not Options.init_local_none:
1182 for entry in lenv.var_entries:
1183 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1184 entry.xdecref_cleanup = 1
1185 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1186 # Decref any increfed args
1187 for entry in lenv.arg_entries:
1188 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1189 code.put_var_decref(entry)
1191 # code.putln("/* TODO: decref scope object */")
1193 # This code is duplicated in ModuleNode.generate_module_init_func
1195 default_retval = self.return_type.default_value
1196 err_val = self.error_value()
1197 if err_val is None and default_retval:
1198 err_val = default_retval
1199 if self.return_type.is_pyobject:
1200 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1202 code.put_finish_refcount_context()
1204 if self.entry.is_special and self.entry.name == "__hash__":
1205 # Returning -1 for __hash__ is supposed to signal an error
1206 # We do as Python instances and coerce -1 into -2.
1207 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1210 if self.return_type.is_pyobject:
1211 code.put_trace_return(Naming.retval_cname)
1213 code.put_trace_return("Py_None")
1216 code.putln("PyGILState_Release(_save);")
1218 if not self.return_type.is_void:
1219 code.putln("return %s;" % Naming.retval_cname)
1222 # ----- Go back and insert temp variable declarations
1223 tempvardecl_code.put_temp_declarations(code.funcstate)
1224 # ----- Python version
1225 code.exit_cfunc_scope()
1227 self.py_func.generate_function_definitions(env, code)
1228 self.generate_wrapper_functions(code)
1230 def declare_argument(self, env, arg):
1231 if arg.type.is_void:
1232 error(arg.pos, "Invalid use of 'void'")
1233 elif not arg.type.is_complete() and not arg.type.is_array:
1235 "Argument type '%s' is incomplete" % arg.type)
1236 return env.declare_arg(arg.name, arg.type, arg.pos)
1238 def generate_wrapper_functions(self, code):
1241 def generate_execution_code(self, code):
1242 # Evaluate and store argument default values
1243 for arg in self.args:
1244 default = arg.default
1246 if not default.is_literal:
1247 default.generate_evaluation_code(code)
1248 default.make_owned_reference(code)
1249 result = default.result_as(arg.type)
1252 arg.calculate_default_value_code(code),
1254 if arg.type.is_pyobject:
1255 code.put_giveref(default.result())
1256 default.generate_post_assignment_code(code)
1257 default.free_temps(code)
1258 # For Python class methods, create and store function object
1260 self.assmt.generate_execution_code(code)
1263 # Special code for the __getbuffer__ function
1265 def getbuffer_init(self, code):
1266 info = self.local_scope.arg_entries[1].cname
1267 # Python 3.0 betas have a bug in memoryview which makes it call
1268 # getbuffer with a NULL parameter. For now we work around this;
1269 # the following line should be removed when this bug is fixed.
1270 code.putln("if (%s == NULL) return 0;" % info)
1271 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1272 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1274 def getbuffer_error_cleanup(self, code):
1275 info = self.local_scope.arg_entries[1].cname
1276 code.put_gotref("%s->obj" % info)
1277 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1280 def getbuffer_normal_cleanup(self, code):
1281 info = self.local_scope.arg_entries[1].cname
1282 code.putln("if (%s->obj == Py_None) {" % info)
1283 code.put_gotref("Py_None")
1284 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1287 class CFuncDefNode(FuncDefNode):
1288 # C function definition.
1290 # modifiers ['inline']
1291 # visibility 'private' or 'public' or 'extern'
1292 # base_type CBaseTypeNode
1293 # declarator CDeclaratorNode
1296 # decorators [DecoratorNode] list of decorators
1298 # with_gil boolean Acquire GIL around body
1300 # py_func wrapper for calling from Python
1301 # overridable whether or not this is a cpdef function
1302 # inline_in_pxd whether this is an inline function in a pxd file
1304 child_attrs = ["base_type", "declarator", "body", "py_func"]
1306 inline_in_pxd = False
1308 directive_locals = {}
1310 def unqualified_name(self):
1311 return self.entry.name
1313 def analyse_declarations(self, env):
1314 self.directive_locals.update(env.directives['locals'])
1315 base_type = self.base_type.analyse(env)
1316 # The 2 here is because we need both function and argument names.
1317 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1318 if not type.is_cfunction:
1320 "Suite attached to non-function declaration")
1321 # Remember the actual type according to the function header
1322 # written here, because the type in the symbol table entry
1323 # may be different if we're overriding a C method inherited
1324 # from the base type of an extension type.
1326 type.is_overridable = self.overridable
1327 declarator = self.declarator
1328 while not hasattr(declarator, 'args'):
1329 declarator = declarator.base
1330 self.args = declarator.args
1331 for formal_arg, type_arg in zip(self.args, type.args):
1332 formal_arg.type = type_arg.type
1333 formal_arg.name = type_arg.name
1334 formal_arg.cname = type_arg.cname
1335 name = name_declarator.name
1336 cname = name_declarator.cname
1337 self.entry = env.declare_cfunction(
1338 name, type, self.pos,
1339 cname = cname, visibility = self.visibility,
1340 defining = self.body is not None,
1341 api = self.api, modifiers = self.modifiers)
1342 self.entry.inline_func_in_pxd = self.inline_in_pxd
1343 self.return_type = type.return_type
1345 if self.overridable and not env.is_module_scope:
1346 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1347 # An error will be produced in the cdef function
1348 self.overridable = False
1350 if self.overridable:
1352 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1353 self.py_func = DefNode(pos = self.pos,
1354 name = self.entry.name,
1357 starstar_arg = None,
1359 body = py_func_body,
1361 self.py_func.is_module_scope = env.is_module_scope
1362 self.py_func.analyse_declarations(env)
1363 self.entry.as_variable = self.py_func.entry
1364 # Reset scope entry the above cfunction
1365 env.entries[name] = self.entry
1366 if not env.is_module_scope or Options.lookup_module_cpdef:
1367 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1368 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1370 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1372 args = self.type.args
1373 if omit_optional_args:
1374 args = args[:len(args) - self.type.optional_arg_count]
1375 arg_names = [arg.name for arg in args]
1377 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1379 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1380 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1381 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1382 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)
1383 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1385 def declare_arguments(self, env):
1386 for arg in self.type.args:
1388 error(arg.pos, "Missing argument name")
1389 self.declare_argument(env, arg)
1391 def need_gil_acquisition(self, lenv):
1392 return self.type.with_gil
1394 def nogil_check(self, env):
1396 with_gil = type.with_gil
1397 if type.nogil and not with_gil:
1398 if type.return_type.is_pyobject:
1400 "Function with Python return type cannot be declared nogil")
1401 for entry in self.local_scope.var_entries:
1402 if entry.type.is_pyobject:
1403 error(self.pos, "Function declared nogil has Python locals or temporaries")
1405 def analyse_expressions(self, env):
1406 self.local_scope.directives = env.directives
1407 if self.py_func is not None:
1408 # this will also analyse the default values
1409 self.py_func.analyse_expressions(env)
1411 self.analyse_default_values(env)
1412 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1414 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1417 visibility = self.entry.visibility
1418 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1419 arg_decls.append(arg.declaration_code())
1420 if with_dispatch and self.overridable:
1421 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1422 if type.optional_arg_count and with_opt_args:
1423 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1424 if type.has_varargs:
1425 arg_decls.append("...")
1427 arg_decls = ["void"]
1429 cname = self.entry.func_cname
1430 entity = type.function_header_code(cname, ', '.join(arg_decls))
1431 if visibility == 'public':
1432 dll_linkage = "DL_EXPORT"
1435 header = self.return_type.declaration_code(entity,
1436 dll_linkage = dll_linkage)
1437 if visibility == 'extern':
1438 storage_class = "%s " % Naming.extern_c_macro
1439 elif visibility == 'public':
1442 storage_class = "static "
1443 code.putln("%s%s %s {" % (
1445 ' '.join(self.modifiers).upper(), # macro forms
1448 def generate_argument_declarations(self, env, code):
1449 for arg in self.args:
1451 result = arg.calculate_default_value_code(code)
1452 code.putln('%s = %s;' % (
1453 arg.type.declaration_code(arg.cname), result))
1455 def generate_keyword_list(self, code):
1458 def generate_argument_parsing_code(self, env, code):
1460 if self.type.optional_arg_count:
1461 code.putln('if (%s) {' % Naming.optional_args_cname)
1462 for arg in self.args:
1464 # FIXME: simple name prefixing doesn't work when
1465 # argument name mangling is in place
1466 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1467 declarator = arg.declarator
1468 while not hasattr(declarator, 'name'):
1469 declarator = declarator.base
1470 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1472 for _ in range(self.type.optional_arg_count):
1476 def generate_argument_conversion_code(self, code):
1479 def generate_argument_type_tests(self, code):
1480 # Generate type tests for args whose type in a parent
1481 # class is a supertype of the declared type.
1482 for arg in self.type.args:
1483 if arg.needs_type_test:
1484 self.generate_arg_type_test(arg, code)
1486 def generate_arg_type_test(self, arg, code):
1487 # Generate type test for one argument.
1488 if arg.type.typeobj_is_available():
1489 typeptr_cname = arg.type.typeptr_cname
1490 arg_code = "((PyObject *)%s)" % arg.cname
1492 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1497 type.is_builtin_type,
1498 code.error_goto(arg.pos)))
1500 error(arg.pos, "Cannot test type of extern C class "
1501 "without type object name specification")
1503 def error_value(self):
1504 if self.return_type.is_pyobject:
1508 return self.entry.type.exception_value
1510 def caller_will_check_exceptions(self):
1511 return self.entry.type.exception_check
1513 def generate_wrapper_functions(self, code):
1514 # If the C signature of a function has changed, we need to generate
1515 # wrappers to put in the slots here.
1518 func_type = entry.type
1519 while entry.prev_entry is not None:
1521 entry = entry.prev_entry
1522 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1524 self.generate_function_header(code,
1526 with_dispatch = entry.type.is_overridable,
1527 with_opt_args = entry.type.optional_arg_count,
1528 cname = entry.func_cname)
1529 if not self.return_type.is_void:
1531 args = self.type.args
1532 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1533 if entry.type.is_overridable:
1534 arglist.append(Naming.skip_dispatch_cname)
1535 elif func_type.is_overridable:
1537 if entry.type.optional_arg_count:
1538 arglist.append(Naming.optional_args_cname)
1539 elif func_type.optional_arg_count:
1540 arglist.append('NULL')
1541 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1545 class PyArgDeclNode(Node):
1546 # Argument which must be a Python object (used
1547 # for * and ** arguments).
1550 # entry Symtab.Entry
1554 class DecoratorNode(Node):
1557 # decorator NameNode or CallNode
1558 child_attrs = ['decorator']
1561 class DefNode(FuncDefNode):
1562 # A Python function definition.
1564 # name string the Python name of the function
1565 # decorators [DecoratorNode] list of decorators
1566 # args [CArgDeclNode] formal arguments
1567 # star_arg PyArgDeclNode or None * argument
1568 # starstar_arg PyArgDeclNode or None ** argument
1569 # doc EncodedString or None
1572 # The following subnode is constructed internally
1573 # when the def statement is inside a Python class definition.
1575 # assmt AssignmentNode Function construction/assignment
1577 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1581 num_required_kw_args = 0
1582 reqd_kw_flags_cname = "0"
1589 def __init__(self, pos, **kwds):
1590 FuncDefNode.__init__(self, pos, **kwds)
1592 for arg in self.args:
1599 self.num_kwonly_args = k
1600 self.num_required_kw_args = rk
1601 self.num_required_args = r
1603 def as_cfunction(self, cfunc=None, scope=None):
1605 error(self.star_arg.pos, "cdef function cannot have star argument")
1606 if self.starstar_arg:
1607 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1610 for formal_arg in self.args:
1611 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1612 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1614 type = py_object_type,
1615 pos = formal_arg.pos))
1616 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1618 has_varargs = False,
1619 exception_value = None,
1620 exception_check = False,
1623 is_overridable = True)
1624 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1626 cfunc_type = cfunc.type
1627 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1628 error(self.pos, "wrong number of arguments")
1629 error(declarator.pos, "previous declaration here")
1630 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1631 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1632 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1633 formal_arg.type = type_arg.type
1634 formal_arg.name_declarator = name_declarator
1636 if cfunc_type.exception_value is None:
1637 exception_value = None
1639 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1640 declarator = CFuncDeclaratorNode(self.pos,
1641 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1643 has_varargs = False,
1644 exception_check = cfunc_type.exception_check,
1645 exception_value = exception_value,
1646 with_gil = cfunc_type.with_gil,
1647 nogil = cfunc_type.nogil)
1648 return CFuncDefNode(self.pos,
1650 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1651 declarator = declarator,
1654 overridable = cfunc_type.is_overridable,
1656 with_gil = cfunc_type.with_gil,
1657 nogil = cfunc_type.nogil,
1658 visibility = 'private',
1660 directive_locals = getattr(cfunc, 'directive_locals', {}))
1662 def analyse_declarations(self, env):
1663 directive_locals = self.directive_locals = env.directives['locals']
1664 for arg in self.args:
1665 if hasattr(arg, 'name'):
1667 name_declarator = None
1669 base_type = arg.base_type.analyse(env)
1670 name_declarator, type = \
1671 arg.declarator.analyse(base_type, env)
1672 arg.name = name_declarator.name
1673 if arg.name in directive_locals:
1674 type_node = directive_locals[arg.name]
1675 other_type = type_node.analyse_as_type(env)
1676 if other_type is None:
1677 error(type_node.pos, "Not a type")
1678 elif (type is not PyrexTypes.py_object_type
1679 and not type.same_as(other_type)):
1680 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1681 error(type_node.pos, "Previous declaration here")
1684 if name_declarator and name_declarator.cname:
1686 "Python function argument cannot have C name specification")
1687 arg.type = type.as_argument_type()
1689 arg.needs_conversion = 0
1690 arg.needs_type_test = 0
1692 if arg.not_none and not arg.type.is_extension_type:
1694 "Only extension type arguments can have 'not None'")
1695 self.declare_pyfunction(env)
1696 self.analyse_signature(env)
1697 self.return_type = self.entry.signature.return_type()
1699 def analyse_signature(self, env):
1700 any_type_tests_needed = 0
1701 if self.entry.is_special:
1702 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1703 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1704 # Use the simpler calling signature for zero- and one-argument functions.
1705 if self.entry.signature is TypeSlots.pyfunction_signature:
1706 if len(self.args) == 0:
1707 self.entry.signature = TypeSlots.pyfunction_noargs
1708 elif len(self.args) == 1:
1709 if self.args[0].default is None and not self.args[0].kw_only:
1710 self.entry.signature = TypeSlots.pyfunction_onearg
1711 elif self.entry.signature is TypeSlots.pymethod_signature:
1712 if len(self.args) == 1:
1713 self.entry.signature = TypeSlots.unaryfunc
1714 elif len(self.args) == 2:
1715 if self.args[1].default is None and not self.args[1].kw_only:
1716 self.entry.signature = TypeSlots.ibinaryfunc
1717 sig = self.entry.signature
1718 nfixed = sig.num_fixed_args()
1719 for i in range(nfixed):
1720 if i < len(self.args):
1723 if sig.is_self_arg(i):
1725 arg.hdr_type = arg.type = env.parent_type
1726 arg.needs_conversion = 0
1728 arg.hdr_type = sig.fixed_arg_type(i)
1729 if not arg.type.same_as(arg.hdr_type):
1730 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1731 arg.needs_type_test = 1
1732 any_type_tests_needed = 1
1734 arg.needs_conversion = 1
1735 if arg.needs_conversion:
1736 arg.hdr_cname = Naming.arg_prefix + arg.name
1738 arg.hdr_cname = Naming.var_prefix + arg.name
1740 self.bad_signature()
1742 if nfixed < len(self.args):
1743 if not sig.has_generic_args:
1744 self.bad_signature()
1745 for arg in self.args:
1746 if arg.is_generic and \
1747 (arg.type.is_extension_type or arg.type.is_builtin_type):
1748 arg.needs_type_test = 1
1749 any_type_tests_needed = 1
1750 if any_type_tests_needed:
1751 env.use_utility_code(arg_type_test_utility_code)
1753 def bad_signature(self):
1754 sig = self.entry.signature
1755 expected_str = "%d" % sig.num_fixed_args()
1756 if sig.has_generic_args:
1757 expected_str = expected_str + " or more"
1759 if name.startswith("__") and name.endswith("__"):
1760 desc = "Special method"
1764 "%s %s has wrong number of arguments "
1765 "(%d declared, %s expected)" % (
1766 desc, self.name, len(self.args), expected_str))
1768 def signature_has_nongeneric_args(self):
1769 argcount = len(self.args)
1770 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1774 def signature_has_generic_args(self):
1775 return self.entry.signature.has_generic_args
1777 def declare_pyfunction(self, env):
1778 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1780 entry = env.lookup_here(self.name)
1781 if entry and entry.type.is_cfunction and not self.is_wrapper:
1782 warning(self.pos, "Overriding cdef method with def method.", 5)
1783 entry = env.declare_pyfunction(self.name, self.pos)
1785 prefix = env.scope_prefix
1786 entry.func_cname = \
1787 Naming.pyfunc_prefix + prefix + name
1788 entry.pymethdef_cname = \
1789 Naming.pymethdef_prefix + prefix + name
1790 if Options.docstrings:
1791 entry.doc = embed_position(self.pos, self.doc)
1793 Naming.funcdoc_prefix + prefix + name
1797 def declare_arguments(self, env):
1798 for arg in self.args:
1800 error(arg.pos, "Missing argument name")
1801 if arg.needs_conversion:
1802 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1803 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1804 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1805 if arg.type.is_pyobject:
1806 arg.entry.init = "0"
1807 arg.entry.init_to_none = 0
1809 arg.entry = self.declare_argument(env, arg)
1811 arg.entry.is_self_arg = arg.is_self_arg
1813 if arg.is_self_arg or \
1814 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1815 arg.entry.is_declared_generic = 1
1816 self.declare_python_arg(env, self.star_arg)
1817 self.declare_python_arg(env, self.starstar_arg)
1819 def declare_python_arg(self, env, arg):
1821 entry = env.declare_var(arg.name,
1822 PyrexTypes.py_object_type, arg.pos)
1825 entry.init_to_none = 0
1826 entry.xdecref_cleanup = 1
1828 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1830 def analyse_expressions(self, env):
1831 self.local_scope.directives = env.directives
1832 self.analyse_default_values(env)
1833 if env.is_py_class_scope:
1834 self.synthesize_assignment_node(env)
1836 def synthesize_assignment_node(self, env):
1838 self.assmt = SingleAssignmentNode(self.pos,
1839 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1840 rhs = ExprNodes.UnboundMethodNode(self.pos,
1841 function = ExprNodes.PyCFunctionNode(self.pos,
1842 pymethdef_cname = self.entry.pymethdef_cname)))
1843 self.assmt.analyse_declarations(env)
1844 self.assmt.analyse_expressions(env)
1846 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1848 sig = self.entry.signature
1849 if sig.has_dummy_arg:
1850 arg_code_list.append(
1851 "PyObject *%s" % Naming.self_cname)
1852 for arg in self.args:
1853 if not arg.is_generic:
1855 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1857 arg_code_list.append(
1858 arg.hdr_type.declaration_code(arg.hdr_cname))
1859 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1860 arg_code_list.append("PyObject *unused")
1861 if sig.has_generic_args:
1862 arg_code_list.append(
1863 "PyObject *%s, PyObject *%s"
1864 % (Naming.args_cname, Naming.kwds_cname))
1865 arg_code = ", ".join(arg_code_list)
1866 dc = self.return_type.declaration_code(self.entry.func_cname)
1867 header = "static %s(%s)" % (dc, arg_code)
1868 code.putln("%s; /*proto*/" % header)
1871 if self.entry.doc and Options.docstrings:
1872 docstr = self.entry.doc
1873 if docstr.is_unicode:
1874 docstr = docstr.utf8encode()
1876 'static char %s[] = "%s";' % (
1877 self.entry.doc_cname,
1878 split_docstring(escape_byte_string(docstr))))
1881 "static PyMethodDef %s = " %
1882 self.entry.pymethdef_cname)
1883 code.put_pymethoddef(self.entry, ";")
1884 code.putln("%s {" % header)
1886 def generate_argument_declarations(self, env, code):
1887 for arg in self.args:
1888 if arg.is_generic: # or arg.needs_conversion:
1889 if arg.needs_conversion:
1890 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1892 code.put_var_declaration(arg.entry)
1894 def generate_keyword_list(self, code):
1895 if self.signature_has_generic_args() and \
1896 self.signature_has_nongeneric_args():
1898 "static PyObject **%s[] = {" %
1899 Naming.pykwdlist_cname)
1900 for arg in self.args:
1902 pystring_cname = code.intern_identifier(arg.name)
1903 code.put('&%s,' % pystring_cname)
1906 def generate_argument_parsing_code(self, env, code):
1907 # Generate PyArg_ParseTuple call for generic
1908 # arguments, if any.
1909 if self.entry.signature.has_dummy_arg:
1910 # get rid of unused argument warning
1911 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1913 old_error_label = code.new_error_label()
1914 our_error_label = code.error_label
1915 end_label = code.new_label("argument_unpacking_done")
1917 has_kwonly_args = self.num_kwonly_args > 0
1918 has_star_or_kw_args = self.star_arg is not None \
1919 or self.starstar_arg is not None or has_kwonly_args
1921 for arg in self.args:
1922 if not arg.type.is_pyobject:
1923 done = arg.type.create_from_py_utility_code(env)
1924 if not done: pass # will fail later
1926 if not self.signature_has_generic_args():
1927 if has_star_or_kw_args:
1928 error(self.pos, "This method cannot have * or keyword arguments")
1929 self.generate_argument_conversion_code(code)
1931 elif not self.signature_has_nongeneric_args():
1932 # func(*args) or func(**kw) or func(*args, **kw)
1933 self.generate_stararg_copy_code(code)
1936 positional_args = []
1938 for arg in self.args:
1939 arg_entry = arg.entry
1942 if not arg.is_self_arg:
1944 kw_only_args.append(arg)
1946 positional_args.append(arg)
1948 kw_only_args.append(arg)
1949 elif not arg.is_self_arg:
1950 positional_args.append(arg)
1952 self.generate_tuple_and_keyword_parsing_code(
1953 positional_args, kw_only_args, end_label, code)
1955 code.error_label = old_error_label
1956 if code.label_used(our_error_label):
1957 if not code.label_used(end_label):
1958 code.put_goto(end_label)
1959 code.put_label(our_error_label)
1960 if has_star_or_kw_args:
1961 self.generate_arg_decref(self.star_arg, code)
1962 if self.starstar_arg:
1963 if self.starstar_arg.entry.xdecref_cleanup:
1964 code.put_var_xdecref(self.starstar_arg.entry)
1966 code.put_var_decref(self.starstar_arg.entry)
1967 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1968 code.putln("return %s;" % self.error_value())
1969 if code.label_used(end_label):
1970 code.put_label(end_label)
1972 def generate_arg_assignment(self, arg, item, code):
1973 if arg.type.is_pyobject:
1975 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1976 code.putln("%s = %s;" % (arg.entry.cname, item))
1978 func = arg.type.from_py_function
1980 code.putln("%s = %s(%s); %s" % (
1984 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1986 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1988 def generate_arg_xdecref(self, arg, code):
1990 code.put_var_xdecref(arg.entry)
1992 def generate_arg_decref(self, arg, code):
1994 code.put_var_decref(arg.entry)
1996 def generate_stararg_copy_code(self, code):
1997 if not self.star_arg:
1998 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1999 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2001 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2002 self.name, Naming.args_cname, self.error_value()))
2005 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2007 if self.starstar_arg:
2009 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2011 kwarg_check = "%s" % Naming.kwds_cname
2013 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2014 Naming.kwds_cname, Naming.kwds_cname)
2016 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2017 kwarg_check, Naming.kwds_cname, self.name,
2018 bool(self.starstar_arg), self.error_value()))
2020 if self.starstar_arg:
2021 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2022 self.starstar_arg.entry.cname,
2025 code.putln("if (unlikely(!%s)) return %s;" % (
2026 self.starstar_arg.entry.cname, self.error_value()))
2027 self.starstar_arg.entry.xdecref_cleanup = 0
2028 code.put_gotref(self.starstar_arg.entry.cname)
2032 code.put_incref(Naming.args_cname, py_object_type)
2033 code.putln("%s = %s;" % (
2034 self.star_arg.entry.cname,
2036 self.star_arg.entry.xdecref_cleanup = 0
2038 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2039 kw_only_args, success_label, code):
2040 argtuple_error_label = code.new_label("argtuple_error")
2042 min_positional_args = self.num_required_args - self.num_required_kw_args
2043 if len(self.args) > 0 and self.args[0].is_self_arg:
2044 min_positional_args -= 1
2045 max_positional_args = len(positional_args)
2046 has_fixed_positional_count = not self.star_arg and \
2047 min_positional_args == max_positional_args
2049 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2050 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2051 if self.num_required_kw_args:
2052 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2054 if self.starstar_arg or self.star_arg:
2055 self.generate_stararg_init_code(max_positional_args, code)
2057 # --- optimised code when we receive keyword arguments
2058 if self.num_required_kw_args:
2059 likely_hint = "likely"
2061 likely_hint = "unlikely"
2062 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2063 self.generate_keyword_unpacking_code(
2064 min_positional_args, max_positional_args,
2065 has_fixed_positional_count,
2066 positional_args, kw_only_args, argtuple_error_label, code)
2068 # --- optimised code when we do not receive any keyword arguments
2069 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2070 # Python raises arg tuple related errors first, so we must
2071 # check the length here
2072 if min_positional_args == max_positional_args and not self.star_arg:
2076 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2077 Naming.args_cname, compare, min_positional_args))
2078 code.put_goto(argtuple_error_label)
2080 if self.num_required_kw_args:
2081 # pure error case: keywords required but not passed
2082 if max_positional_args > min_positional_args and not self.star_arg:
2083 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2084 Naming.args_cname, max_positional_args))
2085 code.put_goto(argtuple_error_label)
2086 code.putln('} else {')
2087 for i, arg in enumerate(kw_only_args):
2089 pystring_cname = code.intern_identifier(arg.name)
2090 # required keyword-only argument missing
2091 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2094 code.putln(code.error_goto(self.pos))
2097 elif min_positional_args == max_positional_args:
2098 # parse the exact number of positional arguments from the
2100 code.putln('} else {')
2101 for i, arg in enumerate(positional_args):
2102 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2103 self.generate_arg_assignment(arg, item, code)
2104 self.generate_arg_default_assignments(code)
2107 # parse the positional arguments from the variable length
2109 code.putln('} else {')
2110 self.generate_arg_default_assignments(code)
2111 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2113 code.putln('default:')
2114 reversed_args = list(enumerate(positional_args))[::-1]
2115 for i, arg in reversed_args:
2116 if i >= min_positional_args-1:
2117 if min_positional_args > 1:
2118 code.putln('case %2d:' % (i+1)) # pure code beautification
2120 code.put('case %2d: ' % (i+1))
2121 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2122 self.generate_arg_assignment(arg, item, code)
2123 if min_positional_args == 0:
2124 code.put('case 0: ')
2125 code.putln('break;')
2127 if min_positional_args:
2128 for i in range(min_positional_args-1, -1, -1):
2129 code.putln('case %2d:' % i)
2130 code.put_goto(argtuple_error_label)
2132 code.put('default: ')
2133 code.put_goto(argtuple_error_label)
2138 if code.label_used(argtuple_error_label):
2139 code.put_goto(success_label)
2140 code.put_label(argtuple_error_label)
2141 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2142 self.name, has_fixed_positional_count,
2143 min_positional_args, max_positional_args,
2145 code.putln(code.error_goto(self.pos))
2147 def generate_arg_default_assignments(self, code):
2148 for arg in self.args:
2149 if arg.is_generic and arg.default:
2153 arg.calculate_default_value_code(code)))
2155 def generate_stararg_init_code(self, max_positional_args, code):
2156 if self.starstar_arg:
2157 self.starstar_arg.entry.xdecref_cleanup = 0
2158 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2159 self.starstar_arg.entry.cname,
2160 self.starstar_arg.entry.cname,
2161 self.error_value()))
2162 code.put_gotref(self.starstar_arg.entry.cname)
2164 self.star_arg.entry.xdecref_cleanup = 0
2165 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2167 max_positional_args))
2168 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2169 self.star_arg.entry.cname, Naming.args_cname,
2170 max_positional_args, Naming.args_cname))
2171 code.put_gotref(self.star_arg.entry.cname)
2172 if self.starstar_arg:
2174 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2175 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2176 code.putln('return %s;' % self.error_value())
2179 code.putln("if (unlikely(!%s)) return %s;" % (
2180 self.star_arg.entry.cname, self.error_value()))
2181 code.putln('} else {')
2182 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2183 code.put_incref(Naming.empty_tuple, py_object_type)
2186 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2187 has_fixed_positional_count, positional_args,
2188 kw_only_args, argtuple_error_label, code):
2189 all_args = tuple(positional_args) + tuple(kw_only_args)
2190 max_args = len(all_args)
2193 for i, arg in enumerate(all_args):
2194 if arg.default and arg.type.is_pyobject:
2195 default_value = arg.calculate_default_value_code(code)
2196 if arg.type is not PyrexTypes.py_object_type:
2197 default_value = "(PyObject*)"+default_value
2198 default_args.append((i, default_value))
2200 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2202 # it looks funny to separate the init-to-0 from setting the
2203 # default value, but C89 needs this
2204 code.putln("PyObject* values[%d] = {%s};" % (
2205 max_args, ','.join(['0']*max_args)))
2206 for i, default_value in default_args:
2207 code.putln('values[%d] = %s;' % (i, default_value))
2209 # parse the tuple and check that it's not too long
2210 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2212 code.putln('default:')
2213 for i in range(max_positional_args-1, -1, -1):
2214 code.put('case %2d: ' % (i+1))
2215 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2216 i, Naming.args_cname, i))
2217 code.putln('case 0: break;')
2218 if not self.star_arg:
2219 code.put('default: ') # more arguments than allowed
2220 code.put_goto(argtuple_error_label)
2223 # now fill up the positional/required arguments with values
2225 if self.num_required_args or max_positional_args > 0:
2226 last_required_arg = -1
2227 for i, arg in enumerate(all_args):
2229 last_required_arg = i
2230 if last_required_arg < max_positional_args:
2231 last_required_arg = max_positional_args-1
2232 num_required_args = self.num_required_args
2233 if max_positional_args > 0:
2234 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2235 for i, arg in enumerate(all_args[:last_required_arg+1]):
2236 if max_positional_args > 0 and i <= max_positional_args:
2237 if self.star_arg and i == max_positional_args:
2238 code.putln('default:')
2240 code.putln('case %2d:' % i)
2241 pystring_cname = code.intern_identifier(arg.name)
2244 # handled separately below
2246 code.putln('if (kw_args > %d) {' % num_required_args)
2247 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2248 Naming.kwds_cname, pystring_cname))
2249 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2252 num_required_args -= 1
2253 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2254 i, Naming.kwds_cname, pystring_cname))
2255 code.putln('if (likely(values[%d])) kw_args--;' % i);
2256 if i < min_positional_args:
2258 # special case: we know arg 0 is missing
2260 code.put_goto(argtuple_error_label)
2262 # print the correct number of values (args or
2263 # kwargs) that were passed into positional
2264 # arguments up to this point
2265 code.putln('else {')
2266 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2267 self.name, has_fixed_positional_count,
2268 min_positional_args, max_positional_args, i))
2269 code.putln(code.error_goto(self.pos))
2272 code.putln('else {')
2273 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2274 self.name, pystring_cname))
2275 code.putln(code.error_goto(self.pos))
2277 if max_positional_args > 0:
2280 if kw_only_args and not self.starstar_arg:
2281 # unpack optional keyword-only arguments
2282 # checking for interned strings in a dict is faster than iterating
2283 # but it's too likely that we must iterate if we expect **kwargs
2285 for i, arg in enumerate(all_args[max_positional_args:]):
2286 if not arg.kw_only or not arg.default:
2288 optional_args.append((i+max_positional_args, arg))
2290 # this mimics an unrolled loop so that we can "break" out of it
2291 code.putln('while (kw_args > 0) {')
2292 code.putln('PyObject* value;')
2293 for i, arg in optional_args:
2294 pystring_cname = code.intern_identifier(arg.name)
2296 'value = PyDict_GetItem(%s, %s);' % (
2297 Naming.kwds_cname, pystring_cname))
2299 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2300 code.putln('break;')
2303 code.putln('if (unlikely(kw_args > 0)) {')
2304 # non-positional/-required kw args left in dict: default args,
2305 # kw-only args, **kwargs or error
2307 # This is sort of a catch-all: except for checking required
2308 # arguments, this will always do the right thing for unpacking
2309 # keyword arguments, so that we can concentrate on optimising
2310 # common cases above.
2311 if max_positional_args == 0:
2314 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2315 Naming.args_cname, max_positional_args,
2316 Naming.args_cname, max_positional_args))
2317 pos_arg_count = "used_pos_args"
2319 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2320 code.globalstate.use_utility_code(parse_keywords_utility_code)
2322 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2324 Naming.pykwdlist_cname,
2325 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2328 code.putln(code.error_goto(self.pos))
2331 # convert arg values to their final type and assign them
2332 for i, arg in enumerate(all_args):
2333 if arg.default and not arg.type.is_pyobject:
2334 code.putln("if (values[%d]) {" % i)
2335 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2336 if arg.default and not arg.type.is_pyobject:
2337 code.putln('} else {')
2341 arg.calculate_default_value_code(code)))
2344 def generate_argument_conversion_code(self, code):
2345 # Generate code to convert arguments from
2346 # signature type to declared type, if needed.
2347 for arg in self.args:
2348 if arg.needs_conversion:
2349 self.generate_arg_conversion(arg, code)
2351 def generate_arg_conversion(self, arg, code):
2352 # Generate conversion code for one argument.
2353 old_type = arg.hdr_type
2355 if old_type.is_pyobject:
2357 code.putln("if (%s) {" % arg.hdr_cname)
2359 code.putln("assert(%s); {" % arg.hdr_cname)
2360 self.generate_arg_conversion_from_pyobject(arg, code)
2362 elif new_type.is_pyobject:
2363 self.generate_arg_conversion_to_pyobject(arg, code)
2365 if new_type.assignable_from(old_type):
2367 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2370 "Cannot convert 1 argument from '%s' to '%s'" %
2371 (old_type, new_type))
2373 def generate_arg_conversion_from_pyobject(self, arg, code):
2375 func = new_type.from_py_function
2376 # copied from CoerceFromPyTypeNode
2378 code.putln("%s = %s(%s); %s" % (
2382 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2385 "Cannot convert Python object argument to type '%s'"
2388 def generate_arg_conversion_to_pyobject(self, arg, code):
2389 old_type = arg.hdr_type
2390 func = old_type.to_py_function
2392 code.putln("%s = %s(%s); %s" % (
2396 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2397 code.put_var_gotref(arg.entry)
2400 "Cannot convert argument of type '%s' to Python object"
2403 def generate_argument_type_tests(self, code):
2404 # Generate type tests for args whose signature
2405 # type is PyObject * and whose declared type is
2406 # a subtype thereof.
2407 for arg in self.args:
2408 if arg.needs_type_test:
2409 self.generate_arg_type_test(arg, code)
2411 def generate_arg_type_test(self, arg, code):
2412 # Generate type test for one argument.
2413 if arg.type.typeobj_is_available():
2414 typeptr_cname = arg.type.typeptr_cname
2415 arg_code = "((PyObject *)%s)" % arg.entry.cname
2417 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2422 arg.type.is_builtin_type,
2423 code.error_goto(arg.pos)))
2425 error(arg.pos, "Cannot test type of extern C class "
2426 "without type object name specification")
2428 def error_value(self):
2429 return self.entry.signature.error_value
2431 def caller_will_check_exceptions(self):
2434 class OverrideCheckNode(StatNode):
2435 # A Node for dispatching to the def method if it
2444 child_attrs = ['body']
2448 def analyse_expressions(self, env):
2449 self.args = env.arg_entries
2450 if self.py_func.is_module_scope:
2455 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2456 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2457 call_node = ExprNodes.SimpleCallNode(self.pos,
2458 function=self.func_node,
2459 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2460 self.body = ReturnStatNode(self.pos, value=call_node)
2461 self.body.analyse_expressions(env)
2463 def generate_execution_code(self, code):
2464 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2465 # Check to see if we are an extension type
2466 if self.py_func.is_module_scope:
2467 self_arg = "((PyObject *)%s)" % Naming.module_cname
2469 self_arg = "((PyObject *)%s)" % self.args[0].cname
2470 code.putln("/* Check if called by wrapper */")
2471 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2472 code.putln("/* Check if overriden in Python */")
2473 if self.py_func.is_module_scope:
2474 code.putln("else {")
2476 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2477 self.func_node.allocate(code)
2478 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2479 # need to get attribute manually--scope would return cdef method
2480 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2481 self.func_node.result(), self_arg, interned_attr_cname, err))
2482 code.put_gotref(self.func_node.py_result())
2483 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2484 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2485 self.func_node.result(), self.py_func.entry.func_cname)
2486 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2487 self.body.generate_execution_code(code)
2489 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2491 self.func_node.release(code)
2493 class ClassDefNode(StatNode, BlockNode):
2496 class PyClassDefNode(ClassDefNode):
2497 # A Python class definition.
2499 # name EncodedString Name of the class
2500 # doc string or None
2501 # body StatNode Attribute definition code
2502 # entry Symtab.Entry
2503 # scope PyClassScope
2504 # decorators [DecoratorNode] list of decorators or None
2506 # The following subnodes are constructed internally:
2508 # dict DictNode Class dictionary
2509 # classobj ClassNode Class object
2510 # target NameNode Variable to assign class object to
2512 child_attrs = ["body", "dict", "classobj", "target"]
2515 def __init__(self, pos, name, bases, doc, body, decorators = None):
2516 StatNode.__init__(self, pos)
2520 self.decorators = decorators
2522 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2523 if self.doc and Options.docstrings:
2524 doc = embed_position(self.pos, self.doc)
2525 doc_node = ExprNodes.StringNode(pos, value = doc)
2528 self.classobj = ExprNodes.ClassNode(pos, name = name,
2529 bases = bases, dict = self.dict, doc = doc_node)
2530 self.target = ExprNodes.NameNode(pos, name = name)
2532 def as_cclass(self):
2534 Return this node as if it were declared as an extension class
2536 bases = self.classobj.bases.args
2538 base_class_name = None
2539 base_class_module = None
2540 elif len(bases) == 1:
2543 from ExprNodes import AttributeNode, NameNode
2544 while isinstance(base, AttributeNode):
2545 path.insert(0, base.attribute)
2547 if isinstance(base, NameNode):
2548 path.insert(0, base.name)
2549 base_class_name = path[-1]
2551 base_class_module = u'.'.join(path[:-1])
2553 base_class_module = None
2555 error(self.classobj.bases.args.pos, "Invalid base class")
2557 error(self.classobj.bases.args.pos, "C class may only have one base class")
2560 return CClassDefNode(self.pos,
2561 visibility = 'private',
2563 class_name = self.name,
2564 base_class_module = base_class_module,
2565 base_class_name = base_class_name,
2566 decorators = self.decorators,
2571 def create_scope(self, env):
2573 while env.is_py_class_scope or env.is_c_class_scope:
2574 env = env.outer_scope
2575 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2578 def analyse_declarations(self, env):
2579 self.target.analyse_target_declaration(env)
2580 cenv = self.create_scope(env)
2581 cenv.directives = env.directives
2582 cenv.class_obj_cname = self.target.entry.cname
2583 self.body.analyse_declarations(cenv)
2585 def analyse_expressions(self, env):
2586 self.dict.analyse_expressions(env)
2587 self.classobj.analyse_expressions(env)
2588 genv = env.global_scope()
2590 self.body.analyse_expressions(cenv)
2591 self.target.analyse_target_expression(env, self.classobj)
2593 def generate_function_definitions(self, env, code):
2594 self.body.generate_function_definitions(self.scope, code)
2596 def generate_execution_code(self, code):
2597 code.pyclass_stack.append(self)
2599 self.dict.generate_evaluation_code(code)
2600 self.classobj.generate_evaluation_code(code)
2601 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2602 self.body.generate_execution_code(code)
2603 self.target.generate_assignment_code(self.classobj, code)
2604 self.dict.generate_disposal_code(code)
2605 self.dict.free_temps(code)
2606 code.pyclass_stack.pop()
2609 class CClassDefNode(ClassDefNode):
2610 # An extension type definition.
2612 # visibility 'private' or 'public' or 'extern'
2613 # typedef_flag boolean
2615 # module_name string or None For import of extern type objects
2616 # class_name string Unqualified name of class
2617 # as_name string or None Name to declare as in this scope
2618 # base_class_module string or None Module containing the base class
2619 # base_class_name string or None Name of the base class
2620 # objstruct_name string or None Specified C name of object struct
2621 # typeobj_name string or None Specified C name of type object
2622 # in_pxd boolean Is in a .pxd file
2623 # decorators [DecoratorNode] list of decorators or None
2624 # doc string or None
2625 # body StatNode or None
2626 # entry Symtab.Entry
2627 # base_type PyExtensionType or None
2628 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2629 # buffer_defaults_pos
2631 child_attrs = ["body"]
2632 buffer_defaults_node = None
2633 buffer_defaults_pos = None
2634 typedef_flag = False
2636 objstruct_name = None
2640 def analyse_declarations(self, env):
2641 #print "CClassDefNode.analyse_declarations:", self.class_name
2642 #print "...visibility =", self.visibility
2643 #print "...module_name =", self.module_name
2646 if self.buffer_defaults_node:
2647 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2648 env, [], self.buffer_defaults_node,
2649 need_complete=False)
2651 buffer_defaults = None
2653 if env.in_cinclude and not self.objstruct_name:
2654 error(self.pos, "Object struct name specification required for "
2655 "C class defined in 'extern from' block")
2656 self.base_type = None
2657 # Now that module imports are cached, we need to
2658 # import the modules for extern classes.
2659 if self.module_name:
2661 for module in env.cimported_modules:
2662 if module.name == self.module_name:
2663 self.module = module
2664 if self.module is None:
2665 self.module = ModuleScope(self.module_name, None, env.context)
2666 self.module.has_extern_class = 1
2667 env.add_imported_module(self.module)
2669 if self.base_class_name:
2670 if self.base_class_module:
2671 base_class_scope = env.find_module(self.base_class_module, self.pos)
2673 base_class_scope = env
2674 if self.base_class_name == 'object':
2675 # extension classes are special and don't need to inherit from object
2676 if base_class_scope is None or base_class_scope.lookup('object') is None:
2677 self.base_class_name = None
2678 self.base_class_module = None
2679 base_class_scope = None
2680 if base_class_scope:
2681 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2682 if base_class_entry:
2683 if not base_class_entry.is_type:
2684 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2685 elif not base_class_entry.type.is_extension_type:
2686 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2687 elif not base_class_entry.type.is_complete():
2688 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2690 self.base_type = base_class_entry.type
2691 has_body = self.body is not None
2692 if self.module_name and self.visibility != 'extern':
2693 module_path = self.module_name.split(".")
2694 home_scope = env.find_imported_module(module_path, self.pos)
2700 if self.visibility == 'extern':
2701 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2702 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2704 self.entry = home_scope.declare_c_class(
2705 name = self.class_name,
2707 defining = has_body and self.in_pxd,
2708 implementing = has_body and not self.in_pxd,
2709 module_name = self.module_name,
2710 base_type = self.base_type,
2711 objstruct_cname = self.objstruct_name,
2712 typeobj_cname = self.typeobj_name,
2713 visibility = self.visibility,
2714 typedef_flag = self.typedef_flag,
2716 buffer_defaults = buffer_defaults)
2717 if home_scope is not env and self.visibility == 'extern':
2718 env.add_imported_entry(self.class_name, self.entry, pos)
2719 scope = self.entry.type.scope
2720 if scope is not None:
2721 scope.directives = env.directives
2723 if self.doc and Options.docstrings:
2724 scope.doc = embed_position(self.pos, self.doc)
2727 self.body.analyse_declarations(scope)
2731 scope.implemented = 1
2732 env.allocate_vtable_names(self.entry)
2734 def analyse_expressions(self, env):
2736 scope = self.entry.type.scope
2737 self.body.analyse_expressions(scope)
2739 def generate_function_definitions(self, env, code):
2741 self.body.generate_function_definitions(
2742 self.entry.type.scope, code)
2744 def generate_execution_code(self, code):
2745 # This is needed to generate evaluation code for
2746 # default values of method arguments.
2748 self.body.generate_execution_code(code)
2750 def annotate(self, code):
2752 self.body.annotate(code)
2755 class PropertyNode(StatNode):
2756 # Definition of a property in an extension type.
2759 # doc EncodedString or None Doc string
2762 child_attrs = ["body"]
2764 def analyse_declarations(self, env):
2765 entry = env.declare_property(self.name, self.doc, self.pos)
2767 entry.scope.directives = env.directives
2768 self.body.analyse_declarations(entry.scope)
2770 def analyse_expressions(self, env):
2771 self.body.analyse_expressions(env)
2773 def generate_function_definitions(self, env, code):
2774 self.body.generate_function_definitions(env, code)
2776 def generate_execution_code(self, code):
2779 def annotate(self, code):
2780 self.body.annotate(code)
2783 class GlobalNode(StatNode):
2784 # Global variable declaration.
2790 def analyse_declarations(self, env):
2791 for name in self.names:
2792 env.declare_global(name, self.pos)
2794 def analyse_expressions(self, env):
2797 def generate_execution_code(self, code):
2801 class ExprStatNode(StatNode):
2802 # Expression used as a statement.
2806 child_attrs = ["expr"]
2808 def analyse_declarations(self, env):
2810 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2811 func = self.expr.function.as_cython_attribute()
2812 if func == u'declare':
2813 args, kwds = self.expr.explicit_args_kwds()
2815 error(self.expr.pos, "Variable names must be specified.")
2816 for var, type_node in kwds.key_value_pairs:
2817 type = type_node.analyse_as_type(env)
2819 error(type_node.pos, "Unknown type")
2821 env.declare_var(var.value, type, var.pos, is_cdef = True)
2822 self.__class__ = PassStatNode
2824 def analyse_expressions(self, env):
2825 self.expr.analyse_expressions(env)
2827 def generate_execution_code(self, code):
2828 self.expr.generate_evaluation_code(code)
2829 if not self.expr.is_temp and self.expr.result():
2830 code.putln("%s;" % self.expr.result())
2831 self.expr.generate_disposal_code(code)
2832 self.expr.free_temps(code)
2834 def annotate(self, code):
2835 self.expr.annotate(code)
2838 class AssignmentNode(StatNode):
2839 # Abstract base class for assignment nodes.
2841 # The analyse_expressions and generate_execution_code
2842 # phases of assignments are split into two sub-phases
2843 # each, to enable all the right hand sides of a
2844 # parallel assignment to be evaluated before assigning
2845 # to any of the left hand sides.
2847 def analyse_expressions(self, env):
2848 self.analyse_types(env)
2850 # def analyse_expressions(self, env):
2851 # self.analyse_expressions_1(env)
2852 # self.analyse_expressions_2(env)
2854 def generate_execution_code(self, code):
2855 self.generate_rhs_evaluation_code(code)
2856 self.generate_assignment_code(code)
2859 class SingleAssignmentNode(AssignmentNode):
2860 # The simplest case:
2864 # lhs ExprNode Left hand side
2865 # rhs ExprNode Right hand side
2866 # first bool Is this guaranteed the first assignment to lhs?
2868 child_attrs = ["lhs", "rhs"]
2870 declaration_only = False
2872 def analyse_declarations(self, env):
2875 # handle declarations of the form x = cython.foo()
2876 if isinstance(self.rhs, ExprNodes.CallNode):
2877 func_name = self.rhs.function.as_cython_attribute()
2879 args, kwds = self.rhs.explicit_args_kwds()
2881 if func_name in ['declare', 'typedef']:
2882 if len(args) > 2 or kwds is not None:
2883 error(rhs.pos, "Can only declare one type at a time.")
2885 type = args[0].analyse_as_type(env)
2887 error(args[0].pos, "Unknown type")
2890 if func_name == 'declare':
2891 if isinstance(lhs, ExprNodes.NameNode):
2892 vars = [(lhs.name, lhs.pos)]
2893 elif isinstance(lhs, ExprNodes.TupleNode):
2894 vars = [(var.name, var.pos) for var in lhs.args]
2896 error(lhs.pos, "Invalid declaration")
2898 for var, pos in vars:
2899 env.declare_var(var, type, pos, is_cdef = True)
2904 self.declaration_only = True
2906 self.declaration_only = True
2907 if not isinstance(lhs, ExprNodes.NameNode):
2908 error(lhs.pos, "Invalid declaration.")
2909 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2911 elif func_name in ['struct', 'union']:
2912 self.declaration_only = True
2913 if len(args) > 0 or kwds is None:
2914 error(rhs.pos, "Struct or union members must be given by name.")
2917 for member, type_node in kwds.key_value_pairs:
2918 type = type_node.analyse_as_type(env)
2920 error(type_node.pos, "Unknown type")
2922 members.append((member.value, type, member.pos))
2923 if len(members) < len(kwds.key_value_pairs):
2925 if not isinstance(self.lhs, ExprNodes.NameNode):
2926 error(self.lhs.pos, "Invalid declaration.")
2927 name = self.lhs.name
2928 scope = StructOrUnionScope(name)
2929 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2930 for member, type, pos in members:
2931 scope.declare_var(member, type, pos)
2933 if self.declaration_only:
2936 self.lhs.analyse_target_declaration(env)
2938 def analyse_types(self, env, use_temp = 0):
2939 self.rhs.analyse_types(env)
2940 self.lhs.analyse_target_types(env)
2941 self.lhs.gil_assignment_check(env)
2942 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2944 self.rhs = self.rhs.coerce_to_temp(env)
2946 def generate_rhs_evaluation_code(self, code):
2947 self.rhs.generate_evaluation_code(code)
2949 def generate_assignment_code(self, code):
2950 self.lhs.generate_assignment_code(self.rhs, code)
2952 def annotate(self, code):
2953 self.lhs.annotate(code)
2954 self.rhs.annotate(code)
2957 class CascadedAssignmentNode(AssignmentNode):
2958 # An assignment with multiple left hand sides:
2962 # lhs_list [ExprNode] Left hand sides
2963 # rhs ExprNode Right hand sides
2967 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2969 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2970 coerced_rhs_list = None
2972 def analyse_declarations(self, env):
2973 for lhs in self.lhs_list:
2974 lhs.analyse_target_declaration(env)
2976 def analyse_types(self, env, use_temp = 0):
2977 self.rhs.analyse_types(env)
2979 self.rhs = self.rhs.coerce_to_temp(env)
2981 self.rhs = self.rhs.coerce_to_simple(env)
2982 from ExprNodes import CloneNode
2983 self.coerced_rhs_list = []
2984 for lhs in self.lhs_list:
2985 lhs.analyse_target_types(env)
2986 lhs.gil_assignment_check(env)
2987 rhs = CloneNode(self.rhs)
2988 rhs = rhs.coerce_to(lhs.type, env)
2989 self.coerced_rhs_list.append(rhs)
2991 def generate_rhs_evaluation_code(self, code):
2992 self.rhs.generate_evaluation_code(code)
2994 def generate_assignment_code(self, code):
2995 for i in range(len(self.lhs_list)):
2996 lhs = self.lhs_list[i]
2997 rhs = self.coerced_rhs_list[i]
2998 rhs.generate_evaluation_code(code)
2999 lhs.generate_assignment_code(rhs, code)
3000 # Assignment has disposed of the cloned RHS
3001 self.rhs.generate_disposal_code(code)
3002 self.rhs.free_temps(code)
3004 def annotate(self, code):
3005 for i in range(len(self.lhs_list)):
3006 lhs = self.lhs_list[i].annotate(code)
3007 rhs = self.coerced_rhs_list[i].annotate(code)
3008 self.rhs.annotate(code)
3011 class ParallelAssignmentNode(AssignmentNode):
3012 # A combined packing/unpacking assignment:
3016 # This has been rearranged by the parser into
3018 # a = d ; b = e ; c = f
3020 # but we must evaluate all the right hand sides
3021 # before assigning to any of the left hand sides.
3023 # stats [AssignmentNode] The constituent assignments
3025 child_attrs = ["stats"]
3027 def analyse_declarations(self, env):
3028 for stat in self.stats:
3029 stat.analyse_declarations(env)
3031 def analyse_expressions(self, env):
3032 for stat in self.stats:
3033 stat.analyse_types(env, use_temp = 1)
3035 # def analyse_expressions(self, env):
3036 # for stat in self.stats:
3037 # stat.analyse_expressions_1(env, use_temp = 1)
3038 # for stat in self.stats:
3039 # stat.analyse_expressions_2(env)
3041 def generate_execution_code(self, code):
3042 for stat in self.stats:
3043 stat.generate_rhs_evaluation_code(code)
3044 for stat in self.stats:
3045 stat.generate_assignment_code(code)
3047 def annotate(self, code):
3048 for stat in self.stats:
3052 class InPlaceAssignmentNode(AssignmentNode):
3053 # An in place arithmatic operand:
3059 # lhs ExprNode Left hand side
3060 # rhs ExprNode Right hand side
3061 # op char one of "+-*/%^&|"
3062 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3064 # This code is a bit tricky because in order to obey Python
3065 # semantics the sub-expressions (e.g. indices) of the lhs must
3066 # not be evaluated twice. So we must re-use the values calculated
3067 # in evaluation phase for the assignment phase as well.
3068 # Fortunately, the type of the lhs node is fairly constrained
3069 # (it must be a NameNode, AttributeNode, or IndexNode).
3071 child_attrs = ["lhs", "rhs"]
3074 def analyse_declarations(self, env):
3075 self.lhs.analyse_target_declaration(env)
3077 def analyse_types(self, env):
3078 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3079 self.rhs.analyse_types(env)
3080 self.lhs.analyse_target_types(env)
3081 if Options.incref_local_binop and self.dup.type.is_pyobject:
3082 self.dup = self.dup.coerce_to_temp(env)
3084 if self.lhs.type.is_pyobject:
3085 self.rhs = self.rhs.coerce_to_pyobject(env)
3086 elif self.rhs.type.is_pyobject:
3087 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3088 if self.lhs.type.is_pyobject:
3089 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3090 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3092 def generate_execution_code(self, code):
3094 self.rhs.generate_evaluation_code(code)
3095 self.dup.generate_subexpr_evaluation_code(code)
3096 if self.dup.is_temp:
3097 self.dup.allocate_temp_result(code)
3098 # self.dup.generate_result_code is run only if it is not buffer access
3099 if self.operator == "**":
3103 if self.lhs.type.is_pyobject:
3104 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3105 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3106 self.dup.generate_result_code(code)
3107 self.result_value_temp.allocate(code)
3109 "%s = %s(%s, %s%s); %s" % (
3110 self.result_value.result(),
3111 self.py_operation_function(),
3112 self.dup.py_result(),
3113 self.rhs.py_result(),
3115 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3116 code.put_gotref(self.result_value.py_result())
3117 self.result_value.generate_evaluation_code(code) # May be a type check...
3118 self.rhs.generate_disposal_code(code)
3119 self.rhs.free_temps(code)
3120 self.dup.generate_disposal_code(code)
3121 self.dup.free_temps(code)
3122 self.lhs.generate_assignment_code(self.result_value, code)
3123 self.result_value_temp.release(code)
3125 c_op = self.operator
3129 error(self.pos, "No C inplace power operator")
3130 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3131 error(self.pos, "Inplace operators not implemented for complex types.")
3133 # have to do assignment directly to avoid side-effects
3134 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3135 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3137 self.dup.generate_result_code(code)
3138 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3139 self.rhs.generate_disposal_code(code)
3140 self.rhs.free_temps(code)
3141 if self.dup.is_temp:
3142 self.dup.generate_subexpr_disposal_code(code)
3143 self.dup.free_subexpr_temps(code)
3145 def create_dup_node(self, env):
3148 self.dup.analyse_types(env)
3149 if isinstance(self.lhs, ExprNodes.NameNode):
3150 target_lhs = ExprNodes.NameNode(self.dup.pos,
3151 name = self.dup.name,
3152 is_temp = self.dup.is_temp,
3153 entry = self.dup.entry)
3154 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3155 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3156 obj = ExprNodes.CloneNode(self.lhs.obj),
3157 attribute = self.dup.attribute,
3158 is_temp = self.dup.is_temp)
3159 elif isinstance(self.lhs, ExprNodes.IndexNode):
3161 index = ExprNodes.CloneNode(self.lhs.index)
3164 if self.lhs.indices:
3165 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3168 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3169 base = ExprNodes.CloneNode(self.dup.base),
3172 is_temp = self.dup.is_temp)
3175 self.lhs = target_lhs
3178 def py_operation_function(self):
3179 return self.py_functions[self.operator]
3182 "|": "PyNumber_InPlaceOr",
3183 "^": "PyNumber_InPlaceXor",
3184 "&": "PyNumber_InPlaceAnd",
3185 "+": "PyNumber_InPlaceAdd",
3186 "-": "PyNumber_InPlaceSubtract",
3187 "*": "PyNumber_InPlaceMultiply",
3188 "/": "PyNumber_InPlaceDivide",
3189 "%": "PyNumber_InPlaceRemainder",
3190 "<<": "PyNumber_InPlaceLshift",
3191 ">>": "PyNumber_InPlaceRshift",
3192 "**": "PyNumber_InPlacePower",
3193 "//": "PyNumber_InPlaceFloorDivide",
3196 def annotate(self, code):
3197 self.lhs.annotate(code)
3198 self.rhs.annotate(code)
3199 self.dup.annotate(code)
3202 class PrintStatNode(StatNode):
3205 # arg_tuple TupleNode
3206 # append_newline boolean
3208 child_attrs = ["arg_tuple"]
3210 def analyse_expressions(self, env):
3211 self.arg_tuple.analyse_expressions(env)
3212 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3213 env.use_utility_code(printing_utility_code)
3214 if len(self.arg_tuple.args) == 1 and self.append_newline:
3215 env.use_utility_code(printing_one_utility_code)
3217 nogil_check = Node.gil_error
3218 gil_message = "Python print statement"
3220 def generate_execution_code(self, code):
3221 if len(self.arg_tuple.args) == 1 and self.append_newline:
3222 arg = self.arg_tuple.args[0]
3223 arg.generate_evaluation_code(code)
3226 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3228 code.error_goto(self.pos)))
3229 arg.generate_disposal_code(code)
3230 arg.free_temps(code)
3232 self.arg_tuple.generate_evaluation_code(code)
3234 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3235 self.arg_tuple.py_result(),
3236 self.append_newline,
3237 code.error_goto(self.pos)))
3238 self.arg_tuple.generate_disposal_code(code)
3239 self.arg_tuple.free_temps(code)
3241 def annotate(self, code):
3242 self.arg_tuple.annotate(code)
3245 class ExecStatNode(StatNode):
3250 child_attrs = ["args"]
3252 def analyse_expressions(self, env):
3253 for i, arg in enumerate(self.args):
3254 arg.analyse_expressions(env)
3255 arg = arg.coerce_to_pyobject(env)
3257 env.use_utility_code(Builtin.pyexec_utility_code)
3259 nogil_check = Node.gil_error
3260 gil_message = "Python exec statement"
3262 def generate_execution_code(self, code):
3264 for arg in self.args:
3265 arg.generate_evaluation_code(code)
3266 args.append( arg.py_result() )
3267 args = tuple(args + ['0', '0'][:3-len(args)])
3268 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3269 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3270 (temp_result,) + args))
3271 for arg in self.args:
3272 arg.generate_disposal_code(code)
3273 arg.free_temps(code)
3275 code.error_goto_if_null(temp_result, self.pos))
3276 code.put_gotref(temp_result)
3277 code.put_decref_clear(temp_result, py_object_type)
3278 code.funcstate.release_temp(temp_result)
3280 def annotate(self, code):
3281 for arg in self.args:
3285 class DelStatNode(StatNode):
3290 child_attrs = ["args"]
3292 def analyse_declarations(self, env):
3293 for arg in self.args:
3294 arg.analyse_target_declaration(env)
3296 def analyse_expressions(self, env):
3297 for arg in self.args:
3298 arg.analyse_target_expression(env, None)
3299 if not arg.type.is_pyobject:
3300 error(arg.pos, "Deletion of non-Python object")
3301 #arg.release_target_temp(env)
3303 def nogil_check(self, env):
3304 for arg in self.args:
3305 if arg.type.is_pyobject:
3308 gil_message = "Deleting Python object"
3310 def generate_execution_code(self, code):
3311 for arg in self.args:
3312 if arg.type.is_pyobject:
3313 arg.generate_deletion_code(code)
3314 # else error reported earlier
3316 def annotate(self, code):
3317 for arg in self.args:
3321 class PassStatNode(StatNode):
3326 def analyse_expressions(self, env):
3329 def generate_execution_code(self, code):
3333 class BreakStatNode(StatNode):
3337 def analyse_expressions(self, env):
3340 def generate_execution_code(self, code):
3341 if not code.break_label:
3342 error(self.pos, "break statement not inside loop")
3344 code.put_goto(code.break_label)
3347 class ContinueStatNode(StatNode):
3351 def analyse_expressions(self, env):
3354 def generate_execution_code(self, code):
3355 if code.funcstate.in_try_finally:
3356 error(self.pos, "continue statement inside try of try...finally")
3357 elif not code.continue_label:
3358 error(self.pos, "continue statement not inside loop")
3360 code.put_goto(code.continue_label)
3363 class ReturnStatNode(StatNode):
3366 # value ExprNode or None
3367 # return_type PyrexType
3369 child_attrs = ["value"]
3371 def analyse_expressions(self, env):
3372 return_type = env.return_type
3373 self.return_type = return_type
3375 error(self.pos, "Return not inside a function body")
3378 self.value.analyse_types(env)
3379 if return_type.is_void or return_type.is_returncode:
3380 error(self.value.pos,
3381 "Return with value in void function")
3383 self.value = self.value.coerce_to(env.return_type, env)
3385 if (not return_type.is_void
3386 and not return_type.is_pyobject
3387 and not return_type.is_returncode):
3388 error(self.pos, "Return value required")
3390 def nogil_check(self, env):
3391 if self.return_type.is_pyobject:
3394 gil_message = "Returning Python object"
3396 def generate_execution_code(self, code):
3397 code.mark_pos(self.pos)
3398 if not self.return_type:
3399 # error reported earlier
3401 if self.return_type.is_pyobject:
3402 code.put_xdecref(Naming.retval_cname,
3405 self.value.generate_evaluation_code(code)
3406 self.value.make_owned_reference(code)
3409 Naming.retval_cname,
3410 self.value.result_as(self.return_type)))
3411 self.value.generate_post_assignment_code(code)
3412 self.value.free_temps(code)
3414 if self.return_type.is_pyobject:
3415 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3416 elif self.return_type.is_returncode:
3419 Naming.retval_cname,
3420 self.return_type.default_value))
3421 for cname, type in code.funcstate.temps_holding_reference():
3422 code.put_decref_clear(cname, type)
3423 code.put_goto(code.return_label)
3425 def annotate(self, code):
3427 self.value.annotate(code)
3430 class RaiseStatNode(StatNode):
3433 # exc_type ExprNode or None
3434 # exc_value ExprNode or None
3435 # exc_tb ExprNode or None
3437 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3439 def analyse_expressions(self, env):
3441 self.exc_type.analyse_types(env)
3442 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3444 self.exc_value.analyse_types(env)
3445 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3447 self.exc_tb.analyse_types(env)
3448 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3449 env.use_utility_code(raise_utility_code)
3450 env.use_utility_code(restore_exception_utility_code)
3452 nogil_check = Node.gil_error
3453 gil_message = "Raising exception"
3455 def generate_execution_code(self, code):
3457 self.exc_type.generate_evaluation_code(code)
3458 type_code = self.exc_type.py_result()
3462 self.exc_value.generate_evaluation_code(code)
3463 value_code = self.exc_value.py_result()
3467 self.exc_tb.generate_evaluation_code(code)
3468 tb_code = self.exc_tb.py_result()
3471 if self.exc_type or self.exc_value or self.exc_tb:
3473 "__Pyx_Raise(%s, %s, %s);" % (
3480 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3482 obj.generate_disposal_code(code)
3483 obj.free_temps(code)
3485 code.error_goto(self.pos))
3487 def annotate(self, code):
3489 self.exc_type.annotate(code)
3491 self.exc_value.annotate(code)
3493 self.exc_tb.annotate(code)
3496 class ReraiseStatNode(StatNode):
3500 def analyse_expressions(self, env):
3501 env.use_utility_code(raise_utility_code)
3502 env.use_utility_code(restore_exception_utility_code)
3504 nogil_check = Node.gil_error
3505 gil_message = "Raising exception"
3507 def generate_execution_code(self, code):
3508 vars = code.funcstate.exc_vars
3510 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3511 code.putln(code.error_goto(self.pos))
3513 error(self.pos, "Reraise not inside except clause")
3516 class AssertStatNode(StatNode):
3520 # value ExprNode or None
3522 child_attrs = ["cond", "value"]
3524 def analyse_expressions(self, env):
3525 self.cond = self.cond.analyse_boolean_expression(env)
3527 self.value.analyse_types(env)
3528 self.value = self.value.coerce_to_pyobject(env)
3530 nogil_check = Node.gil_error
3531 gil_message = "Raising exception"
3533 def generate_execution_code(self, code):
3534 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3535 self.cond.generate_evaluation_code(code)
3537 "if (unlikely(!%s)) {" %
3540 self.value.generate_evaluation_code(code)
3542 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3543 self.value.py_result())
3544 self.value.generate_disposal_code(code)
3545 self.value.free_temps(code)
3548 "PyErr_SetNone(PyExc_AssertionError);")
3550 code.error_goto(self.pos))
3553 self.cond.generate_disposal_code(code)
3554 self.cond.free_temps(code)
3555 code.putln("#endif")
3557 def annotate(self, code):
3558 self.cond.annotate(code)
3560 self.value.annotate(code)
3563 class IfStatNode(StatNode):
3566 # if_clauses [IfClauseNode]
3567 # else_clause StatNode or None
3569 child_attrs = ["if_clauses", "else_clause"]
3571 def analyse_control_flow(self, env):
3572 env.start_branching(self.pos)
3573 for if_clause in self.if_clauses:
3574 if_clause.analyse_control_flow(env)
3575 env.next_branch(if_clause.end_pos())
3576 if self.else_clause:
3577 self.else_clause.analyse_control_flow(env)
3578 env.finish_branching(self.end_pos())
3580 def analyse_declarations(self, env):
3581 for if_clause in self.if_clauses:
3582 if_clause.analyse_declarations(env)
3583 if self.else_clause:
3584 self.else_clause.analyse_declarations(env)
3586 def analyse_expressions(self, env):
3587 for if_clause in self.if_clauses:
3588 if_clause.analyse_expressions(env)
3589 if self.else_clause:
3590 self.else_clause.analyse_expressions(env)
3592 def generate_execution_code(self, code):
3593 code.mark_pos(self.pos)
3594 end_label = code.new_label()
3595 for if_clause in self.if_clauses:
3596 if_clause.generate_execution_code(code, end_label)
3597 if self.else_clause:
3598 code.putln("/*else*/ {")
3599 self.else_clause.generate_execution_code(code)
3601 code.put_label(end_label)
3603 def annotate(self, code):
3604 for if_clause in self.if_clauses:
3605 if_clause.annotate(code)
3606 if self.else_clause:
3607 self.else_clause.annotate(code)
3610 class IfClauseNode(Node):
3611 # if or elif clause in an if statement
3613 # condition ExprNode
3616 child_attrs = ["condition", "body"]
3618 def analyse_control_flow(self, env):
3619 self.body.analyse_control_flow(env)
3621 def analyse_declarations(self, env):
3622 self.condition.analyse_declarations(env)
3623 self.body.analyse_declarations(env)
3625 def analyse_expressions(self, env):
3627 self.condition.analyse_temp_boolean_expression(env)
3628 self.body.analyse_expressions(env)
3630 def generate_execution_code(self, code, end_label):
3631 self.condition.generate_evaluation_code(code)
3634 self.condition.result())
3635 self.condition.generate_disposal_code(code)
3636 self.condition.free_temps(code)
3637 self.body.generate_execution_code(code)
3641 code.put_goto(end_label)
3644 def annotate(self, code):
3645 self.condition.annotate(code)
3646 self.body.annotate(code)
3649 class SwitchCaseNode(StatNode):
3650 # Generated in the optimization of an if-elif-else node
3652 # conditions [ExprNode]
3655 child_attrs = ['conditions', 'body']
3657 def generate_execution_code(self, code):
3658 for cond in self.conditions:
3659 code.mark_pos(cond.pos)
3660 cond.generate_evaluation_code(code)
3661 code.putln("case %s:" % cond.result())
3662 self.body.generate_execution_code(code)
3663 code.putln("break;")
3665 def annotate(self, code):
3666 for cond in self.conditions:
3668 self.body.annotate(code)
3670 class SwitchStatNode(StatNode):
3671 # Generated in the optimization of an if-elif-else node
3674 # cases [SwitchCaseNode]
3675 # else_clause StatNode or None
3677 child_attrs = ['test', 'cases', 'else_clause']
3679 def generate_execution_code(self, code):
3680 code.putln("switch (%s) {" % self.test.result())
3681 for case in self.cases:
3682 case.generate_execution_code(code)
3683 if self.else_clause is not None:
3684 code.putln("default:")
3685 self.else_clause.generate_execution_code(code)
3686 code.putln("break;")
3689 def annotate(self, code):
3690 self.test.annotate(code)
3691 for case in self.cases:
3693 if self.else_clause is not None:
3694 self.else_clause.annotate(code)
3696 class LoopNode(object):
3698 def analyse_control_flow(self, env):
3699 env.start_branching(self.pos)
3700 self.body.analyse_control_flow(env)
3701 env.next_branch(self.body.end_pos())
3702 if self.else_clause:
3703 self.else_clause.analyse_control_flow(env)
3704 env.finish_branching(self.end_pos())
3707 class WhileStatNode(LoopNode, StatNode):
3710 # condition ExprNode
3712 # else_clause StatNode
3714 child_attrs = ["condition", "body", "else_clause"]
3716 def analyse_declarations(self, env):
3717 self.body.analyse_declarations(env)
3718 if self.else_clause:
3719 self.else_clause.analyse_declarations(env)
3721 def analyse_expressions(self, env):
3723 self.condition.analyse_temp_boolean_expression(env)
3724 self.body.analyse_expressions(env)
3725 if self.else_clause:
3726 self.else_clause.analyse_expressions(env)
3728 def generate_execution_code(self, code):
3729 old_loop_labels = code.new_loop_labels()
3732 self.condition.generate_evaluation_code(code)
3733 self.condition.generate_disposal_code(code)
3736 self.condition.result())
3737 self.condition.free_temps(code)
3738 self.body.generate_execution_code(code)
3739 code.put_label(code.continue_label)
3741 break_label = code.break_label
3742 code.set_loop_labels(old_loop_labels)
3743 if self.else_clause:
3744 code.putln("/*else*/ {")
3745 self.else_clause.generate_execution_code(code)
3747 code.put_label(break_label)
3749 def annotate(self, code):
3750 self.condition.annotate(code)
3751 self.body.annotate(code)
3752 if self.else_clause:
3753 self.else_clause.annotate(code)
3756 def ForStatNode(pos, **kw):
3757 if 'iterator' in kw:
3758 return ForInStatNode(pos, **kw)
3760 return ForFromStatNode(pos, **kw)
3762 class ForInStatNode(LoopNode, StatNode):
3766 # iterator IteratorNode
3768 # else_clause StatNode
3769 # item NextNode used internally
3771 child_attrs = ["target", "iterator", "body", "else_clause"]
3774 def analyse_declarations(self, env):
3775 self.target.analyse_target_declaration(env)
3776 self.body.analyse_declarations(env)
3777 if self.else_clause:
3778 self.else_clause.analyse_declarations(env)
3780 def analyse_expressions(self, env):
3782 self.target.analyse_target_types(env)
3783 self.iterator.analyse_expressions(env)
3784 self.item = ExprNodes.NextNode(self.iterator, env)
3785 self.item = self.item.coerce_to(self.target.type, env)
3786 self.body.analyse_expressions(env)
3787 if self.else_clause:
3788 self.else_clause.analyse_expressions(env)
3790 def generate_execution_code(self, code):
3791 old_loop_labels = code.new_loop_labels()
3792 self.iterator.allocate_counter_temp(code)
3793 self.iterator.generate_evaluation_code(code)
3796 self.item.generate_evaluation_code(code)
3797 self.target.generate_assignment_code(self.item, code)
3798 self.body.generate_execution_code(code)
3799 code.put_label(code.continue_label)
3802 break_label = code.break_label
3803 code.set_loop_labels(old_loop_labels)
3804 if self.else_clause:
3805 code.putln("/*else*/ {")
3806 self.else_clause.generate_execution_code(code)
3808 code.put_label(break_label)
3809 self.iterator.release_counter_temp(code)
3810 self.iterator.generate_disposal_code(code)
3811 self.iterator.free_temps(code)
3813 def annotate(self, code):
3814 self.target.annotate(code)
3815 self.iterator.annotate(code)
3816 self.body.annotate(code)
3817 if self.else_clause:
3818 self.else_clause.annotate(code)
3819 self.item.annotate(code)
3822 class ForFromStatNode(LoopNode, StatNode):
3823 # for name from expr rel name rel expr
3830 # step ExprNode or None
3832 # else_clause StatNode or None
3838 # loopvar_node ExprNode (usually a NameNode or temp node)
3839 # py_loopvar_node PyTempNode or None
3840 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3842 is_py_target = False
3844 py_loopvar_node = None
3847 gil_message = "For-loop using object bounds or target"
3849 def nogil_check(self, env):
3850 for x in (self.target, self.bound1, self.bound2):
3851 if x.type.is_pyobject:
3854 def analyse_declarations(self, env):
3855 self.target.analyse_target_declaration(env)
3856 self.body.analyse_declarations(env)
3857 if self.else_clause:
3858 self.else_clause.analyse_declarations(env)
3860 def analyse_expressions(self, env):
3862 self.target.analyse_target_types(env)
3863 self.bound1.analyse_types(env)
3864 self.bound2.analyse_types(env)
3865 if self.step is not None:
3866 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3867 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3868 self.step.analyse_types(env)
3870 target_type = self.target.type
3871 if self.target.type.is_numeric:
3872 loop_type = self.target.type
3874 loop_type = PyrexTypes.c_int_type
3875 if not self.bound1.type.is_pyobject:
3876 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3877 if not self.bound2.type.is_pyobject:
3878 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3879 if self.step is not None and not self.step.type.is_pyobject:
3880 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3881 self.bound1 = self.bound1.coerce_to(loop_type, env)
3882 self.bound2 = self.bound2.coerce_to(loop_type, env)
3883 if not self.bound2.is_literal:
3884 self.bound2 = self.bound2.coerce_to_temp(env)
3885 if self.step is not None:
3886 self.step = self.step.coerce_to(loop_type, env)
3887 if not self.step.is_literal:
3888 self.step = self.step.coerce_to_temp(env)
3890 target_type = self.target.type
3891 if not (target_type.is_pyobject or target_type.is_numeric):
3892 error(self.target.pos,
3893 "for-from loop variable must be c numeric type or Python object")
3894 if target_type.is_numeric:
3895 self.is_py_target = False
3896 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3897 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3898 self.loopvar_node = self.target
3899 self.py_loopvar_node = None
3901 self.is_py_target = True
3902 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3903 self.loopvar_node = c_loopvar_node
3904 self.py_loopvar_node = \
3905 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3906 self.body.analyse_expressions(env)
3907 if self.else_clause:
3908 self.else_clause.analyse_expressions(env)
3910 def generate_execution_code(self, code):
3911 old_loop_labels = code.new_loop_labels()
3912 from_range = self.from_range
3913 self.bound1.generate_evaluation_code(code)
3914 self.bound2.generate_evaluation_code(code)
3915 offset, incop = self.relation_table[self.relation1]
3916 if self.step is not None:
3917 self.step.generate_evaluation_code(code)
3918 step = self.step.result()
3919 incop = "%s=%s" % (incop[0], step)
3921 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3922 self.loopvar_node.allocate(code)
3923 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3924 self.py_loopvar_node.allocate(code)
3926 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3928 loopvar_name = self.loopvar_node.result()
3930 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3932 self.bound1.result(), offset,
3933 loopvar_name, self.relation2, self.bound2.result(),
3934 loopvar_name, incop))
3935 if self.py_loopvar_node:
3936 self.py_loopvar_node.generate_evaluation_code(code)
3937 self.target.generate_assignment_code(self.py_loopvar_node, code)
3939 code.putln("%s = %s;" % (
3940 self.target.result(), loopvar_name))
3941 self.body.generate_execution_code(code)
3942 code.put_label(code.continue_label)
3943 if self.py_loopvar_node:
3944 # This mess is to make for..from loops with python targets behave
3945 # exactly like those with C targets with regards to re-assignment
3946 # of the loop variable.
3948 if self.target.entry.is_pyglobal:
3949 # We know target is a NameNode, this is the only ugly case.
3950 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3951 target_node.allocate(code)
3952 interned_cname = code.intern_identifier(self.target.entry.name)
3953 code.putln("/*here*/")
3954 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3955 target_node.result(),
3956 Naming.module_cname,
3958 code.error_goto_if_null(target_node.result(), self.target.pos)))
3959 code.put_gotref(target_node.result())
3961 target_node = self.target
3962 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3963 from_py_node.temp_code = loopvar_name
3964 from_py_node.generate_result_code(code)
3965 if self.target.entry.is_pyglobal:
3966 code.put_decref(target_node.result(), target_node.type)
3967 target_node.release(code)
3969 if self.py_loopvar_node:
3970 # This is potentially wasteful, but we don't want the semantics to
3971 # depend on whether or not the loop is a python type.
3972 self.py_loopvar_node.generate_evaluation_code(code)
3973 self.target.generate_assignment_code(self.py_loopvar_node, code)
3974 break_label = code.break_label
3975 code.set_loop_labels(old_loop_labels)
3976 if self.else_clause:
3977 code.putln("/*else*/ {")
3978 self.else_clause.generate_execution_code(code)
3980 code.put_label(break_label)
3981 self.bound1.generate_disposal_code(code)
3982 self.bound1.free_temps(code)
3983 self.bound2.generate_disposal_code(code)
3984 self.bound2.free_temps(code)
3985 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3986 self.loopvar_node.release(code)
3987 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3988 self.py_loopvar_node.release(code)
3989 if self.step is not None:
3990 self.step.generate_disposal_code(code)
3991 self.step.free_temps(code)
3994 # {relop : (initial offset, increment op)}
4001 def annotate(self, code):
4002 self.target.annotate(code)
4003 self.bound1.annotate(code)
4004 self.bound2.annotate(code)
4006 self.bound2.annotate(code)
4007 self.body.annotate(code)
4008 if self.else_clause:
4009 self.else_clause.annotate(code)
4012 class WithStatNode(StatNode):
4014 Represents a Python with statement.
4016 This is only used at parse tree level; and is not present in
4017 analysis or generation phases.
4019 # manager The with statement manager object
4020 # target Node (lhs expression)
4022 child_attrs = ["manager", "target", "body"]
4024 class TryExceptStatNode(StatNode):
4025 # try .. except statement
4028 # except_clauses [ExceptClauseNode]
4029 # else_clause StatNode or None
4031 child_attrs = ["body", "except_clauses", "else_clause"]
4033 def analyse_control_flow(self, env):
4034 env.start_branching(self.pos)
4035 self.body.analyse_control_flow(env)
4036 successful_try = env.control_flow # grab this for later
4037 env.next_branch(self.body.end_pos())
4038 env.finish_branching(self.body.end_pos())
4040 env.start_branching(self.except_clauses[0].pos)
4041 for except_clause in self.except_clauses:
4042 except_clause.analyse_control_flow(env)
4043 env.next_branch(except_clause.end_pos())
4045 # the else cause it executed only when the try clause finishes
4046 env.control_flow.incoming = successful_try
4047 if self.else_clause:
4048 self.else_clause.analyse_control_flow(env)
4049 env.finish_branching(self.end_pos())
4051 def analyse_declarations(self, env):
4052 self.body.analyse_declarations(env)
4053 for except_clause in self.except_clauses:
4054 except_clause.analyse_declarations(env)
4055 if self.else_clause:
4056 self.else_clause.analyse_declarations(env)
4057 env.use_utility_code(reset_exception_utility_code)
4059 def analyse_expressions(self, env):
4060 self.body.analyse_expressions(env)
4061 default_clause_seen = 0
4062 for except_clause in self.except_clauses:
4063 except_clause.analyse_expressions(env)
4064 if default_clause_seen:
4065 error(except_clause.pos, "default 'except:' must be last")
4066 if not except_clause.pattern:
4067 default_clause_seen = 1
4068 self.has_default_clause = default_clause_seen
4069 if self.else_clause:
4070 self.else_clause.analyse_expressions(env)
4072 nogil_check = Node.gil_error
4073 gil_message = "Try-except statement"
4075 def generate_execution_code(self, code):
4076 old_return_label = code.return_label
4077 old_break_label = code.break_label
4078 old_continue_label = code.continue_label
4079 old_error_label = code.new_error_label()
4080 our_error_label = code.error_label
4081 except_end_label = code.new_label('exception_handled')
4082 except_error_label = code.new_label('except_error')
4083 except_return_label = code.new_label('except_return')
4084 try_return_label = code.new_label('try_return')
4085 try_break_label = code.new_label('try_break')
4086 try_continue_label = code.new_label('try_continue')
4087 try_end_label = code.new_label('try_end')
4090 code.putln("PyObject %s;" %
4091 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4092 code.putln("__Pyx_ExceptionSave(%s);" %
4093 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4094 for var in Naming.exc_save_vars:
4095 code.put_xgotref(var)
4098 code.return_label = try_return_label
4099 code.break_label = try_break_label
4100 code.continue_label = try_continue_label
4101 self.body.generate_execution_code(code)
4104 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4105 code.error_label = except_error_label
4106 code.return_label = except_return_label
4107 if self.else_clause:
4110 self.else_clause.generate_execution_code(code)
4113 for var in Naming.exc_save_vars:
4114 code.put_xdecref_clear(var, py_object_type)
4115 code.put_goto(try_end_label)
4116 if code.label_used(try_return_label):
4117 code.put_label(try_return_label)
4118 for var in Naming.exc_save_vars:
4119 code.put_xdecref_clear(var, py_object_type)
4120 code.put_goto(old_return_label)
4121 code.put_label(our_error_label)
4122 for temp_name, type in temps_to_clean_up:
4123 code.put_xdecref_clear(temp_name, type)
4124 for except_clause in self.except_clauses:
4125 except_clause.generate_handling_code(code, except_end_label)
4127 error_label_used = code.label_used(except_error_label)
4128 if error_label_used or not self.has_default_clause:
4129 if error_label_used:
4130 code.put_label(except_error_label)
4131 for var in Naming.exc_save_vars:
4132 code.put_xdecref(var, py_object_type)
4133 code.put_goto(old_error_label)
4135 if code.label_used(try_break_label):
4136 code.put_label(try_break_label)
4137 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4138 code.putln("__Pyx_ExceptionReset(%s);" %
4139 ', '.join(Naming.exc_save_vars))
4140 code.put_goto(old_break_label)
4142 if code.label_used(try_continue_label):
4143 code.put_label(try_continue_label)
4144 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4145 code.putln("__Pyx_ExceptionReset(%s);" %
4146 ', '.join(Naming.exc_save_vars))
4147 code.put_goto(old_continue_label)
4149 if code.label_used(except_return_label):
4150 code.put_label(except_return_label)
4151 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4152 code.putln("__Pyx_ExceptionReset(%s);" %
4153 ', '.join(Naming.exc_save_vars))
4154 code.put_goto(old_return_label)
4156 if code.label_used(except_end_label):
4157 code.put_label(except_end_label)
4158 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4159 code.putln("__Pyx_ExceptionReset(%s);" %
4160 ', '.join(Naming.exc_save_vars))
4161 code.put_label(try_end_label)
4164 code.return_label = old_return_label
4165 code.break_label = old_break_label
4166 code.continue_label = old_continue_label
4167 code.error_label = old_error_label
4169 def annotate(self, code):
4170 self.body.annotate(code)
4171 for except_node in self.except_clauses:
4172 except_node.annotate(code)
4173 if self.else_clause:
4174 self.else_clause.annotate(code)
4177 class ExceptClauseNode(Node):
4178 # Part of try ... except statement.
4181 # target ExprNode or None
4183 # excinfo_target NameNode or None optional target for exception info
4184 # match_flag string result of exception match
4185 # exc_value ExcValueNode used internally
4186 # function_name string qualified name of enclosing function
4187 # exc_vars (string * 3) local exception variables
4189 # excinfo_target is never set by the parser, but can be set by a transform
4190 # in order to extract more extensive information about the exception as a
4191 # sys.exc_info()-style tuple into a target variable
4193 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4196 excinfo_target = None
4198 def analyse_declarations(self, env):
4200 self.target.analyse_target_declaration(env)
4201 if self.excinfo_target is not None:
4202 self.excinfo_target.analyse_target_declaration(env)
4203 self.body.analyse_declarations(env)
4205 def analyse_expressions(self, env):
4207 genv = env.global_scope()
4208 self.function_name = env.qualified_name
4210 self.pattern.analyse_expressions(env)
4211 self.pattern = self.pattern.coerce_to_pyobject(env)
4214 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4215 self.target.analyse_target_expression(env, self.exc_value)
4216 if self.excinfo_target is not None:
4218 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4219 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4220 self.excinfo_tuple.analyse_expressions(env)
4221 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4223 self.body.analyse_expressions(env)
4225 def generate_handling_code(self, code, end_label):
4226 code.mark_pos(self.pos)
4228 self.pattern.generate_evaluation_code(code)
4230 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4232 "%s = PyErr_ExceptionMatches(%s);" % (
4234 self.pattern.py_result()))
4235 self.pattern.generate_disposal_code(code)
4236 self.pattern.free_temps(code)
4240 code.funcstate.release_temp(match_flag)
4242 code.putln("/*except:*/ {")
4244 if not getattr(self.body, 'stats', True):
4245 # most simple case: no exception variable, empty body (pass)
4246 # => reset the exception state, done
4247 code.putln("PyErr_Restore(0,0,0);")
4248 code.put_goto(end_label)
4252 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4255 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4256 # We always have to fetch the exception value even if
4257 # there is no target, because this also normalises the
4258 # exception and stores it in the thread state.
4259 code.globalstate.use_utility_code(get_exception_utility_code)
4260 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4261 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4262 code.error_goto(self.pos)))
4266 self.exc_value.set_var(exc_vars[1])
4267 self.exc_value.generate_evaluation_code(code)
4268 self.target.generate_assignment_code(self.exc_value, code)
4269 if self.excinfo_target is not None:
4270 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4271 node.set_var(tempvar)
4272 self.excinfo_tuple.generate_evaluation_code(code)
4273 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4275 old_break_label, old_continue_label = code.break_label, code.continue_label
4276 code.break_label = code.new_label('except_break')
4277 code.continue_label = code.new_label('except_continue')
4279 old_exc_vars = code.funcstate.exc_vars
4280 code.funcstate.exc_vars = exc_vars
4281 self.body.generate_execution_code(code)
4282 code.funcstate.exc_vars = old_exc_vars
4283 for var in exc_vars:
4284 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4285 code.put_goto(end_label)
4287 if code.label_used(code.break_label):
4288 code.put_label(code.break_label)
4289 for var in exc_vars:
4290 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4291 code.put_goto(old_break_label)
4292 code.break_label = old_break_label
4294 if code.label_used(code.continue_label):
4295 code.put_label(code.continue_label)
4296 for var in exc_vars:
4297 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4298 code.put_goto(old_continue_label)
4299 code.continue_label = old_continue_label
4301 for temp in exc_vars:
4302 code.funcstate.release_temp(temp)
4307 def annotate(self, code):
4309 self.pattern.annotate(code)
4311 self.target.annotate(code)
4312 self.body.annotate(code)
4315 class TryFinallyStatNode(StatNode):
4316 # try ... finally statement
4319 # finally_clause StatNode
4321 # The plan is that we funnel all continue, break
4322 # return and error gotos into the beginning of the
4323 # finally block, setting a variable to remember which
4324 # one we're doing. At the end of the finally block, we
4325 # switch on the variable to figure out where to go.
4326 # In addition, if we're doing an error, we save the
4327 # exception on entry to the finally block and restore
4330 child_attrs = ["body", "finally_clause"]
4332 preserve_exception = 1
4334 disallow_continue_in_try_finally = 0
4335 # There doesn't seem to be any point in disallowing
4336 # continue in the try block, since we have no problem
4339 def create_analysed(pos, env, body, finally_clause):
4340 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4342 create_analysed = staticmethod(create_analysed)
4344 def analyse_control_flow(self, env):
4345 env.start_branching(self.pos)
4346 self.body.analyse_control_flow(env)
4347 env.next_branch(self.body.end_pos())
4348 env.finish_branching(self.body.end_pos())
4349 self.finally_clause.analyse_control_flow(env)
4351 def analyse_declarations(self, env):
4352 self.body.analyse_declarations(env)
4353 self.finally_clause.analyse_declarations(env)
4355 def analyse_expressions(self, env):
4356 self.body.analyse_expressions(env)
4357 self.finally_clause.analyse_expressions(env)
4359 nogil_check = Node.gil_error
4360 gil_message = "Try-finally statement"
4362 def generate_execution_code(self, code):
4363 old_error_label = code.error_label
4364 old_labels = code.all_new_labels()
4365 new_labels = code.get_all_labels()
4366 new_error_label = code.error_label
4367 catch_label = code.new_label()
4370 if self.disallow_continue_in_try_finally:
4371 was_in_try_finally = code.funcstate.in_try_finally
4372 code.funcstate.in_try_finally = 1
4373 self.body.generate_execution_code(code)
4374 if self.disallow_continue_in_try_finally:
4375 code.funcstate.in_try_finally = was_in_try_finally
4378 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4382 error_label_used = 0
4383 for i, new_label in enumerate(new_labels):
4384 if new_label in code.labels_used:
4385 cases_used.append(i)
4386 if new_label == new_error_label:
4387 error_label_used = 1
4388 error_label_case = i
4392 if error_label_used and self.preserve_exception:
4394 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4396 "int %s;" % Naming.exc_lineno_name)
4397 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4398 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4399 code.putln(exc_var_init_zero)
4401 exc_var_init_zero = None
4402 code.use_label(catch_label)
4404 "__pyx_why = 0; goto %s;" % catch_label)
4405 for i in cases_used:
4406 new_label = new_labels[i]
4407 #if new_label and new_label != "<try>":
4408 if new_label == new_error_label and self.preserve_exception:
4409 self.put_error_catcher(code,
4410 new_error_label, i+1, catch_label, temps_to_clean_up)
4412 code.put('%s: ' % new_label)
4413 if exc_var_init_zero:
4414 code.putln(exc_var_init_zero)
4415 code.putln("__pyx_why = %s; goto %s;" % (
4418 code.put_label(catch_label)
4419 code.set_all_labels(old_labels)
4420 if error_label_used:
4421 code.new_error_label()
4422 finally_error_label = code.error_label
4423 self.finally_clause.generate_execution_code(code)
4424 if error_label_used:
4425 if finally_error_label in code.labels_used and self.preserve_exception:
4426 over_label = code.new_label()
4427 code.put_goto(over_label);
4428 code.put_label(finally_error_label)
4429 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4430 for var in Naming.exc_vars:
4431 code.putln("Py_XDECREF(%s);" % var)
4433 code.put_goto(old_error_label)
4434 code.put_label(over_label)
4435 code.error_label = old_error_label
4438 "switch (__pyx_why) {")
4439 for i in cases_used:
4440 old_label = old_labels[i]
4441 if old_label == old_error_label and self.preserve_exception:
4442 self.put_error_uncatcher(code, i+1, old_error_label)
4444 code.use_label(old_label)
4446 "case %s: goto %s;" % (
4454 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4455 code.globalstate.use_utility_code(restore_exception_utility_code)
4462 for temp_name, type in temps_to_clean_up:
4463 code.put_xdecref_clear(temp_name, type)
4465 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4469 Naming.exc_lineno_name, Naming.lineno_cname))
4473 code.put_goto(catch_label)
4477 def put_error_uncatcher(self, code, i, error_label):
4478 code.globalstate.use_utility_code(restore_exception_utility_code)
4483 "__Pyx_ErrRestore(%s, %s, %s);" %
4487 Naming.lineno_cname, Naming.exc_lineno_name))
4488 for var in Naming.exc_vars:
4492 code.put_goto(error_label)
4496 def annotate(self, code):
4497 self.body.annotate(code)
4498 self.finally_clause.annotate(code)
4501 class GILStatNode(TryFinallyStatNode):
4502 # 'with gil' or 'with nogil' statement
4504 # state string 'gil' or 'nogil'
4508 preserve_exception = 0
4510 def __init__(self, pos, state, body):
4512 TryFinallyStatNode.__init__(self, pos,
4514 finally_clause = GILExitNode(pos, state = state))
4516 def analyse_expressions(self, env):
4517 env.use_utility_code(force_init_threads_utility_code)
4518 was_nogil = env.nogil
4520 TryFinallyStatNode.analyse_expressions(self, env)
4521 env.nogil = was_nogil
4525 def generate_execution_code(self, code):
4526 code.mark_pos(self.pos)
4527 if self.state == 'gil':
4528 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4530 code.putln("{ PyThreadState *_save;")
4531 code.putln("Py_UNBLOCK_THREADS")
4532 TryFinallyStatNode.generate_execution_code(self, code)
4536 class GILExitNode(StatNode):
4537 # Used as the 'finally' block in a GILStatNode
4539 # state string 'gil' or 'nogil'
4543 def analyse_expressions(self, env):
4546 def generate_execution_code(self, code):
4547 if self.state == 'gil':
4548 code.putln("PyGILState_Release();")
4550 code.putln("Py_BLOCK_THREADS")
4553 class CImportStatNode(StatNode):
4556 # module_name string Qualified name of module being imported
4557 # as_name string or None Name specified in "as" clause, if any
4561 def analyse_declarations(self, env):
4562 if not env.is_module_scope:
4563 error(self.pos, "cimport only allowed at module level")
4565 module_scope = env.find_module(self.module_name, self.pos)
4566 if "." in self.module_name:
4567 names = [EncodedString(name) for name in self.module_name.split(".")]
4569 top_module_scope = env.context.find_submodule(top_name)
4570 module_scope = top_module_scope
4571 for name in names[1:]:
4572 submodule_scope = module_scope.find_submodule(name)
4573 module_scope.declare_module(name, submodule_scope, self.pos)
4574 module_scope = submodule_scope
4576 env.declare_module(self.as_name, module_scope, self.pos)
4578 env.declare_module(top_name, top_module_scope, self.pos)
4580 name = self.as_name or self.module_name
4581 env.declare_module(name, module_scope, self.pos)
4583 def analyse_expressions(self, env):
4586 def generate_execution_code(self, code):
4590 class FromCImportStatNode(StatNode):
4591 # from ... cimport statement
4593 # module_name string Qualified name of module
4594 # imported_names [(pos, name, as_name, kind)] Names to be imported
4598 def analyse_declarations(self, env):
4599 if not env.is_module_scope:
4600 error(self.pos, "cimport only allowed at module level")
4602 module_scope = env.find_module(self.module_name, self.pos)
4603 env.add_imported_module(module_scope)
4604 for pos, name, as_name, kind in self.imported_names:
4606 for local_name, entry in module_scope.entries.items():
4607 env.add_imported_entry(local_name, entry, pos)
4609 entry = module_scope.lookup(name)
4611 if kind and not self.declaration_matches(entry, kind):
4612 entry.redeclared(pos)
4614 if kind == 'struct' or kind == 'union':
4615 entry = module_scope.declare_struct_or_union(name,
4616 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4617 elif kind == 'class':
4618 entry = module_scope.declare_c_class(name, pos = pos,
4619 module_name = self.module_name)
4621 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4622 if submodule_scope.parent_module is module_scope:
4623 env.declare_module(as_name or name, submodule_scope, self.pos)
4625 error(pos, "Name '%s' not declared in module '%s'"
4626 % (name, self.module_name))
4629 local_name = as_name or name
4630 env.add_imported_entry(local_name, entry, pos)
4632 def declaration_matches(self, entry, kind):
4633 if not entry.is_type:
4637 if not type.is_extension_type:
4640 if not type.is_struct_or_union:
4642 if kind != type.kind:
4646 def analyse_expressions(self, env):
4649 def generate_execution_code(self, code):
4653 class FromImportStatNode(StatNode):
4654 # from ... import statement
4657 # items [(string, NameNode)]
4658 # interned_items [(string, NameNode, ExprNode)]
4659 # item PyTempNode used internally
4660 # import_star boolean used internally
4662 child_attrs = ["module"]
4665 def analyse_declarations(self, env):
4666 for name, target in self.items:
4668 if not env.is_module_scope:
4669 error(self.pos, "import * only allowed at module level")
4671 env.has_import_star = 1
4672 self.import_star = 1
4674 target.analyse_target_declaration(env)
4676 def analyse_expressions(self, env):
4678 self.module.analyse_expressions(env)
4679 self.item = ExprNodes.PyTempNode(self.pos, env)
4680 self.interned_items = []
4681 for name, target in self.items:
4683 for _, entry in env.entries.items():
4684 if not entry.is_type and entry.type.is_extension_type:
4685 env.use_utility_code(ExprNodes.type_test_utility_code)
4688 entry = env.lookup(target.name)
4689 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4690 continue # already cimported
4691 target.analyse_target_expression(env, None)
4692 if target.type is py_object_type:
4695 coerced_item = self.item.coerce_to(target.type, env)
4696 self.interned_items.append(
4697 (name, target, coerced_item))
4699 def generate_execution_code(self, code):
4700 self.module.generate_evaluation_code(code)
4701 if self.import_star:
4703 'if (%s(%s) < 0) %s;' % (
4705 self.module.py_result(),
4706 code.error_goto(self.pos)))
4707 self.item.allocate(code)
4708 for name, target, coerced_item in self.interned_items:
4709 cname = code.intern_identifier(name)
4711 '%s = PyObject_GetAttr(%s, %s); %s' % (
4713 self.module.py_result(),
4715 code.error_goto_if_null(self.item.result(), self.pos)))
4716 code.put_gotref(self.item.py_result())
4717 if coerced_item is None:
4718 target.generate_assignment_code(self.item, code)
4720 coerced_item.allocate_temp_result(code)
4721 coerced_item.generate_result_code(code)
4722 target.generate_assignment_code(coerced_item, code)
4723 if self.item.result() != coerced_item.result():
4724 code.put_decref_clear(self.item.result(), self.item.type)
4725 self.item.release(code)
4726 self.module.generate_disposal_code(code)
4727 self.module.free_temps(code)
4731 #------------------------------------------------------------------------------------
4733 # Runtime support code
4735 #------------------------------------------------------------------------------------
4737 utility_function_predeclarations = \
4740 #define INLINE __inline__
4742 #define INLINE __inline
4747 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4751 static int %(skip_dispatch_cname)s = 0;
4753 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4755 if Options.gcc_branch_hints:
4756 branch_prediction_macros = \
4759 /* Test for GCC > 2.95 */
4760 #if __GNUC__ > 2 || \
4761 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4762 #define likely(x) __builtin_expect(!!(x), 1)
4763 #define unlikely(x) __builtin_expect(!!(x), 0)
4764 #else /* __GNUC__ > 2 ... */
4765 #define likely(x) (x)
4766 #define unlikely(x) (x)
4767 #endif /* __GNUC__ > 2 ... */
4768 #else /* __GNUC__ */
4769 #define likely(x) (x)
4770 #define unlikely(x) (x)
4771 #endif /* __GNUC__ */
4774 branch_prediction_macros = \
4776 #define likely(x) (x)
4777 #define unlikely(x) (x)
4780 #get_name_predeclaration = \
4781 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4783 #get_name_interned_predeclaration = \
4784 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4786 #------------------------------------------------------------------------------------
4788 printing_utility_code = UtilityCode(
4790 static int __Pyx_Print(PyObject *, int); /*proto*/
4791 #if PY_MAJOR_VERSION >= 3
4792 static PyObject* %s = 0;
4793 static PyObject* %s = 0;
4795 """ % (Naming.print_function, Naming.print_function_kwargs),
4797 #if PY_MAJOR_VERSION < 3
4798 static PyObject *__Pyx_GetStdout(void) {
4799 PyObject *f = PySys_GetObject((char *)"stdout");
4801 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4806 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4811 if (!(f = __Pyx_GetStdout()))
4813 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4814 if (PyFile_SoftSpace(f, 1)) {
4815 if (PyFile_WriteString(" ", f) < 0)
4818 v = PyTuple_GET_ITEM(arg_tuple, i);
4819 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4821 if (PyString_Check(v)) {
4822 char *s = PyString_AsString(v);
4823 Py_ssize_t len = PyString_Size(v);
4825 isspace(Py_CHARMASK(s[len-1])) &&
4827 PyFile_SoftSpace(f, 0);
4831 if (PyFile_WriteString("\n", f) < 0)
4833 PyFile_SoftSpace(f, 0);
4838 #else /* Python 3 has a print function */
4840 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4841 PyObject* kwargs = 0;
4842 PyObject* result = 0;
4843 PyObject* end_string;
4844 if (!%(PRINT_FUNCTION)s) {
4845 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4846 if (!%(PRINT_FUNCTION)s)
4850 if (!%(PRINT_KWARGS)s) {
4851 %(PRINT_KWARGS)s = PyDict_New();
4852 if (!%(PRINT_KWARGS)s)
4854 end_string = PyUnicode_FromStringAndSize(" ", 1);
4857 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4858 Py_DECREF(end_string);
4861 Py_DECREF(end_string);
4863 kwargs = %(PRINT_KWARGS)s;
4865 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4873 """ % {'BUILTINS' : Naming.builtins_cname,
4874 'PRINT_FUNCTION' : Naming.print_function,
4875 'PRINT_KWARGS' : Naming.print_function_kwargs}
4879 printing_one_utility_code = UtilityCode(
4881 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4884 #if PY_MAJOR_VERSION < 3
4886 static int __Pyx_PrintOne(PyObject *o) {
4888 if (!(f = __Pyx_GetStdout()))
4890 if (PyFile_SoftSpace(f, 0)) {
4891 if (PyFile_WriteString(" ", f) < 0)
4894 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4896 if (PyFile_WriteString("\n", f) < 0)
4899 /* the line below is just to avoid compiler
4900 * compiler warnings about unused functions */
4901 return __Pyx_Print(NULL, 0);
4904 #else /* Python 3 has a print function */
4906 static int __Pyx_PrintOne(PyObject *o) {
4908 PyObject* arg_tuple = PyTuple_New(1);
4909 if (unlikely(!arg_tuple))
4912 PyTuple_SET_ITEM(arg_tuple, 0, o);
4913 res = __Pyx_Print(arg_tuple, 1);
4914 Py_DECREF(arg_tuple);
4920 requires=[printing_utility_code])
4924 #------------------------------------------------------------------------------------
4926 # The following function is based on do_raise() from ceval.c.
4928 raise_utility_code = UtilityCode(
4930 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4933 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4937 /* First, check the traceback argument, replacing None with NULL. */
4938 if (tb == Py_None) {
4942 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4943 PyErr_SetString(PyExc_TypeError,
4944 "raise: arg 3 must be a traceback or None");
4947 /* Next, replace a missing value with None */
4948 if (value == NULL) {
4952 #if PY_VERSION_HEX < 0x02050000
4953 if (!PyClass_Check(type))
4955 if (!PyType_Check(type))
4958 /* Raising an instance. The value should be a dummy. */
4959 if (value != Py_None) {
4960 PyErr_SetString(PyExc_TypeError,
4961 "instance exception may not have a separate value");
4964 /* Normalize to raise <class>, <instance> */
4967 #if PY_VERSION_HEX < 0x02050000
4968 if (PyInstance_Check(type)) {
4969 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4974 PyErr_SetString(PyExc_TypeError,
4975 "raise: exception must be an old-style class or instance");
4979 type = (PyObject*) Py_TYPE(type);
4981 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4982 PyErr_SetString(PyExc_TypeError,
4983 "raise: exception class must be a subclass of BaseException");
4988 __Pyx_ErrRestore(type, value, tb);
4998 #------------------------------------------------------------------------------------
5000 reraise_utility_code = UtilityCode(
5002 static void __Pyx_ReRaise(void); /*proto*/
5005 static void __Pyx_ReRaise(void) {
5006 PyThreadState *tstate = PyThreadState_GET();
5007 PyObject* tmp_type = tstate->curexc_type;
5008 PyObject* tmp_value = tstate->curexc_value;
5009 PyObject* tmp_tb = tstate->curexc_traceback;
5010 tstate->curexc_type = tstate->exc_type;
5011 tstate->curexc_value = tstate->exc_value;
5012 tstate->curexc_traceback = tstate->exc_traceback;
5013 tstate->exc_type = 0;
5014 tstate->exc_value = 0;
5015 tstate->exc_traceback = 0;
5016 Py_XDECREF(tmp_type);
5017 Py_XDECREF(tmp_value);
5022 #------------------------------------------------------------------------------------
5024 arg_type_test_utility_code = UtilityCode(
5026 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5027 const char *name, int exact); /*proto*/
5030 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5031 const char *name, int exact)
5034 PyErr_Format(PyExc_SystemError, "Missing type object");
5037 if (none_allowed && obj == Py_None) return 1;
5039 if (Py_TYPE(obj) == type) return 1;
5042 if (PyObject_TypeCheck(obj, type)) return 1;
5044 PyErr_Format(PyExc_TypeError,
5045 "Argument '%s' has incorrect type (expected %s, got %s)",
5046 name, type->tp_name, Py_TYPE(obj)->tp_name);
5051 #------------------------------------------------------------------------------------
5053 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5054 # many or too few positional arguments were found. This handles
5055 # Py_ssize_t formatting correctly.
5057 raise_argtuple_invalid_utility_code = UtilityCode(
5059 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5060 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5063 static void __Pyx_RaiseArgtupleInvalid(
5064 const char* func_name,
5068 Py_ssize_t num_found)
5070 Py_ssize_t num_expected;
5071 const char *number, *more_or_less;
5073 if (num_found < num_min) {
5074 num_expected = num_min;
5075 more_or_less = "at least";
5077 num_expected = num_max;
5078 more_or_less = "at most";
5081 more_or_less = "exactly";
5083 number = (num_expected == 1) ? "" : "s";
5084 PyErr_Format(PyExc_TypeError,
5085 #if PY_VERSION_HEX < 0x02050000
5086 "%s() takes %s %d positional argument%s (%d given)",
5088 "%s() takes %s %zd positional argument%s (%zd given)",
5090 func_name, more_or_less, num_expected, number, num_found);
5094 raise_keyword_required_utility_code = UtilityCode(
5096 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5099 static INLINE void __Pyx_RaiseKeywordRequired(
5100 const char* func_name,
5103 PyErr_Format(PyExc_TypeError,
5104 #if PY_MAJOR_VERSION >= 3
5105 "%s() needs keyword-only argument %U", func_name, kw_name);
5107 "%s() needs keyword-only argument %s", func_name,
5108 PyString_AS_STRING(kw_name));
5113 raise_double_keywords_utility_code = UtilityCode(
5115 static void __Pyx_RaiseDoubleKeywordsError(
5116 const char* func_name, PyObject* kw_name); /*proto*/
5119 static void __Pyx_RaiseDoubleKeywordsError(
5120 const char* func_name,
5123 PyErr_Format(PyExc_TypeError,
5124 #if PY_MAJOR_VERSION >= 3
5125 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5127 "%s() got multiple values for keyword argument '%s'", func_name,
5128 PyString_AS_STRING(kw_name));
5133 #------------------------------------------------------------------------------------
5135 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5136 # were passed to a function, or if any keywords were passed to a
5137 # function that does not accept them.
5139 keyword_string_check_utility_code = UtilityCode(
5141 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5142 const char* function_name, int kw_allowed); /*proto*/
5145 static INLINE int __Pyx_CheckKeywordStrings(
5147 const char* function_name,
5152 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5153 #if PY_MAJOR_VERSION < 3
5154 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5156 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5158 goto invalid_keyword_type;
5160 if ((!kw_allowed) && unlikely(key))
5161 goto invalid_keyword;
5163 invalid_keyword_type:
5164 PyErr_Format(PyExc_TypeError,
5165 "%s() keywords must be strings", function_name);
5168 PyErr_Format(PyExc_TypeError,
5169 #if PY_MAJOR_VERSION < 3
5170 "%s() got an unexpected keyword argument '%s'",
5171 function_name, PyString_AsString(key));
5173 "%s() got an unexpected keyword argument '%U'",
5174 function_name, key);
5180 #------------------------------------------------------------------------------------
5182 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5183 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5184 # keywords will raise an invalid keyword error.
5186 # Three kinds of errors are checked: 1) non-string keywords, 2)
5187 # unexpected keywords and 3) overlap with positional arguments.
5189 # If num_posargs is greater 0, it denotes the number of positional
5190 # arguments that were passed and that must therefore not appear
5191 # amongst the keywords as well.
5193 # This method does not check for required keyword arguments.
5196 parse_keywords_utility_code = UtilityCode(
5198 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5199 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5200 const char* function_name); /*proto*/
5203 static int __Pyx_ParseOptionalKeywords(
5205 PyObject **argnames[],
5208 Py_ssize_t num_pos_args,
5209 const char* function_name)
5211 PyObject *key = 0, *value = 0;
5214 PyObject*** first_kw_arg = argnames + num_pos_args;
5216 while (PyDict_Next(kwds, &pos, &key, &value)) {
5217 name = first_kw_arg;
5218 while (*name && (**name != key)) name++;
5220 values[name-argnames] = value;
5222 #if PY_MAJOR_VERSION < 3
5223 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5225 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5227 goto invalid_keyword_type;
5229 for (name = first_kw_arg; *name; name++) {
5230 #if PY_MAJOR_VERSION >= 3
5231 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5232 PyUnicode_Compare(**name, key) == 0) break;
5234 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5235 _PyString_Eq(**name, key)) break;
5239 values[name-argnames] = value;
5241 /* unexpected keyword found */
5242 for (name=argnames; name != first_kw_arg; name++) {
5243 if (**name == key) goto arg_passed_twice;
5244 #if PY_MAJOR_VERSION >= 3
5245 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5246 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5248 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5249 _PyString_Eq(**name, key)) goto arg_passed_twice;
5253 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5255 goto invalid_keyword;
5263 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5265 invalid_keyword_type:
5266 PyErr_Format(PyExc_TypeError,
5267 "%s() keywords must be strings", function_name);
5270 PyErr_Format(PyExc_TypeError,
5271 #if PY_MAJOR_VERSION < 3
5272 "%s() got an unexpected keyword argument '%s'",
5273 function_name, PyString_AsString(key));
5275 "%s() got an unexpected keyword argument '%U'",
5276 function_name, key);
5283 #------------------------------------------------------------------------------------
5285 traceback_utility_code = UtilityCode(
5287 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5290 #include "compile.h"
5291 #include "frameobject.h"
5292 #include "traceback.h"
5294 static void __Pyx_AddTraceback(const char *funcname) {
5295 PyObject *py_srcfile = 0;
5296 PyObject *py_funcname = 0;
5297 PyObject *py_globals = 0;
5298 PyCodeObject *py_code = 0;
5299 PyFrameObject *py_frame = 0;
5301 #if PY_MAJOR_VERSION < 3
5302 py_srcfile = PyString_FromString(%(FILENAME)s);
5304 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5306 if (!py_srcfile) goto bad;
5308 #if PY_MAJOR_VERSION < 3
5309 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5311 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5315 #if PY_MAJOR_VERSION < 3
5316 py_funcname = PyString_FromString(funcname);
5318 py_funcname = PyUnicode_FromString(funcname);
5321 if (!py_funcname) goto bad;
5322 py_globals = PyModule_GetDict(%(GLOBALS)s);
5323 if (!py_globals) goto bad;
5324 py_code = PyCode_New(
5325 0, /*int argcount,*/
5326 #if PY_MAJOR_VERSION >= 3
5327 0, /*int kwonlyargcount,*/
5330 0, /*int stacksize,*/
5332 %(EMPTY_BYTES)s, /*PyObject *code,*/
5333 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5334 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5335 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5336 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5337 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5338 py_srcfile, /*PyObject *filename,*/
5339 py_funcname, /*PyObject *name,*/
5340 %(LINENO)s, /*int firstlineno,*/
5341 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5343 if (!py_code) goto bad;
5344 py_frame = PyFrame_New(
5345 PyThreadState_GET(), /*PyThreadState *tstate,*/
5346 py_code, /*PyCodeObject *code,*/
5347 py_globals, /*PyObject *globals,*/
5348 0 /*PyObject *locals*/
5350 if (!py_frame) goto bad;
5351 py_frame->f_lineno = %(LINENO)s;
5352 PyTraceBack_Here(py_frame);
5354 Py_XDECREF(py_srcfile);
5355 Py_XDECREF(py_funcname);
5356 Py_XDECREF(py_code);
5357 Py_XDECREF(py_frame);
5360 'FILENAME': Naming.filename_cname,
5361 'LINENO': Naming.lineno_cname,
5362 'CFILENAME': Naming.cfilenm_cname,
5363 'CLINENO': Naming.clineno_cname,
5364 'GLOBALS': Naming.module_cname,
5365 'EMPTY_TUPLE' : Naming.empty_tuple,
5366 'EMPTY_BYTES' : Naming.empty_bytes,
5369 restore_exception_utility_code = UtilityCode(
5371 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5372 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5375 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5376 PyObject *tmp_type, *tmp_value, *tmp_tb;
5377 PyThreadState *tstate = PyThreadState_GET();
5379 #if PY_MAJOR_VERSION >= 3
5380 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5381 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5382 tmp_type = tstate->exc_type;
5383 tmp_value = tstate->exc_value;
5384 tmp_tb = tstate->exc_traceback;
5385 PyErr_NormalizeException(&type, &value, &tb);
5386 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5387 tstate->exc_type = 0;
5388 tstate->exc_value = 0;
5389 tstate->exc_traceback = 0;
5390 PyException_SetContext(value, tmp_value);
5391 Py_DECREF(tmp_type);
5396 tmp_type = tstate->curexc_type;
5397 tmp_value = tstate->curexc_value;
5398 tmp_tb = tstate->curexc_traceback;
5399 tstate->curexc_type = type;
5400 tstate->curexc_value = value;
5401 tstate->curexc_traceback = tb;
5402 Py_XDECREF(tmp_type);
5403 Py_XDECREF(tmp_value);
5407 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5408 PyThreadState *tstate = PyThreadState_GET();
5409 *type = tstate->curexc_type;
5410 *value = tstate->curexc_value;
5411 *tb = tstate->curexc_traceback;
5413 tstate->curexc_type = 0;
5414 tstate->curexc_value = 0;
5415 tstate->curexc_traceback = 0;
5420 #------------------------------------------------------------------------------------
5422 unraisable_exception_utility_code = UtilityCode(
5424 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5427 static void __Pyx_WriteUnraisable(const char *name) {
5428 PyObject *old_exc, *old_val, *old_tb;
5430 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5431 #if PY_MAJOR_VERSION < 3
5432 ctx = PyString_FromString(name);
5434 ctx = PyUnicode_FromString(name);
5436 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5438 PyErr_WriteUnraisable(Py_None);
5440 PyErr_WriteUnraisable(ctx);
5445 requires=[restore_exception_utility_code])
5447 #------------------------------------------------------------------------------------
5449 set_vtable_utility_code = UtilityCode(
5451 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5454 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5455 PyObject *pycobj = 0;
5458 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5461 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5474 #------------------------------------------------------------------------------------
5476 get_vtable_utility_code = UtilityCode(
5478 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5481 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5485 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5488 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5489 if (!*(void **)vtabptr)
5502 #------------------------------------------------------------------------------------
5504 init_string_tab_utility_code = UtilityCode(
5506 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5509 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5511 #if PY_MAJOR_VERSION < 3
5512 if (t->is_unicode && (!t->is_identifier)) {
5513 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5514 } else if (t->intern) {
5515 *t->p = PyString_InternFromString(t->s);
5517 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5519 #else /* Python 3+ has unicode identifiers */
5520 if (t->is_identifier || (t->is_unicode && t->intern)) {
5521 *t->p = PyUnicode_InternFromString(t->s);
5522 } else if (t->is_unicode) {
5523 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5525 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5536 #------------------------------------------------------------------------------------
5538 get_exception_utility_code = UtilityCode(
5540 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5543 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5544 PyObject *tmp_type, *tmp_value, *tmp_tb;
5545 PyThreadState *tstate = PyThreadState_GET();
5546 *type = tstate->curexc_type;
5547 *value = tstate->curexc_value;
5548 *tb = tstate->curexc_traceback;
5549 tstate->curexc_type = 0;
5550 tstate->curexc_value = 0;
5551 tstate->curexc_traceback = 0;
5552 PyErr_NormalizeException(type, value, tb);
5553 if (PyErr_Occurred())
5558 tmp_type = tstate->exc_type;
5559 tmp_value = tstate->exc_value;
5560 tmp_tb = tstate->exc_traceback;
5561 tstate->exc_type = *type;
5562 tstate->exc_value = *value;
5563 tstate->exc_traceback = *tb;
5564 /* Make sure tstate is in a consistent state when we XDECREF
5565 these objects (XDECREF may run arbitrary code). */
5566 Py_XDECREF(tmp_type);
5567 Py_XDECREF(tmp_value);
5579 #------------------------------------------------------------------------------------
5581 get_exception_tuple_utility_code = UtilityCode(proto="""
5582 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5585 static PyObject *__Pyx_GetExceptionTuple(void) {
5586 PyObject *type = NULL, *value = NULL, *tb = NULL;
5587 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5588 PyObject* exc_info = PyTuple_New(3);
5593 PyTuple_SET_ITEM(exc_info, 0, type);
5594 PyTuple_SET_ITEM(exc_info, 1, value);
5595 PyTuple_SET_ITEM(exc_info, 2, tb);
5602 requires=[get_exception_utility_code])
5604 #------------------------------------------------------------------------------------
5606 reset_exception_utility_code = UtilityCode(
5608 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5609 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5612 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5613 PyThreadState *tstate = PyThreadState_GET();
5614 *type = tstate->exc_type;
5615 *value = tstate->exc_value;
5616 *tb = tstate->exc_traceback;
5622 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5623 PyObject *tmp_type, *tmp_value, *tmp_tb;
5624 PyThreadState *tstate = PyThreadState_GET();
5625 tmp_type = tstate->exc_type;
5626 tmp_value = tstate->exc_value;
5627 tmp_tb = tstate->exc_traceback;
5628 tstate->exc_type = type;
5629 tstate->exc_value = value;
5630 tstate->exc_traceback = tb;
5631 Py_XDECREF(tmp_type);
5632 Py_XDECREF(tmp_value);
5637 #------------------------------------------------------------------------------------
5639 force_init_threads_utility_code = UtilityCode(
5641 #ifndef __PYX_FORCE_INIT_THREADS
5642 #if PY_VERSION_HEX < 0x02040200
5643 #define __PYX_FORCE_INIT_THREADS 1
5645 #define __PYX_FORCE_INIT_THREADS 0
5650 #------------------------------------------------------------------------------------
5652 # Note that cPython ignores PyTrace_EXCEPTION,
5653 # but maybe some other profilers don't.
5655 trace_utility_code = UtilityCode(proto="""
5656 #ifndef CYTHON_TRACING
5657 #define CYTHON_TRACING 1
5660 #ifndef CYTHON_TRACING_REUSE_FRAME
5661 #define CYTHON_TRACING_REUSE_FRAME 0
5666 #include "compile.h"
5667 #include "frameobject.h"
5668 #include "traceback.h"
5670 #if CYTHON_TRACING_REUSE_FRAME
5671 #define CYTHON_FRAME_MODIFIER static
5672 #define CYTHON_FRAME_DEL
5674 #define CYTHON_FRAME_MODIFIER
5675 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
5678 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
5679 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
5680 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
5681 int __Pyx_use_tracing = 0; \\
5682 if (PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5683 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
5686 #define __Pyx_TraceException() \\
5687 if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5688 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
5690 PyThreadState_GET()->c_profilefunc( \\
5691 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
5692 Py_DECREF(exc_info); \\
5696 #define __Pyx_TraceReturn(result) \\
5697 if (__Pyx_use_tracing && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
5698 PyThreadState_GET()->c_profilefunc( \\
5699 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
5700 CYTHON_FRAME_DEL; \\
5703 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5704 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
5707 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
5708 #define __Pyx_TraceException()
5709 #define __Pyx_TraceReturn(result)
5710 #endif /* CYTHON_TRACING */
5713 "FRAME": Naming.frame_cname,
5714 "FRAME_CODE": Naming.frame_code_cname,
5720 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
5721 PyFrameObject** frame,
5722 const char *funcname,
5723 const char *srcfile,
5725 if (*frame == NULL || !CYTHON_TRACING_REUSE_FRAME) {
5726 if (*code == NULL) {
5727 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
5728 if (*code == NULL) return 0;
5730 *frame = PyFrame_New(
5731 PyThreadState_GET(), /*PyThreadState *tstate*/
5732 *code, /*PyCodeObject *code*/
5733 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
5734 0 /*PyObject *locals*/
5736 if (*frame == NULL) return 0;
5739 (*frame)->f_tstate = PyThreadState_GET();
5741 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
5744 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
5745 PyObject *py_srcfile = 0;
5746 PyObject *py_funcname = 0;
5747 PyCodeObject *py_code = 0;
5749 #if PY_MAJOR_VERSION < 3
5750 py_funcname = PyString_FromString(funcname);
5751 py_srcfile = PyString_FromString(srcfile);
5753 py_funcname = PyUnicode_FromString(funcname);
5754 py_srcfile = PyUnicode_FromString(srcfile);
5756 if (!py_funcname | !py_srcfile) goto bad;
5758 py_code = PyCode_New(
5759 0, /*int argcount,*/
5760 #if PY_MAJOR_VERSION >= 3
5761 0, /*int kwonlyargcount,*/
5764 0, /*int stacksize,*/
5766 %(EMPTY_BYTES)s, /*PyObject *code,*/
5767 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5768 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5769 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5770 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5771 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5772 py_srcfile, /*PyObject *filename,*/
5773 py_funcname, /*PyObject *name,*/
5774 firstlineno, /*int firstlineno,*/
5775 %(EMPTY_BYTES)s /*PyObject *lnotab*/
5779 Py_XDECREF(py_srcfile);
5780 Py_XDECREF(py_funcname);
5785 #endif /* CYTHON_TRACING */
5787 'EMPTY_TUPLE' : Naming.empty_tuple,
5788 'EMPTY_BYTES' : Naming.empty_bytes,
5789 "MODULE": Naming.module_cname,