2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
135 def gil_check(self, env):
140 error(self.pos, "%s not allowed without gil" % self.gil_message)
142 def clone_node(self):
143 """Clone the node. This is defined as a shallow copy, except for member lists
144 amongst the child attributes (from get_child_accessors) which are also
145 copied. Lists containing child nodes are thus seen as a way for the node
146 to hold multiple children directly; the list is not treated as a seperate
147 level in the tree."""
148 result = copy.copy(self)
149 for attrname in result.child_attrs:
150 value = getattr(result, attrname)
151 if isinstance(value, list):
152 setattr(result, attrname, [x for x in value])
157 # There are 4 phases of parse tree processing, applied in order to
158 # all the statements in a given scope-block:
160 # (0) analyse_control_flow
161 # Create the control flow tree into which state can be asserted and
164 # (1) analyse_declarations
165 # Make symbol table entries for all declarations at the current
166 # level, both explicit (def, cdef, etc.) and implicit (assignment
167 # to an otherwise undeclared name).
169 # (2) analyse_expressions
170 # Determine the result types of expressions and fill in the
171 # 'type' attribute of each ExprNode. Insert coercion nodes into the
172 # tree where needed to convert to and from Python objects.
173 # Allocate temporary locals for intermediate results. Fill
174 # in the 'result_code' attribute of each ExprNode with a C code
178 # Emit C code for all declarations, statements and expressions.
179 # Recursively applies the 3 processing phases to the bodies of
183 def analyse_control_flow(self, env):
186 def analyse_declarations(self, env):
189 def analyse_expressions(self, env):
190 raise InternalError("analyse_expressions not implemented for %s" % \
191 self.__class__.__name__)
193 def generate_code(self, code):
194 raise InternalError("generate_code not implemented for %s" % \
195 self.__class__.__name__)
197 def annotate(self, code):
198 # mro does the wrong thing
199 if isinstance(self, BlockNode):
200 self.body.annotate(code)
205 except AttributeError:
207 if not self.child_attrs:
210 for attr in self.child_attrs:
211 child = getattr(self, attr)
212 # Sometimes lists, sometimes nodes
215 elif isinstance(child, list):
217 pos = max(pos, c.end_pos())
219 pos = max(pos, child.end_pos())
223 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
225 return "<...nesting level cutoff...>"
226 if encountered is None:
228 if id(self) in encountered:
229 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
230 encountered.add(id(self))
232 def dump_child(x, level):
233 if isinstance(x, Node):
234 return x.dump(level, filter_out, cutoff-1, encountered)
235 elif isinstance(x, list):
236 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
241 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
243 return "<%s (%d)>" % (self.__class__.__name__, id(self))
246 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
247 for key, value in attrs:
248 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
249 res += "%s>" % indent
252 class CompilerDirectivesNode(Node):
254 Sets compiler directives for the children nodes
256 # directives {string:value} A dictionary holding the right value for
257 # *all* possible directives.
259 child_attrs = ["body"]
261 def analyse_control_flow(self, env):
263 env.directives = self.directives
264 self.body.analyse_control_flow(env)
267 def analyse_declarations(self, env):
269 env.directives = self.directives
270 self.body.analyse_declarations(env)
273 def analyse_expressions(self, env):
275 env.directives = self.directives
276 self.body.analyse_expressions(env)
279 def generate_function_definitions(self, env, code):
280 env_old = env.directives
281 code_old = code.globalstate.directives
282 code.globalstate.directives = self.directives
283 self.body.generate_function_definitions(env, code)
284 env.directives = env_old
285 code.globalstate.directives = code_old
287 def generate_execution_code(self, code):
288 old = code.globalstate.directives
289 code.globalstate.directives = self.directives
290 self.body.generate_execution_code(code)
291 code.globalstate.directives = old
293 def annotate(self, code):
294 old = code.globalstate.directives
295 code.globalstate.directives = self.directives
296 self.body.annotate(code)
297 code.globalstate.directives = old
299 class BlockNode(object):
300 # Mixin class for nodes representing a declaration block.
302 def generate_const_definitions(self, env, code):
303 if env.const_entries:
304 for entry in env.const_entries:
305 if not entry.is_interned:
306 code.globalstate.add_const_definition(entry)
308 def generate_interned_string_decls(self, env, code):
309 entries = env.global_scope().new_interned_string_entries
311 for entry in entries:
312 code.globalstate.add_interned_string_decl(entry)
315 def generate_py_string_decls(self, env, code):
317 return # earlier error
318 entries = env.pystring_entries
320 for entry in entries:
321 if not entry.is_interned:
322 code.globalstate.add_py_string_decl(entry)
324 def generate_interned_num_decls(self, env, code):
325 # Flush accumulated interned nums from the global scope
326 # and generate declarations for them.
327 genv = env.global_scope()
328 entries = genv.interned_nums
330 for entry in entries:
331 code.globalstate.add_interned_num_decl(entry)
334 def generate_cached_builtins_decls(self, env, code):
335 entries = env.global_scope().undeclared_cached_builtins
336 for entry in entries:
337 code.globalstate.add_cached_builtin_decl(entry)
341 class StatListNode(Node):
342 # stats a list of StatNode
344 child_attrs = ["stats"]
346 def create_analysed(pos, env, *args, **kw):
347 node = StatListNode(pos, *args, **kw)
348 return node # No node-specific analysis necesarry
349 create_analysed = staticmethod(create_analysed)
351 def analyse_control_flow(self, env):
352 for stat in self.stats:
353 stat.analyse_control_flow(env)
355 def analyse_declarations(self, env):
356 #print "StatListNode.analyse_declarations" ###
357 for stat in self.stats:
358 stat.analyse_declarations(env)
360 def analyse_expressions(self, env):
361 #print "StatListNode.analyse_expressions" ###
362 for stat in self.stats:
363 stat.analyse_expressions(env)
365 def generate_function_definitions(self, env, code):
366 #print "StatListNode.generate_function_definitions" ###
367 for stat in self.stats:
368 stat.generate_function_definitions(env, code)
370 def generate_execution_code(self, code):
371 #print "StatListNode.generate_execution_code" ###
372 for stat in self.stats:
373 code.mark_pos(stat.pos)
374 stat.generate_execution_code(code)
376 def annotate(self, code):
377 for stat in self.stats:
381 class StatNode(Node):
383 # Code generation for statements is split into the following subphases:
385 # (1) generate_function_definitions
386 # Emit C code for the definitions of any structs,
387 # unions, enums and functions defined in the current
390 # (2) generate_execution_code
391 # Emit C code for executable statements.
394 def generate_function_definitions(self, env, code):
397 def generate_execution_code(self, code):
398 raise InternalError("generate_execution_code not implemented for %s" % \
399 self.__class__.__name__)
402 class CDefExternNode(StatNode):
403 # include_file string or None
406 child_attrs = ["body"]
408 def analyse_declarations(self, env):
409 if self.include_file:
410 env.add_include_file(self.include_file)
411 old_cinclude_flag = env.in_cinclude
413 self.body.analyse_declarations(env)
414 env.in_cinclude = old_cinclude_flag
416 def analyse_expressions(self, env):
419 def generate_execution_code(self, code):
422 def annotate(self, code):
423 self.body.annotate(code)
426 class CDeclaratorNode(Node):
427 # Part of a C declaration.
429 # Processing during analyse_declarations phase:
432 # Returns (name, type) pair where name is the
433 # CNameDeclaratorNode of the name being declared
434 # and type is the type it is being declared as.
436 # calling_convention string Calling convention of CFuncDeclaratorNode
437 # for which this is a base
441 calling_convention = ""
444 class CNameDeclaratorNode(CDeclaratorNode):
445 # name string The Pyrex name being declared
446 # cname string or None C name, if specified
447 # default ExprNode or None the value assigned on declaration
449 child_attrs = ['default']
453 def analyse(self, base_type, env, nonempty = 0):
454 if nonempty and self.name == '':
455 # May have mistaken the name for the type.
456 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
457 error(self.pos, "Missing argument name")
458 elif base_type.is_void:
459 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
461 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
462 base_type = py_object_type
463 self.type = base_type
464 return self, base_type
466 class CPtrDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Pointer base type cannot be a Python object")
475 ptr_type = PyrexTypes.c_ptr_type(base_type)
476 return self.base.analyse(ptr_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
486 self.dimension.analyse_const_expression(env)
487 if not self.dimension.type.is_int:
488 error(self.dimension.pos, "Array dimension not integer")
489 size = self.dimension.result()
497 if not base_type.is_complete():
499 "Array element type '%s' is incomplete" % base_type)
500 if base_type.is_pyobject:
502 "Array element cannot be a Python object")
503 if base_type.is_cfunction:
505 "Array element cannot be a function")
506 array_type = PyrexTypes.c_array_type(base_type, size)
507 return self.base.analyse(array_type, env, nonempty = nonempty)
510 class CFuncDeclaratorNode(CDeclaratorNode):
511 # base CDeclaratorNode
512 # args [CArgDeclNode]
513 # has_varargs boolean
514 # exception_value ConstNode
515 # exception_check boolean True if PyErr_Occurred check needed
516 # nogil boolean Can be called without gil
517 # with_gil boolean Acquire gil around function body
519 child_attrs = ["base", "args", "exception_value"]
522 optional_arg_count = 0
524 def analyse(self, return_type, env, nonempty = 0):
528 for arg_node in self.args:
529 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
530 name = name_declarator.name
531 if name_declarator.cname:
533 "Function argument cannot have C name specification")
534 # Turn *[] argument into **
536 type = PyrexTypes.c_ptr_type(type.base_type)
537 # Catch attempted C-style func(void) decl
539 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
540 # if type.is_pyobject and self.nogil:
542 # "Function with Python argument cannot be declared nogil")
543 func_type_args.append(
544 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
546 self.optional_arg_count += 1
547 elif self.optional_arg_count:
548 error(self.pos, "Non-default argument follows default argument")
550 if self.optional_arg_count:
551 scope = StructOrUnionScope()
552 arg_count_member = '%sn' % Naming.pyrex_prefix
553 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
554 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
555 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
556 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
557 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
562 cname = struct_cname)
563 self.op_args_struct.defined_in_pxd = 1
564 self.op_args_struct.used = 1
568 if self.exception_check == '+':
569 env.add_include_file('stdexcept')
570 if return_type.is_pyobject \
571 and (self.exception_value or self.exception_check) \
572 and self.exception_check != '+':
574 "Exception clause not allowed for function returning Python object")
576 if self.exception_value:
577 self.exception_value.analyse_const_expression(env)
578 if self.exception_check == '+':
579 exc_val_type = self.exception_value.type
580 if not exc_val_type.is_error and \
581 not exc_val_type.is_pyobject and \
582 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
583 error(self.exception_value.pos,
584 "Exception value must be a Python exception or cdef function with no arguments.")
585 exc_val = self.exception_value
587 exc_val = self.exception_value.result()
588 if not return_type.assignable_from(self.exception_value.type):
589 error(self.exception_value.pos,
590 "Exception value incompatible with function return type")
591 exc_check = self.exception_check
592 if return_type.is_array:
594 "Function cannot return an array")
595 if return_type.is_cfunction:
597 "Function cannot return a function")
598 func_type = PyrexTypes.CFuncType(
599 return_type, func_type_args, self.has_varargs,
600 optional_arg_count = self.optional_arg_count,
601 exception_value = exc_val, exception_check = exc_check,
602 calling_convention = self.base.calling_convention,
603 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
604 if self.optional_arg_count:
605 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
606 return self.base.analyse(func_type, env)
609 class CArgDeclNode(Node):
610 # Item in a function declaration argument list.
612 # base_type CBaseTypeNode
613 # declarator CDeclaratorNode
614 # not_none boolean Tagged with 'not None'
615 # default ExprNode or None
616 # default_entry Symtab.Entry Entry for the variable holding the default value
617 # default_result_code string cname or code fragment for default value
618 # is_self_arg boolean Is the "self" arg of an extension type method
619 # is_kw_only boolean Is a keyword-only argument
621 child_attrs = ["base_type", "declarator", "default"]
626 name_declarator = None
628 def analyse(self, env, nonempty = 0):
629 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
630 if self.type is None:
631 # The parser may missinterpret names as types...
633 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
635 self.declarator.name = self.base_type.name
636 self.base_type.name = None
637 self.base_type.is_basic_c_type = False
640 could_be_name = False
641 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
642 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
643 self.declarator.name = self.base_type.arg_name
644 return self.declarator.analyse(base_type, env, nonempty = nonempty)
646 return self.name_declarator, self.type
648 def annotate(self, code):
650 self.default.annotate(code)
653 class CBaseTypeNode(Node):
654 # Abstract base class for C base type nodes.
656 # Processing during analyse_declarations phase:
663 class CAnalysedBaseTypeNode(Node):
668 def analyse(self, env, could_be_name = False):
671 class CSimpleBaseTypeNode(CBaseTypeNode):
673 # module_path [string] Qualifying name components
674 # is_basic_c_type boolean
678 # is_self_arg boolean Is self argument of C method
681 arg_name = None # in case the argument name was interpreted as a type
683 def analyse(self, env, could_be_name = False):
684 # Return type descriptor.
685 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
687 if self.is_basic_c_type:
688 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
690 error(self.pos, "Unrecognised type modifier combination")
691 elif self.name == "object" and not self.module_path:
692 type = py_object_type
693 elif self.name is None:
694 if self.is_self_arg and env.is_c_class_scope:
695 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
696 type = env.parent_type
698 type = py_object_type
701 scope = env.find_imported_module(self.module_path, self.pos)
705 if scope.is_c_class_scope:
706 scope = scope.global_scope()
707 entry = scope.lookup(self.name)
708 if entry and entry.is_type:
711 if self.is_self_arg and env.is_c_class_scope:
712 type = env.parent_type
714 type = py_object_type
715 self.arg_name = self.name
717 error(self.pos, "'%s' is not a type identifier" % self.name)
719 if not type.is_numeric or type.is_complex:
720 error(self.pos, "can only complexify c numeric types")
721 type = PyrexTypes.CComplexType(type)
725 return PyrexTypes.error_type
727 class CBufferAccessTypeNode(CBaseTypeNode):
729 # positional_args [ExprNode] List of positional arguments
730 # keyword_args DictNode Keyword arguments
731 # base_type_node CBaseTypeNode
734 # type PyrexType.BufferType ...containing the right options
737 child_attrs = ["base_type_node", "positional_args",
738 "keyword_args", "dtype_node"]
744 def analyse(self, env, could_be_name = False):
745 base_type = self.base_type_node.analyse(env)
746 if base_type.is_error: return base_type
749 options = Buffer.analyse_buffer_options(
752 self.positional_args,
754 base_type.buffer_defaults)
756 self.type = PyrexTypes.BufferType(base_type, **options)
759 class CComplexBaseTypeNode(CBaseTypeNode):
760 # base_type CBaseTypeNode
761 # declarator CDeclaratorNode
763 child_attrs = ["base_type", "declarator"]
765 def analyse(self, env, could_be_name = False):
766 base = self.base_type.analyse(env, could_be_name)
767 _, type = self.declarator.analyse(base, env)
771 class CVarDefNode(StatNode):
772 # C variable definition or forward/extern function declaration.
774 # visibility 'private' or 'public' or 'extern'
775 # base_type CBaseTypeNode
776 # declarators [CDeclaratorNode]
779 # need_properties [entry]
781 # decorators [cython.locals(...)] or None
782 # directive_locals { string : NameNode } locals defined by cython.locals(...)
784 child_attrs = ["base_type", "declarators"]
788 directive_locals = {}
790 def analyse_declarations(self, env, dest_scope = None):
793 self.dest_scope = dest_scope
794 base_type = self.base_type.analyse(env)
795 if (dest_scope.is_c_class_scope
796 and self.visibility == 'public'
797 and base_type.is_pyobject
798 and (base_type.is_builtin_type or base_type.is_extension_type)):
799 self.need_properties = []
801 visibility = 'private'
803 need_property = False
804 visibility = self.visibility
806 for declarator in self.declarators:
807 name_declarator, type = declarator.analyse(base_type, env)
808 if not type.is_complete():
809 if not (self.visibility == 'extern' and type.is_array):
810 error(declarator.pos,
811 "Variable type '%s' is incomplete" % type)
812 if self.visibility == 'extern' and type.is_pyobject:
813 error(declarator.pos,
814 "Python object cannot be declared extern")
815 name = name_declarator.name
816 cname = name_declarator.cname
818 error(declarator.pos, "Missing name in declaration.")
820 if type.is_cfunction:
821 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
822 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
824 if entry is not None:
825 entry.directive_locals = self.directive_locals
827 if self.directive_locals:
828 s.error("Decorators can only be followed by functions")
829 if self.in_pxd and self.visibility != 'extern':
831 "Only 'extern' C variable declaration allowed in .pxd file")
832 entry = dest_scope.declare_var(name, type, declarator.pos,
833 cname = cname, visibility = visibility, is_cdef = 1)
835 self.need_properties.append(entry)
836 entry.needs_property = 1
839 class CStructOrUnionDefNode(StatNode):
841 # cname string or None
842 # kind "struct" or "union"
843 # typedef_flag boolean
844 # visibility "public" or "private"
846 # attributes [CVarDefNode] or None
850 child_attrs = ["attributes"]
852 def analyse_declarations(self, env):
854 if self.visibility == 'extern' and self.packed:
855 error(self.pos, "Cannot declare extern struct as 'packed'")
856 if self.attributes is not None:
857 scope = StructOrUnionScope(self.name)
858 self.entry = env.declare_struct_or_union(
859 self.name, self.kind, scope, self.typedef_flag, self.pos,
860 self.cname, visibility = self.visibility, packed = self.packed)
861 if self.attributes is not None:
862 if self.in_pxd and not env.in_cinclude:
863 self.entry.defined_in_pxd = 1
864 for attr in self.attributes:
865 attr.analyse_declarations(env, scope)
866 if self.visibility != 'extern':
867 need_typedef_indirection = False
868 for attr in scope.var_entries:
871 type = type.base_type
872 if type == self.entry.type:
873 error(attr.pos, "Struct cannot contain itself as a member.")
874 if self.typedef_flag:
876 type = type.base_type
877 if type == self.entry.type:
878 need_typedef_indirection = True
879 if need_typedef_indirection:
880 # C can't handle typedef structs that refer to themselves.
881 struct_entry = self.entry
882 cname = env.new_const_cname()
883 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
884 struct_entry.type.typedef_flag = False
885 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
887 def analyse_expressions(self, env):
890 def generate_execution_code(self, code):
894 class CEnumDefNode(StatNode):
895 # name string or None
896 # cname string or None
897 # items [CEnumDefItemNode]
898 # typedef_flag boolean
899 # visibility "public" or "private"
903 child_attrs = ["items"]
905 def analyse_declarations(self, env):
906 self.entry = env.declare_enum(self.name, self.pos,
907 cname = self.cname, typedef_flag = self.typedef_flag,
908 visibility = self.visibility)
909 if self.items is not None:
910 if self.in_pxd and not env.in_cinclude:
911 self.entry.defined_in_pxd = 1
912 for item in self.items:
913 item.analyse_declarations(env, self.entry)
915 def analyse_expressions(self, env):
916 if self.visibility == 'public':
917 self.temp = env.allocate_temp_pyobject()
918 env.release_temp(self.temp)
920 def generate_execution_code(self, code):
921 if self.visibility == 'public':
922 for item in self.entry.enum_values:
923 code.putln("%s = PyInt_FromLong(%s); %s" % (
926 code.error_goto_if_null(self.temp, item.pos)))
927 code.put_gotref(self.temp)
928 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
932 code.error_goto(item.pos)))
933 code.put_decref_clear(self.temp, PyrexTypes.py_object_type)
936 class CEnumDefItemNode(StatNode):
938 # cname string or None
939 # value ExprNode or None
941 child_attrs = ["value"]
943 def analyse_declarations(self, env, enum_entry):
945 self.value.analyse_const_expression(env)
946 if not self.value.type.is_int:
947 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
948 self.value.analyse_const_expression(env)
949 value = self.value.result()
952 entry = env.declare_const(self.name, enum_entry.type,
953 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
954 enum_entry.enum_values.append(entry)
957 class CTypeDefNode(StatNode):
958 # base_type CBaseTypeNode
959 # declarator CDeclaratorNode
960 # visibility "public" or "private"
963 child_attrs = ["base_type", "declarator"]
965 def analyse_declarations(self, env):
966 base = self.base_type.analyse(env)
967 name_declarator, type = self.declarator.analyse(base, env)
968 name = name_declarator.name
969 cname = name_declarator.cname
970 entry = env.declare_typedef(name, type, self.pos,
971 cname = cname, visibility = self.visibility)
972 if self.in_pxd and not env.in_cinclude:
973 entry.defined_in_pxd = 1
975 def analyse_expressions(self, env):
977 def generate_execution_code(self, code):
981 class FuncDefNode(StatNode, BlockNode):
982 # Base class for function definition nodes.
984 # return_type PyrexType
985 # #filename string C name of filename string const
987 # needs_closure boolean Whether or not this function has inner functions/classes/yield
988 # directive_locals { string : NameNode } locals defined by cython.locals(...)
992 needs_closure = False
994 def analyse_default_values(self, env):
995 genv = env.global_scope()
996 for arg in self.args:
999 if not hasattr(arg, 'default_entry'):
1000 arg.default.analyse_types(env)
1001 arg.default = arg.default.coerce_to(arg.type, genv)
1002 if arg.default.is_literal:
1003 arg.default_entry = arg.default
1004 arg.default_result_code = arg.default.calculate_result_code()
1005 if arg.default.type != arg.type and not arg.type.is_int:
1006 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1008 arg.default.allocate_temps(genv)
1009 arg.default_entry = genv.add_default_value(arg.type)
1010 if arg.type.is_pyobject:
1011 arg.default_entry.init = 0
1012 arg.default_entry.used = 1
1013 arg.default_result_code = arg.default_entry.cname
1016 "This argument cannot have a default value")
1019 def need_gil_acquisition(self, lenv):
1022 def create_local_scope(self, env):
1024 while env.is_py_class_scope or env.is_c_class_scope:
1025 env = env.outer_scope
1026 if self.needs_closure:
1027 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1029 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1030 lenv.return_type = self.return_type
1031 type = self.entry.type
1032 if type.is_cfunction:
1033 lenv.nogil = type.nogil and not type.with_gil
1034 self.local_scope = lenv
1035 lenv.directives = env.directives
1038 def generate_function_definitions(self, env, code):
1041 lenv = self.local_scope
1043 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1044 self.entry.scope.is_c_class_scope)
1046 # Generate C code for header and body of function
1047 code.enter_cfunc_scope()
1048 code.return_from_error_cleanup_label = code.new_label()
1050 # ----- Top-level constants used by this function
1051 code.mark_pos(self.pos)
1052 self.generate_interned_num_decls(lenv, code)
1053 self.generate_interned_string_decls(lenv, code)
1054 self.generate_py_string_decls(lenv, code)
1055 self.generate_cached_builtins_decls(lenv, code)
1057 #code.put_var_declarations(lenv.const_entries, static = 1)
1058 self.generate_const_definitions(lenv, code)
1059 # ----- Function header
1062 self.py_func.generate_function_header(code,
1063 with_pymethdef = env.is_py_class_scope,
1065 self.generate_function_header(code,
1066 with_pymethdef = env.is_py_class_scope)
1067 # ----- Local variable declarations
1068 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1069 self.generate_argument_declarations(lenv, code)
1070 if self.needs_closure:
1071 code.putln("/* TODO: declare and create scope object */")
1072 code.put_var_declarations(lenv.var_entries)
1074 if not self.return_type.is_void:
1075 if self.return_type.is_pyobject:
1079 (self.return_type.declaration_code(
1080 Naming.retval_cname),
1082 tempvardecl_code = code.insertion_point()
1083 self.generate_keyword_list(code)
1084 # ----- Extern library function declarations
1085 lenv.generate_library_function_declarations(code)
1086 # ----- GIL acquisition
1087 acquire_gil = self.need_gil_acquisition(lenv)
1089 env.use_utility_code(force_init_threads_utility_code)
1090 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1091 # ----- Automatic lead-ins for certain special functions
1093 code.put_setup_refcount_context(self.entry.name)
1094 if is_getbuffer_slot:
1095 self.getbuffer_init(code)
1096 # ----- Fetch arguments
1097 self.generate_argument_parsing_code(env, code)
1098 # If an argument is assigned to in the body, we must
1099 # incref it to properly keep track of refcounts.
1100 for entry in lenv.arg_entries:
1101 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1102 code.put_var_incref(entry)
1103 # ----- Initialise local variables
1104 for entry in lenv.var_entries:
1105 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1106 code.put_init_var_to_py_none(entry)
1107 # ----- Initialise local buffer auxiliary variables
1108 for entry in lenv.var_entries + lenv.arg_entries:
1109 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1110 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1111 # ----- Check and convert arguments
1112 self.generate_argument_type_tests(code)
1113 # ----- Acquire buffer arguments
1114 for entry in lenv.arg_entries:
1115 if entry.type.is_buffer:
1116 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1117 # ----- Function body
1118 self.body.generate_execution_code(code)
1119 # ----- Default return value
1121 if self.return_type.is_pyobject:
1122 #if self.return_type.is_extension_type:
1123 # lhs = "(PyObject *)%s" % Naming.retval_cname
1125 lhs = Naming.retval_cname
1126 code.put_init_to_py_none(lhs, self.return_type)
1128 val = self.return_type.default_value
1130 code.putln("%s = %s;" % (Naming.retval_cname, val))
1131 # ----- Error cleanup
1132 if code.error_label in code.labels_used:
1133 code.put_goto(code.return_label)
1134 code.put_label(code.error_label)
1135 # cleanup temps the old way
1136 code.put_var_xdecrefs(lenv.temp_entries)
1137 # cleanup temps the new way
1138 for cname, type in code.funcstate.all_managed_temps():
1139 code.put_xdecref(cname, type)
1141 # Clean up buffers -- this calls a Python function
1142 # so need to save and restore error state
1143 buffers_present = len(lenv.buffer_entries) > 0
1145 code.globalstate.use_utility_code(restore_exception_utility_code)
1146 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1147 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1148 for entry in lenv.buffer_entries:
1149 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1150 #code.putln("%s = 0;" % entry.cname)
1151 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1153 err_val = self.error_value()
1154 exc_check = self.caller_will_check_exceptions()
1155 if err_val is not None or exc_check:
1156 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1158 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1159 % self.entry.qualified_name, 0)
1161 '__Pyx_WriteUnraisable("%s");' %
1162 self.entry.qualified_name)
1163 env.use_utility_code(unraisable_exception_utility_code)
1164 env.use_utility_code(restore_exception_utility_code)
1165 default_retval = self.return_type.default_value
1166 if err_val is None and default_retval:
1167 err_val = default_retval
1168 if err_val is not None:
1171 Naming.retval_cname,
1174 if is_getbuffer_slot:
1175 self.getbuffer_error_cleanup(code)
1177 # If we are using the non-error cleanup section we should
1178 # jump past it if we have an error. The if-test below determine
1179 # whether this section is used.
1180 if buffers_present or is_getbuffer_slot:
1181 code.put_goto(code.return_from_error_cleanup_label)
1184 # ----- Non-error return cleanup
1185 # If you add anything here, remember to add a condition to the
1186 # if-test above in the error block (so that it can jump past this
1188 code.put_label(code.return_label)
1189 for entry in lenv.buffer_entries:
1191 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1192 if is_getbuffer_slot:
1193 self.getbuffer_normal_cleanup(code)
1194 # ----- Return cleanup for both error and no-error return
1195 code.put_label(code.return_from_error_cleanup_label)
1196 if not Options.init_local_none:
1197 for entry in lenv.var_entries:
1198 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1199 entry.xdecref_cleanup = 1
1200 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1201 # Decref any increfed args
1202 for entry in lenv.arg_entries:
1203 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1204 code.put_var_decref(entry)
1206 # code.putln("/* TODO: decref scope object */")
1208 # This code is duplicated in ModuleNode.generate_module_init_func
1210 default_retval = self.return_type.default_value
1211 err_val = self.error_value()
1212 if err_val is None and default_retval:
1213 err_val = default_retval
1214 if self.return_type.is_pyobject:
1215 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1217 code.put_finish_refcount_context()
1220 code.putln("PyGILState_Release(_save);")
1222 if not self.return_type.is_void:
1223 code.putln("return %s;" % Naming.retval_cname)
1226 # ----- Go back and insert temp variable declarations
1227 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1228 tempvardecl_code.put_temp_declarations(code.funcstate)
1229 # ----- Python version
1230 code.exit_cfunc_scope()
1232 self.py_func.generate_function_definitions(env, code)
1233 self.generate_wrapper_functions(code)
1235 def declare_argument(self, env, arg):
1236 if arg.type.is_void:
1237 error(arg.pos, "Invalid use of 'void'")
1238 elif not arg.type.is_complete() and not arg.type.is_array:
1240 "Argument type '%s' is incomplete" % arg.type)
1241 return env.declare_arg(arg.name, arg.type, arg.pos)
1243 def generate_wrapper_functions(self, code):
1246 def generate_execution_code(self, code):
1247 # Evaluate and store argument default values
1248 for arg in self.args:
1249 default = arg.default
1251 if not default.is_literal:
1252 default.generate_evaluation_code(code)
1253 default.make_owned_reference(code)
1256 arg.default_entry.cname,
1257 default.result_as(arg.default_entry.type)))
1258 if default.is_temp and default.type.is_pyobject:
1259 code.putln("%s = 0;" % default.result())
1260 default.free_temps(code)
1261 code.put_var_giveref(arg.default_entry)
1262 # For Python class methods, create and store function object
1264 self.assmt.generate_execution_code(code)
1267 # Special code for the __getbuffer__ function
1269 def getbuffer_init(self, code):
1270 info = self.local_scope.arg_entries[1].cname
1271 # Python 3.0 betas have a bug in memoryview which makes it call
1272 # getbuffer with a NULL parameter. For now we work around this;
1273 # the following line should be removed when this bug is fixed.
1274 code.putln("if (%s == NULL) return 0;" % info)
1275 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1276 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1278 def getbuffer_error_cleanup(self, code):
1279 info = self.local_scope.arg_entries[1].cname
1280 code.put_gotref("%s->obj" % info)
1281 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1284 def getbuffer_normal_cleanup(self, code):
1285 info = self.local_scope.arg_entries[1].cname
1286 code.putln("if (%s->obj == Py_None) {" % info)
1287 code.put_gotref("Py_None")
1288 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1291 class CFuncDefNode(FuncDefNode):
1292 # C function definition.
1294 # modifiers ['inline']
1295 # visibility 'private' or 'public' or 'extern'
1296 # base_type CBaseTypeNode
1297 # declarator CDeclaratorNode
1300 # decorators [DecoratorNode] list of decorators
1302 # with_gil boolean Acquire GIL around body
1304 # py_func wrapper for calling from Python
1305 # overridable whether or not this is a cpdef function
1306 # inline_in_pxd whether this is an inline function in a pxd file
1308 child_attrs = ["base_type", "declarator", "body", "py_func"]
1310 inline_in_pxd = False
1312 directive_locals = {}
1314 def unqualified_name(self):
1315 return self.entry.name
1317 def analyse_declarations(self, env):
1318 directive_locals = self.directive_locals = env.directives['locals']
1319 base_type = self.base_type.analyse(env)
1320 # The 2 here is because we need both function and argument names.
1321 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1322 if not type.is_cfunction:
1324 "Suite attached to non-function declaration")
1325 # Remember the actual type according to the function header
1326 # written here, because the type in the symbol table entry
1327 # may be different if we're overriding a C method inherited
1328 # from the base type of an extension type.
1330 type.is_overridable = self.overridable
1331 declarator = self.declarator
1332 while not hasattr(declarator, 'args'):
1333 declarator = declarator.base
1334 self.args = declarator.args
1335 for formal_arg, type_arg in zip(self.args, type.args):
1336 formal_arg.type = type_arg.type
1337 formal_arg.name = type_arg.name
1338 formal_arg.cname = type_arg.cname
1339 name = name_declarator.name
1340 cname = name_declarator.cname
1341 self.entry = env.declare_cfunction(
1342 name, type, self.pos,
1343 cname = cname, visibility = self.visibility,
1344 defining = self.body is not None,
1345 api = self.api, modifiers = self.modifiers)
1346 self.entry.inline_func_in_pxd = self.inline_in_pxd
1347 self.return_type = type.return_type
1349 if self.overridable and not env.is_module_scope:
1350 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1351 # An error will be produced in the cdef function
1352 self.overridable = False
1354 if self.overridable:
1356 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1357 self.py_func = DefNode(pos = self.pos,
1358 name = self.entry.name,
1361 starstar_arg = None,
1363 body = py_func_body,
1365 self.py_func.is_module_scope = env.is_module_scope
1366 self.py_func.analyse_declarations(env)
1367 self.entry.as_variable = self.py_func.entry
1368 # Reset scope entry the above cfunction
1369 env.entries[name] = self.entry
1370 self.py_func.interned_attr_cname = env.intern_identifier(
1371 self.py_func.entry.name)
1372 if not env.is_module_scope or Options.lookup_module_cpdef:
1373 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1374 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1376 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1378 args = self.type.args
1379 if omit_optional_args:
1380 args = args[:len(args) - self.type.optional_arg_count]
1381 arg_names = [arg.name for arg in args]
1383 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1385 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1386 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1387 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1388 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)
1389 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1391 def declare_arguments(self, env):
1392 for arg in self.type.args:
1394 error(arg.pos, "Missing argument name")
1395 self.declare_argument(env, arg)
1397 def need_gil_acquisition(self, lenv):
1399 with_gil = self.type.with_gil
1400 if type.nogil and not with_gil:
1401 if type.return_type.is_pyobject:
1403 "Function with Python return type cannot be declared nogil")
1404 for entry in lenv.var_entries + lenv.temp_entries:
1405 if entry.type.is_pyobject:
1406 error(self.pos, "Function declared nogil has Python locals or temporaries")
1409 def analyse_expressions(self, env):
1410 self.local_scope.directives = env.directives
1411 self.analyse_default_values(env)
1412 if self.py_func is not None:
1413 self.py_func.analyse_expressions(env)
1415 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1418 visibility = self.entry.visibility
1419 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1420 arg_decls.append(arg.declaration_code())
1421 if with_dispatch and self.overridable:
1422 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1423 if type.optional_arg_count and with_opt_args:
1424 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1425 if type.has_varargs:
1426 arg_decls.append("...")
1428 arg_decls = ["void"]
1430 cname = self.entry.func_cname
1431 entity = type.function_header_code(cname, ', '.join(arg_decls))
1432 if visibility == 'public':
1433 dll_linkage = "DL_EXPORT"
1436 header = self.return_type.declaration_code(entity,
1437 dll_linkage = dll_linkage)
1438 if visibility == 'extern':
1439 storage_class = "%s " % Naming.extern_c_macro
1440 elif visibility == 'public':
1443 storage_class = "static "
1444 code.putln("%s%s %s {" % (
1446 ' '.join(self.modifiers).upper(), # macro forms
1449 def generate_argument_declarations(self, env, code):
1450 for arg in self.args:
1452 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1454 def generate_keyword_list(self, code):
1457 def generate_argument_parsing_code(self, env, code):
1459 if self.type.optional_arg_count:
1460 code.putln('if (%s) {' % Naming.optional_args_cname)
1461 for arg in self.args:
1463 # FIXME: simple name prefixing doesn't work when
1464 # argument name mangling is in place
1465 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1466 declarator = arg.declarator
1467 while not hasattr(declarator, 'name'):
1468 declarator = declarator.base
1469 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1471 for _ in range(self.type.optional_arg_count):
1475 def generate_argument_conversion_code(self, code):
1478 def generate_argument_type_tests(self, code):
1479 # Generate type tests for args whose type in a parent
1480 # class is a supertype of the declared type.
1481 for arg in self.type.args:
1482 if arg.needs_type_test:
1483 self.generate_arg_type_test(arg, code)
1485 def generate_arg_type_test(self, arg, code):
1486 # Generate type test for one argument.
1487 if arg.type.typeobj_is_available():
1488 typeptr_cname = arg.type.typeptr_cname
1489 arg_code = "((PyObject *)%s)" % arg.cname
1491 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1496 type.is_builtin_type,
1497 code.error_goto(arg.pos)))
1499 error(arg.pos, "Cannot test type of extern C class "
1500 "without type object name specification")
1502 def error_value(self):
1503 if self.return_type.is_pyobject:
1507 return self.entry.type.exception_value
1509 def caller_will_check_exceptions(self):
1510 return self.entry.type.exception_check
1512 def generate_wrapper_functions(self, code):
1513 # If the C signature of a function has changed, we need to generate
1514 # wrappers to put in the slots here.
1517 func_type = entry.type
1518 while entry.prev_entry is not None:
1520 entry = entry.prev_entry
1521 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1523 self.generate_function_header(code,
1525 with_dispatch = entry.type.is_overridable,
1526 with_opt_args = entry.type.optional_arg_count,
1527 cname = entry.func_cname)
1528 if not self.return_type.is_void:
1530 args = self.type.args
1531 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1532 if entry.type.is_overridable:
1533 arglist.append(Naming.skip_dispatch_cname)
1534 elif func_type.is_overridable:
1536 if entry.type.optional_arg_count:
1537 arglist.append(Naming.optional_args_cname)
1538 elif func_type.optional_arg_count:
1539 arglist.append('NULL')
1540 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1544 class PyArgDeclNode(Node):
1545 # Argument which must be a Python object (used
1546 # for * and ** arguments).
1549 # entry Symtab.Entry
1553 class DecoratorNode(Node):
1556 # decorator NameNode or CallNode
1557 child_attrs = ['decorator']
1560 class DefNode(FuncDefNode):
1561 # A Python function definition.
1563 # name string the Python name of the function
1564 # decorators [DecoratorNode] list of decorators
1565 # args [CArgDeclNode] formal arguments
1566 # star_arg PyArgDeclNode or None * argument
1567 # starstar_arg PyArgDeclNode or None ** argument
1568 # doc EncodedString or None
1571 # The following subnode is constructed internally
1572 # when the def statement is inside a Python class definition.
1574 # assmt AssignmentNode Function construction/assignment
1576 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1580 num_required_kw_args = 0
1581 reqd_kw_flags_cname = "0"
1587 def __init__(self, pos, **kwds):
1588 FuncDefNode.__init__(self, pos, **kwds)
1590 for arg in self.args:
1597 self.num_kwonly_args = k
1598 self.num_required_kw_args = rk
1599 self.num_required_args = r
1601 def as_cfunction(self, cfunc=None, scope=None):
1603 error(self.star_arg.pos, "cdef function cannot have star argument")
1604 if self.starstar_arg:
1605 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1608 for formal_arg in self.args:
1609 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1610 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1612 type = py_object_type,
1613 pos = formal_arg.pos))
1614 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1616 has_varargs = False,
1617 exception_value = None,
1618 exception_check = False,
1621 is_overridable = True)
1622 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1624 cfunc_type = cfunc.type
1625 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1626 error(self.pos, "wrong number of arguments")
1627 error(declarator.pos, "previous declaration here")
1628 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1629 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1630 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1631 formal_arg.type = type_arg.type
1632 formal_arg.name_declarator = name_declarator
1634 if cfunc_type.exception_value is None:
1635 exception_value = None
1637 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1638 declarator = CFuncDeclaratorNode(self.pos,
1639 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1641 has_varargs = False,
1642 exception_check = cfunc_type.exception_check,
1643 exception_value = exception_value,
1644 with_gil = cfunc_type.with_gil,
1645 nogil = cfunc_type.nogil)
1646 return CFuncDefNode(self.pos,
1648 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1649 declarator = declarator,
1652 overridable = cfunc_type.is_overridable,
1654 with_gil = cfunc_type.with_gil,
1655 nogil = cfunc_type.nogil,
1656 visibility = 'private',
1658 directive_locals = getattr(cfunc, 'directive_locals', {}))
1660 def analyse_declarations(self, env):
1661 directive_locals = self.directive_locals = env.directives['locals']
1662 for arg in self.args:
1663 if hasattr(arg, 'name'):
1665 name_declarator = None
1667 base_type = arg.base_type.analyse(env)
1668 name_declarator, type = \
1669 arg.declarator.analyse(base_type, env)
1670 arg.name = name_declarator.name
1671 if arg.name in directive_locals:
1672 type_node = directive_locals[arg.name]
1673 other_type = type_node.analyse_as_type(env)
1674 if other_type is None:
1675 error(type_node.pos, "Not a type")
1676 elif (type is not PyrexTypes.py_object_type
1677 and not type.same_as(other_type)):
1678 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1679 error(type_node.pos, "Previous declaration here")
1682 if name_declarator and name_declarator.cname:
1684 "Python function argument cannot have C name specification")
1685 arg.type = type.as_argument_type()
1687 arg.needs_conversion = 0
1688 arg.needs_type_test = 0
1690 if arg.not_none and not arg.type.is_extension_type:
1692 "Only extension type arguments can have 'not None'")
1693 self.declare_pyfunction(env)
1694 self.analyse_signature(env)
1695 self.return_type = self.entry.signature.return_type()
1697 def analyse_signature(self, env):
1698 any_type_tests_needed = 0
1699 if self.entry.is_special:
1700 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1701 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1702 # Use the simpler calling signature for zero- and one-argument functions.
1703 if self.entry.signature is TypeSlots.pyfunction_signature:
1704 if len(self.args) == 0:
1705 self.entry.signature = TypeSlots.pyfunction_noargs
1706 elif len(self.args) == 1:
1707 if self.args[0].default is None and not self.args[0].kw_only:
1708 self.entry.signature = TypeSlots.pyfunction_onearg
1709 elif self.entry.signature is TypeSlots.pymethod_signature:
1710 if len(self.args) == 1:
1711 self.entry.signature = TypeSlots.unaryfunc
1712 elif len(self.args) == 2:
1713 if self.args[1].default is None and not self.args[1].kw_only:
1714 self.entry.signature = TypeSlots.ibinaryfunc
1715 sig = self.entry.signature
1716 nfixed = sig.num_fixed_args()
1717 for i in range(nfixed):
1718 if i < len(self.args):
1721 if sig.is_self_arg(i):
1723 arg.hdr_type = arg.type = env.parent_type
1724 arg.needs_conversion = 0
1726 arg.hdr_type = sig.fixed_arg_type(i)
1727 if not arg.type.same_as(arg.hdr_type):
1728 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1729 arg.needs_type_test = 1
1730 any_type_tests_needed = 1
1732 arg.needs_conversion = 1
1733 if arg.needs_conversion:
1734 arg.hdr_cname = Naming.arg_prefix + arg.name
1736 arg.hdr_cname = Naming.var_prefix + arg.name
1738 self.bad_signature()
1740 if nfixed < len(self.args):
1741 if not sig.has_generic_args:
1742 self.bad_signature()
1743 for arg in self.args:
1744 if arg.is_generic and \
1745 (arg.type.is_extension_type or arg.type.is_builtin_type):
1746 arg.needs_type_test = 1
1747 any_type_tests_needed = 1
1748 if any_type_tests_needed:
1749 env.use_utility_code(arg_type_test_utility_code)
1751 def bad_signature(self):
1752 sig = self.entry.signature
1753 expected_str = "%d" % sig.num_fixed_args()
1754 if sig.has_generic_args:
1755 expected_str = expected_str + " or more"
1757 if name.startswith("__") and name.endswith("__"):
1758 desc = "Special method"
1762 "%s %s has wrong number of arguments "
1763 "(%d declared, %s expected)" % (
1764 desc, self.name, len(self.args), expected_str))
1766 def signature_has_nongeneric_args(self):
1767 argcount = len(self.args)
1768 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1772 def signature_has_generic_args(self):
1773 return self.entry.signature.has_generic_args
1775 def declare_pyfunction(self, env):
1776 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1778 entry = env.lookup_here(self.name)
1779 if entry and entry.type.is_cfunction and not self.is_wrapper:
1780 warning(self.pos, "Overriding cdef method with def method.", 5)
1781 entry = env.declare_pyfunction(self.name, self.pos)
1783 prefix = env.scope_prefix
1784 entry.func_cname = \
1785 Naming.pyfunc_prefix + prefix + name
1786 entry.pymethdef_cname = \
1787 Naming.pymethdef_prefix + prefix + name
1788 if Options.docstrings:
1789 entry.doc = embed_position(self.pos, self.doc)
1791 Naming.funcdoc_prefix + prefix + name
1795 def declare_arguments(self, env):
1796 for arg in self.args:
1798 error(arg.pos, "Missing argument name")
1799 if arg.needs_conversion:
1800 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1801 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1802 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1803 if arg.type.is_pyobject:
1804 arg.entry.init = "0"
1805 arg.entry.init_to_none = 0
1807 arg.entry = self.declare_argument(env, arg)
1809 arg.entry.is_self_arg = arg.is_self_arg
1810 if not arg.is_self_arg:
1811 arg.name_entry = env.get_string_const(
1812 arg.name, identifier = True)
1813 env.add_py_string(arg.name_entry, identifier = True)
1815 if arg.is_self_arg or \
1816 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1817 arg.entry.is_declared_generic = 1
1818 self.declare_python_arg(env, self.star_arg)
1819 self.declare_python_arg(env, self.starstar_arg)
1821 def declare_python_arg(self, env, arg):
1823 entry = env.declare_var(arg.name,
1824 PyrexTypes.py_object_type, arg.pos)
1827 entry.init_to_none = 0
1828 entry.xdecref_cleanup = 1
1830 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1832 def analyse_expressions(self, env):
1833 self.local_scope.directives = env.directives
1834 self.analyse_default_values(env)
1835 if env.is_py_class_scope:
1836 self.synthesize_assignment_node(env)
1838 def synthesize_assignment_node(self, env):
1840 self.assmt = SingleAssignmentNode(self.pos,
1841 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1842 rhs = ExprNodes.UnboundMethodNode(self.pos,
1843 class_cname = env.class_obj_cname,
1844 function = ExprNodes.PyCFunctionNode(self.pos,
1845 pymethdef_cname = self.entry.pymethdef_cname)))
1846 self.assmt.analyse_declarations(env)
1847 self.assmt.analyse_expressions(env)
1849 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1851 sig = self.entry.signature
1852 if sig.has_dummy_arg:
1853 arg_code_list.append(
1854 "PyObject *%s" % Naming.self_cname)
1855 for arg in self.args:
1856 if not arg.is_generic:
1858 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1860 arg_code_list.append(
1861 arg.hdr_type.declaration_code(arg.hdr_cname))
1862 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1863 arg_code_list.append("PyObject *unused")
1864 if sig.has_generic_args:
1865 arg_code_list.append(
1866 "PyObject *%s, PyObject *%s"
1867 % (Naming.args_cname, Naming.kwds_cname))
1868 arg_code = ", ".join(arg_code_list)
1869 dc = self.return_type.declaration_code(self.entry.func_cname)
1870 header = "static %s(%s)" % (dc, arg_code)
1871 code.putln("%s; /*proto*/" % header)
1874 if self.entry.doc and Options.docstrings:
1875 docstr = self.entry.doc
1876 if not isinstance(docstr, str):
1877 docstr = docstr.utf8encode()
1879 'static char %s[] = "%s";' % (
1880 self.entry.doc_cname,
1881 split_docstring(escape_byte_string(docstr))))
1884 "static PyMethodDef %s = " %
1885 self.entry.pymethdef_cname)
1886 code.put_pymethoddef(self.entry, ";")
1887 code.putln("%s {" % header)
1889 def generate_argument_declarations(self, env, code):
1890 for arg in self.args:
1891 if arg.is_generic: # or arg.needs_conversion:
1892 if arg.needs_conversion:
1893 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1895 code.put_var_declaration(arg.entry)
1897 def generate_keyword_list(self, code):
1898 if self.signature_has_generic_args() and \
1899 self.signature_has_nongeneric_args():
1901 "static PyObject **%s[] = {" %
1902 Naming.pykwdlist_cname)
1903 for arg in self.args:
1905 code.put('&%s,' % arg.name_entry.pystring_cname)
1908 def generate_argument_parsing_code(self, env, code):
1909 # Generate PyArg_ParseTuple call for generic
1910 # arguments, if any.
1911 if self.entry.signature.has_dummy_arg:
1912 # get rid of unused argument warning
1913 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1915 old_error_label = code.new_error_label()
1916 our_error_label = code.error_label
1917 end_label = code.new_label("argument_unpacking_done")
1919 has_kwonly_args = self.num_kwonly_args > 0
1920 has_star_or_kw_args = self.star_arg is not None \
1921 or self.starstar_arg is not None or has_kwonly_args
1923 if not self.signature_has_generic_args():
1924 if has_star_or_kw_args:
1925 error(self.pos, "This method cannot have * or keyword arguments")
1926 self.generate_argument_conversion_code(code)
1928 elif not self.signature_has_nongeneric_args():
1929 # func(*args) or func(**kw) or func(*args, **kw)
1930 self.generate_stararg_copy_code(code)
1933 positional_args = []
1936 for arg in self.args:
1937 arg_entry = arg.entry
1941 if not arg.is_self_arg:
1943 kw_only_args.append(arg)
1945 positional_args.append(arg)
1947 kw_only_args.append(arg)
1950 error(arg.pos, "Non-default argument following default argument")
1951 elif not arg.is_self_arg:
1952 positional_args.append(arg)
1954 self.generate_tuple_and_keyword_parsing_code(
1955 positional_args, kw_only_args, end_label, code)
1957 code.error_label = old_error_label
1958 if code.label_used(our_error_label):
1959 if not code.label_used(end_label):
1960 code.put_goto(end_label)
1961 code.put_label(our_error_label)
1962 if has_star_or_kw_args:
1963 self.generate_arg_decref(self.star_arg, code)
1964 if self.starstar_arg:
1965 if self.starstar_arg.entry.xdecref_cleanup:
1966 code.put_var_xdecref(self.starstar_arg.entry)
1968 code.put_var_decref(self.starstar_arg.entry)
1969 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1970 code.putln("return %s;" % self.error_value())
1971 if code.label_used(end_label):
1972 code.put_label(end_label)
1974 def generate_arg_assignment(self, arg, item, code):
1975 if arg.type.is_pyobject:
1977 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1978 code.putln("%s = %s;" % (arg.entry.cname, item))
1980 func = arg.type.from_py_function
1982 code.putln("%s = %s(%s); %s" % (
1986 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1988 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1990 def generate_arg_xdecref(self, arg, code):
1992 code.put_var_xdecref(arg.entry)
1994 def generate_arg_decref(self, arg, code):
1996 code.put_var_decref(arg.entry)
1998 def generate_stararg_copy_code(self, code):
1999 if not self.star_arg:
2000 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2001 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2003 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2004 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2007 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2009 if self.starstar_arg:
2011 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2013 kwarg_check = "%s" % Naming.kwds_cname
2015 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2016 Naming.kwds_cname, Naming.kwds_cname)
2018 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2019 kwarg_check, Naming.kwds_cname, self.name,
2020 bool(self.starstar_arg), self.error_value()))
2022 if self.starstar_arg:
2023 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2024 self.starstar_arg.entry.cname,
2027 code.putln("if (unlikely(!%s)) return %s;" % (
2028 self.starstar_arg.entry.cname, self.error_value()))
2029 self.starstar_arg.entry.xdecref_cleanup = 0
2030 code.put_gotref(self.starstar_arg.entry.cname)
2034 code.put_incref(Naming.args_cname, py_object_type)
2035 code.putln("%s = %s;" % (
2036 self.star_arg.entry.cname,
2038 self.star_arg.entry.xdecref_cleanup = 0
2040 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2041 kw_only_args, success_label, code):
2042 argtuple_error_label = code.new_label("argtuple_error")
2044 min_positional_args = self.num_required_args - self.num_required_kw_args
2045 if len(self.args) > 0 and self.args[0].is_self_arg:
2046 min_positional_args -= 1
2047 max_positional_args = len(positional_args)
2048 has_fixed_positional_count = not self.star_arg and \
2049 min_positional_args == max_positional_args
2051 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2052 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2053 if self.num_required_kw_args:
2054 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2056 if self.starstar_arg or self.star_arg:
2057 self.generate_stararg_init_code(max_positional_args, code)
2059 # --- optimised code when we receive keyword arguments
2060 if self.num_required_kw_args:
2061 likely_hint = "likely"
2063 likely_hint = "unlikely"
2064 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2065 self.generate_keyword_unpacking_code(
2066 min_positional_args, max_positional_args,
2067 has_fixed_positional_count,
2068 positional_args, kw_only_args, argtuple_error_label, code)
2070 # --- optimised code when we do not receive any keyword arguments
2071 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2072 # Python raises arg tuple related errors first, so we must
2073 # check the length here
2074 if min_positional_args == max_positional_args and not self.star_arg:
2078 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2079 Naming.args_cname, compare, min_positional_args))
2080 code.put_goto(argtuple_error_label)
2082 if self.num_required_kw_args:
2083 # pure error case: keywords required but not passed
2084 if max_positional_args > min_positional_args and not self.star_arg:
2085 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2086 Naming.args_cname, max_positional_args))
2087 code.put_goto(argtuple_error_label)
2088 code.putln('} else {')
2089 for i, arg in enumerate(kw_only_args):
2091 # required keyword-only argument missing
2092 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2093 self.name.utf8encode(),
2094 arg.name_entry.pystring_cname))
2095 code.putln(code.error_goto(self.pos))
2098 elif min_positional_args == max_positional_args:
2099 # parse the exact number of positional arguments from the
2101 code.putln('} else {')
2102 for i, arg in enumerate(positional_args):
2103 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2104 self.generate_arg_assignment(arg, item, code)
2105 self.generate_arg_default_assignments(code)
2108 # parse the positional arguments from the variable length
2110 code.putln('} else {')
2111 self.generate_arg_default_assignments(code)
2112 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2114 code.putln('default:')
2115 reversed_args = list(enumerate(positional_args))[::-1]
2116 for i, arg in reversed_args:
2117 if i >= min_positional_args-1:
2118 if min_positional_args > 1:
2119 code.putln('case %2d:' % (i+1)) # pure code beautification
2121 code.put('case %2d: ' % (i+1))
2122 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2123 self.generate_arg_assignment(arg, item, code)
2124 if min_positional_args == 0:
2125 code.put('case 0: ')
2126 code.putln('break;')
2128 if min_positional_args:
2129 for i in range(min_positional_args-1, -1, -1):
2130 code.putln('case %2d:' % i)
2131 code.put_goto(argtuple_error_label)
2133 code.put('default: ')
2134 code.put_goto(argtuple_error_label)
2139 if code.label_used(argtuple_error_label):
2140 code.put_goto(success_label)
2141 code.put_label(argtuple_error_label)
2142 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2143 self.name.utf8encode(), has_fixed_positional_count,
2144 min_positional_args, max_positional_args,
2146 code.putln(code.error_goto(self.pos))
2148 def generate_arg_default_assignments(self, code):
2149 for arg in self.args:
2150 if arg.is_generic and arg.default:
2154 arg.default_result_code))
2156 def generate_stararg_init_code(self, max_positional_args, code):
2157 if self.starstar_arg:
2158 self.starstar_arg.entry.xdecref_cleanup = 0
2159 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2160 self.starstar_arg.entry.cname,
2161 self.starstar_arg.entry.cname,
2162 self.error_value()))
2163 code.put_gotref(self.starstar_arg.entry.cname)
2165 self.star_arg.entry.xdecref_cleanup = 0
2166 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2168 max_positional_args))
2169 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2170 self.star_arg.entry.cname, Naming.args_cname,
2171 max_positional_args, Naming.args_cname))
2172 code.put_gotref(self.star_arg.entry.cname)
2173 if self.starstar_arg:
2175 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2176 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2177 code.putln('return %s;' % self.error_value())
2180 code.putln("if (unlikely(!%s)) return %s;" % (
2181 self.star_arg.entry.cname, self.error_value()))
2182 code.putln('} else {')
2183 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2184 code.put_incref(Naming.empty_tuple, py_object_type)
2187 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2188 has_fixed_positional_count, positional_args,
2189 kw_only_args, argtuple_error_label, code):
2190 all_args = tuple(positional_args) + tuple(kw_only_args)
2191 max_args = len(all_args)
2194 for i, arg in enumerate(all_args):
2195 if arg.default and arg.type.is_pyobject:
2196 default_value = arg.default_result_code
2197 if arg.type is not PyrexTypes.py_object_type:
2198 default_value = "(PyObject*)"+default_value
2199 default_args.append((i, default_value))
2201 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2203 # it looks funny to separate the init-to-0 from setting the
2204 # default value, but C89 needs this
2205 code.putln("PyObject* values[%d] = {%s};" % (
2206 max_args, ','.join(['0']*max_args)))
2207 for i, default_value in default_args:
2208 code.putln('values[%d] = %s;' % (i, default_value))
2210 # parse the tuple and check that it's not too long
2211 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2213 code.putln('default:')
2214 for i in range(max_positional_args-1, -1, -1):
2215 code.put('case %2d: ' % (i+1))
2216 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2217 i, Naming.args_cname, i))
2218 code.putln('case 0: break;')
2219 if not self.star_arg:
2220 code.put('default: ') # more arguments than allowed
2221 code.put_goto(argtuple_error_label)
2224 # now fill up the positional/required arguments with values
2226 if self.num_required_args or max_positional_args > 0:
2227 last_required_arg = -1
2228 for i, arg in enumerate(all_args):
2230 last_required_arg = i
2231 if last_required_arg < max_positional_args:
2232 last_required_arg = max_positional_args-1
2233 num_required_args = self.num_required_args
2234 if max_positional_args > 0:
2235 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2236 for i, arg in enumerate(all_args[:last_required_arg+1]):
2237 if max_positional_args > 0 and i <= max_positional_args:
2238 if self.star_arg and i == max_positional_args:
2239 code.putln('default:')
2241 code.putln('case %2d:' % i)
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, arg.name_entry.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, arg.name_entry.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.utf8encode(), 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.utf8encode(), arg.name_entry.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:
2295 'value = PyDict_GetItem(%s, %s);' % (
2296 Naming.kwds_cname, arg.name_entry.pystring_cname))
2298 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2299 code.putln('break;')
2302 code.putln('if (unlikely(kw_args > 0)) {')
2303 # non-positional/-required kw args left in dict: default args,
2304 # kw-only args, **kwargs or error
2306 # This is sort of a catch-all: except for checking required
2307 # arguments, this will always do the right thing for unpacking
2308 # keyword arguments, so that we can concentrate on optimising
2309 # common cases above.
2310 if max_positional_args == 0:
2313 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2314 Naming.args_cname, max_positional_args,
2315 Naming.args_cname, max_positional_args))
2316 pos_arg_count = "used_pos_args"
2318 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2319 code.globalstate.use_utility_code(parse_keywords_utility_code)
2321 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2323 Naming.pykwdlist_cname,
2324 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2326 self.name.utf8encode()))
2327 code.putln(code.error_goto(self.pos))
2330 # convert arg values to their final type and assign them
2331 for i, arg in enumerate(all_args):
2332 if arg.default and not arg.type.is_pyobject:
2333 code.putln("if (values[%d]) {" % i)
2334 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2335 if arg.default and not arg.type.is_pyobject:
2336 code.putln('} else {')
2340 arg.default_result_code))
2343 def generate_argument_conversion_code(self, code):
2344 # Generate code to convert arguments from
2345 # signature type to declared type, if needed.
2346 for arg in self.args:
2347 if arg.needs_conversion:
2348 self.generate_arg_conversion(arg, code)
2350 def generate_arg_conversion(self, arg, code):
2351 # Generate conversion code for one argument.
2352 old_type = arg.hdr_type
2354 if old_type.is_pyobject:
2356 code.putln("if (%s) {" % arg.hdr_cname)
2358 code.putln("assert(%s); {" % arg.hdr_cname)
2359 self.generate_arg_conversion_from_pyobject(arg, code)
2361 elif new_type.is_pyobject:
2362 self.generate_arg_conversion_to_pyobject(arg, code)
2364 if new_type.assignable_from(old_type):
2366 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2369 "Cannot convert 1 argument from '%s' to '%s'" %
2370 (old_type, new_type))
2372 def generate_arg_conversion_from_pyobject(self, arg, code):
2374 func = new_type.from_py_function
2375 # copied from CoerceFromPyTypeNode
2377 code.putln("%s = %s(%s); %s" % (
2381 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2384 "Cannot convert Python object argument to type '%s'"
2387 def generate_arg_conversion_to_pyobject(self, arg, code):
2388 old_type = arg.hdr_type
2389 func = old_type.to_py_function
2391 code.putln("%s = %s(%s); %s" % (
2395 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2396 code.put_var_gotref(arg.entry)
2399 "Cannot convert argument of type '%s' to Python object"
2402 def generate_argument_type_tests(self, code):
2403 # Generate type tests for args whose signature
2404 # type is PyObject * and whose declared type is
2405 # a subtype thereof.
2406 for arg in self.args:
2407 if arg.needs_type_test:
2408 self.generate_arg_type_test(arg, code)
2410 def generate_arg_type_test(self, arg, code):
2411 # Generate type test for one argument.
2412 if arg.type.typeobj_is_available():
2413 typeptr_cname = arg.type.typeptr_cname
2414 arg_code = "((PyObject *)%s)" % arg.entry.cname
2416 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2421 arg.type.is_builtin_type,
2422 code.error_goto(arg.pos)))
2424 error(arg.pos, "Cannot test type of extern C class "
2425 "without type object name specification")
2427 def error_value(self):
2428 return self.entry.signature.error_value
2430 def caller_will_check_exceptions(self):
2433 class OverrideCheckNode(StatNode):
2434 # A Node for dispatching to the def method if it
2443 child_attrs = ['body']
2447 def analyse_expressions(self, env):
2448 self.args = env.arg_entries
2449 if self.py_func.is_module_scope:
2454 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2455 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2456 call_node = ExprNodes.SimpleCallNode(self.pos,
2457 function=self.func_node,
2458 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2459 self.body = ReturnStatNode(self.pos, value=call_node)
2460 self.body.analyse_expressions(env)
2462 def generate_execution_code(self, code):
2463 # Check to see if we are an extension type
2464 if self.py_func.is_module_scope:
2465 self_arg = "((PyObject *)%s)" % Naming.module_cname
2467 self_arg = "((PyObject *)%s)" % self.args[0].cname
2468 code.putln("/* Check if called by wrapper */")
2469 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2470 code.putln("/* Check if overriden in Python */")
2471 if self.py_func.is_module_scope:
2472 code.putln("else {")
2474 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2475 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2476 # need to get attribute manually--scope would return cdef method
2477 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2478 code.put_gotref(self.func_node.py_result())
2479 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2480 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2481 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2482 self.body.generate_execution_code(code)
2484 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2487 class ClassDefNode(StatNode, BlockNode):
2490 class PyClassDefNode(ClassDefNode):
2491 # A Python class definition.
2493 # name EncodedString Name of the class
2494 # doc string or None
2495 # body StatNode Attribute definition code
2496 # entry Symtab.Entry
2497 # scope PyClassScope
2499 # The following subnodes are constructed internally:
2501 # dict DictNode Class dictionary
2502 # classobj ClassNode Class object
2503 # target NameNode Variable to assign class object to
2505 child_attrs = ["body", "dict", "classobj", "target"]
2507 def __init__(self, pos, name, bases, doc, body):
2508 StatNode.__init__(self, pos)
2513 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2514 if self.doc and Options.docstrings:
2515 doc = embed_position(self.pos, self.doc)
2516 doc_node = ExprNodes.StringNode(pos, value = doc)
2519 self.classobj = ExprNodes.ClassNode(pos, name = name,
2520 bases = bases, dict = self.dict, doc = doc_node)
2521 self.target = ExprNodes.NameNode(pos, name = name)
2523 def as_cclass(self):
2525 Return this node as if it were declared as an extension class
2527 bases = self.classobj.bases.args
2529 base_class_name = None
2530 base_class_module = None
2531 elif len(bases) == 1:
2534 from ExprNodes import AttributeNode, NameNode
2535 while isinstance(base, AttributeNode):
2536 path.insert(0, base.attribute)
2538 if isinstance(base, NameNode):
2539 path.insert(0, base.name)
2540 base_class_name = path[-1]
2542 base_class_module = u'.'.join(path[:-1])
2544 base_class_module = None
2546 error(self.classobj.bases.args.pos, "Invalid base class")
2548 error(self.classobj.bases.args.pos, "C class may only have one base class")
2551 return CClassDefNode(self.pos,
2552 visibility = 'private',
2554 class_name = self.name,
2555 base_class_module = base_class_module,
2556 base_class_name = base_class_name,
2561 def create_scope(self, env):
2563 while env.is_py_class_scope or env.is_c_class_scope:
2564 env = env.outer_scope
2565 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2568 def analyse_declarations(self, env):
2569 self.target.analyse_target_declaration(env)
2570 cenv = self.create_scope(env)
2571 cenv.directives = env.directives
2572 cenv.class_obj_cname = self.target.entry.cname
2573 self.body.analyse_declarations(cenv)
2575 def analyse_expressions(self, env):
2576 self.dict.analyse_expressions(env)
2577 self.classobj.analyse_expressions(env)
2578 genv = env.global_scope()
2580 cenv.class_dict_cname = self.dict.result()
2581 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2582 self.body.analyse_expressions(cenv)
2583 self.target.analyse_target_expression(env, self.classobj)
2584 self.dict.release_temp(env)
2585 #self.classobj.release_temp(env)
2586 #self.target.release_target_temp(env)
2588 def generate_function_definitions(self, env, code):
2589 self.generate_py_string_decls(self.scope, code)
2590 self.body.generate_function_definitions(self.scope, code)
2592 def generate_execution_code(self, code):
2593 self.dict.generate_evaluation_code(code)
2594 self.classobj.generate_evaluation_code(code)
2595 self.body.generate_execution_code(code)
2596 self.target.generate_assignment_code(self.classobj, code)
2597 self.dict.generate_disposal_code(code)
2598 self.dict.free_temps(code)
2601 class CClassDefNode(ClassDefNode):
2602 # An extension type definition.
2604 # visibility 'private' or 'public' or 'extern'
2605 # typedef_flag boolean
2607 # module_name string or None For import of extern type objects
2608 # class_name string Unqualified name of class
2609 # as_name string or None Name to declare as in this scope
2610 # base_class_module string or None Module containing the base class
2611 # base_class_name string or None Name of the base class
2612 # objstruct_name string or None Specified C name of object struct
2613 # typeobj_name string or None Specified C name of type object
2614 # in_pxd boolean Is in a .pxd file
2615 # doc string or None
2616 # body StatNode or None
2617 # entry Symtab.Entry
2618 # base_type PyExtensionType or None
2619 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2620 # buffer_defaults_pos
2622 child_attrs = ["body"]
2623 buffer_defaults_node = None
2624 buffer_defaults_pos = None
2625 typedef_flag = False
2627 objstruct_name = None
2630 def analyse_declarations(self, env):
2631 #print "CClassDefNode.analyse_declarations:", self.class_name
2632 #print "...visibility =", self.visibility
2633 #print "...module_name =", self.module_name
2636 if self.buffer_defaults_node:
2637 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2638 env, [], self.buffer_defaults_node,
2639 need_complete=False)
2641 buffer_defaults = None
2643 if env.in_cinclude and not self.objstruct_name:
2644 error(self.pos, "Object struct name specification required for "
2645 "C class defined in 'extern from' block")
2646 self.base_type = None
2647 # Now that module imports are cached, we need to
2648 # import the modules for extern classes.
2649 if self.module_name:
2651 for module in env.cimported_modules:
2652 if module.name == self.module_name:
2653 self.module = module
2654 if self.module is None:
2655 self.module = ModuleScope(self.module_name, None, env.context)
2656 self.module.has_extern_class = 1
2657 env.add_imported_module(self.module)
2659 if self.base_class_name:
2660 if self.base_class_module:
2661 base_class_scope = env.find_module(self.base_class_module, self.pos)
2663 base_class_scope = env
2664 if self.base_class_name == 'object':
2665 # extension classes are special and don't need to inherit from object
2666 if base_class_scope is None or base_class_scope.lookup('object') is None:
2667 self.base_class_name = None
2668 self.base_class_module = None
2669 base_class_scope = None
2670 if base_class_scope:
2671 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2672 if base_class_entry:
2673 if not base_class_entry.is_type:
2674 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2675 elif not base_class_entry.type.is_extension_type:
2676 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2677 elif not base_class_entry.type.is_complete():
2678 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2680 self.base_type = base_class_entry.type
2681 has_body = self.body is not None
2682 if self.module_name and self.visibility != 'extern':
2683 module_path = self.module_name.split(".")
2684 home_scope = env.find_imported_module(module_path, self.pos)
2690 if self.visibility == 'extern':
2691 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2692 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2694 self.entry = home_scope.declare_c_class(
2695 name = self.class_name,
2697 defining = has_body and self.in_pxd,
2698 implementing = has_body and not self.in_pxd,
2699 module_name = self.module_name,
2700 base_type = self.base_type,
2701 objstruct_cname = self.objstruct_name,
2702 typeobj_cname = self.typeobj_name,
2703 visibility = self.visibility,
2704 typedef_flag = self.typedef_flag,
2706 buffer_defaults = buffer_defaults)
2707 if home_scope is not env and self.visibility == 'extern':
2708 env.add_imported_entry(self.class_name, self.entry, pos)
2709 scope = self.entry.type.scope
2710 if scope is not None:
2711 scope.directives = env.directives
2713 if self.doc and Options.docstrings:
2714 scope.doc = embed_position(self.pos, self.doc)
2717 self.body.analyse_declarations(scope)
2721 scope.implemented = 1
2722 env.allocate_vtable_names(self.entry)
2724 def analyse_expressions(self, env):
2726 scope = self.entry.type.scope
2727 self.body.analyse_expressions(scope)
2729 def generate_function_definitions(self, env, code):
2730 self.generate_py_string_decls(self.entry.type.scope, code)
2732 self.body.generate_function_definitions(
2733 self.entry.type.scope, code)
2735 def generate_execution_code(self, code):
2736 # This is needed to generate evaluation code for
2737 # default values of method arguments.
2739 self.body.generate_execution_code(code)
2741 def annotate(self, code):
2743 self.body.annotate(code)
2746 class PropertyNode(StatNode):
2747 # Definition of a property in an extension type.
2750 # doc EncodedString or None Doc string
2753 child_attrs = ["body"]
2755 def analyse_declarations(self, env):
2756 entry = env.declare_property(self.name, self.doc, self.pos)
2758 if self.doc and Options.docstrings:
2759 doc_entry = env.get_string_const(
2760 self.doc, identifier = False)
2761 entry.doc_cname = doc_entry.cname
2762 entry.scope.directives = env.directives
2763 self.body.analyse_declarations(entry.scope)
2765 def analyse_expressions(self, env):
2766 self.body.analyse_expressions(env)
2768 def generate_function_definitions(self, env, code):
2769 self.body.generate_function_definitions(env, code)
2771 def generate_execution_code(self, code):
2774 def annotate(self, code):
2775 self.body.annotate(code)
2778 class GlobalNode(StatNode):
2779 # Global variable declaration.
2785 def analyse_declarations(self, env):
2786 for name in self.names:
2787 env.declare_global(name, self.pos)
2789 def analyse_expressions(self, env):
2792 def generate_execution_code(self, code):
2796 class ExprStatNode(StatNode):
2797 # Expression used as a statement.
2801 child_attrs = ["expr"]
2803 def analyse_declarations(self, env):
2805 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2806 func = self.expr.function.as_cython_attribute()
2807 if func == u'declare':
2808 args, kwds = self.expr.explicit_args_kwds()
2810 error(self.expr.pos, "Variable names must be specified.")
2811 for var, type_node in kwds.key_value_pairs:
2812 type = type_node.analyse_as_type(env)
2814 error(type_node.pos, "Unknown type")
2816 env.declare_var(var.value, type, var.pos, is_cdef = True)
2817 self.__class__ = PassStatNode
2819 def analyse_expressions(self, env):
2820 self.expr.analyse_expressions(env)
2821 self.expr.release_temp(env)
2823 def generate_execution_code(self, code):
2824 self.expr.generate_evaluation_code(code)
2825 if not self.expr.is_temp and self.expr.result():
2826 code.putln("%s;" % self.expr.result())
2827 self.expr.generate_disposal_code(code)
2828 self.expr.free_temps(code)
2830 def annotate(self, code):
2831 self.expr.annotate(code)
2834 class AssignmentNode(StatNode):
2835 # Abstract base class for assignment nodes.
2837 # The analyse_expressions and generate_execution_code
2838 # phases of assignments are split into two sub-phases
2839 # each, to enable all the right hand sides of a
2840 # parallel assignment to be evaluated before assigning
2841 # to any of the left hand sides.
2843 def analyse_expressions(self, env):
2844 self.analyse_types(env)
2845 self.allocate_rhs_temps(env)
2846 self.allocate_lhs_temps(env)
2848 # def analyse_expressions(self, env):
2849 # self.analyse_expressions_1(env)
2850 # self.analyse_expressions_2(env)
2852 def generate_execution_code(self, code):
2853 self.generate_rhs_evaluation_code(code)
2854 self.generate_assignment_code(code)
2857 class SingleAssignmentNode(AssignmentNode):
2858 # The simplest case:
2862 # lhs ExprNode Left hand side
2863 # rhs ExprNode Right hand side
2864 # first bool Is this guaranteed the first assignment to lhs?
2866 child_attrs = ["lhs", "rhs"]
2868 declaration_only = False
2870 def analyse_declarations(self, env):
2873 # handle declarations of the form x = cython.foo()
2874 if isinstance(self.rhs, ExprNodes.CallNode):
2875 func_name = self.rhs.function.as_cython_attribute()
2877 args, kwds = self.rhs.explicit_args_kwds()
2879 if func_name in ['declare', 'typedef']:
2880 if len(args) > 2 or kwds is not None:
2881 error(rhs.pos, "Can only declare one type at a time.")
2883 type = args[0].analyse_as_type(env)
2885 error(args[0].pos, "Unknown type")
2888 if func_name == 'declare':
2889 if isinstance(lhs, ExprNodes.NameNode):
2890 vars = [(lhs.name, lhs.pos)]
2891 elif isinstance(lhs, ExprNodes.TupleNode):
2892 vars = [(var.name, var.pos) for var in lhs.args]
2894 error(lhs.pos, "Invalid declaration")
2896 for var, pos in vars:
2897 env.declare_var(var, type, pos, is_cdef = True)
2902 self.declaration_only = True
2904 self.declaration_only = True
2905 if not isinstance(lhs, ExprNodes.NameNode):
2906 error(lhs.pos, "Invalid declaration.")
2907 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2909 elif func_name in ['struct', 'union']:
2910 self.declaration_only = True
2911 if len(args) > 0 or kwds is None:
2912 error(rhs.pos, "Struct or union members must be given by name.")
2915 for member, type_node in kwds.key_value_pairs:
2916 type = type_node.analyse_as_type(env)
2918 error(type_node.pos, "Unknown type")
2920 members.append((member.value, type, member.pos))
2921 if len(members) < len(kwds.key_value_pairs):
2923 if not isinstance(self.lhs, ExprNodes.NameNode):
2924 error(self.lhs.pos, "Invalid declaration.")
2925 name = self.lhs.name
2926 scope = StructOrUnionScope(name)
2927 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2928 for member, type, pos in members:
2929 scope.declare_var(member, type, pos)
2931 if self.declaration_only:
2934 self.lhs.analyse_target_declaration(env)
2936 def analyse_types(self, env, use_temp = 0):
2937 self.rhs.analyse_types(env)
2938 self.lhs.analyse_target_types(env)
2939 self.lhs.gil_assignment_check(env)
2940 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2942 self.rhs = self.rhs.coerce_to_temp(env)
2944 def allocate_rhs_temps(self, env):
2945 self.rhs.allocate_temps(env)
2947 def allocate_lhs_temps(self, env):
2948 self.lhs.allocate_target_temps(env, self.rhs)
2949 #self.lhs.release_target_temp(env)
2950 #self.rhs.release_temp(env)
2952 def generate_rhs_evaluation_code(self, code):
2953 self.rhs.generate_evaluation_code(code)
2955 def generate_assignment_code(self, code):
2956 self.lhs.generate_assignment_code(self.rhs, code)
2958 def annotate(self, code):
2959 self.lhs.annotate(code)
2960 self.rhs.annotate(code)
2963 class CascadedAssignmentNode(AssignmentNode):
2964 # An assignment with multiple left hand sides:
2968 # lhs_list [ExprNode] Left hand sides
2969 # rhs ExprNode Right hand sides
2973 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2975 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2976 coerced_rhs_list = None
2978 def analyse_declarations(self, env):
2979 for lhs in self.lhs_list:
2980 lhs.analyse_target_declaration(env)
2982 def analyse_types(self, env, use_temp = 0):
2983 self.rhs.analyse_types(env)
2985 self.rhs = self.rhs.coerce_to_temp(env)
2987 self.rhs = self.rhs.coerce_to_simple(env)
2988 from ExprNodes import CloneNode
2989 self.coerced_rhs_list = []
2990 for lhs in self.lhs_list:
2991 lhs.analyse_target_types(env)
2992 lhs.gil_assignment_check(env)
2993 rhs = CloneNode(self.rhs)
2994 rhs = rhs.coerce_to(lhs.type, env)
2995 self.coerced_rhs_list.append(rhs)
2997 def allocate_rhs_temps(self, env):
2998 self.rhs.allocate_temps(env)
3000 def allocate_lhs_temps(self, env):
3001 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
3002 rhs.allocate_temps(env)
3003 lhs.allocate_target_temps(env, rhs)
3004 #lhs.release_target_temp(env)
3005 #rhs.release_temp(env)
3006 self.rhs.release_temp(env)
3008 def generate_rhs_evaluation_code(self, code):
3009 self.rhs.generate_evaluation_code(code)
3011 def generate_assignment_code(self, code):
3012 for i in range(len(self.lhs_list)):
3013 lhs = self.lhs_list[i]
3014 rhs = self.coerced_rhs_list[i]
3015 rhs.generate_evaluation_code(code)
3016 lhs.generate_assignment_code(rhs, code)
3017 # Assignment has disposed of the cloned RHS
3018 self.rhs.generate_disposal_code(code)
3019 self.rhs.free_temps(code)
3021 def annotate(self, code):
3022 for i in range(len(self.lhs_list)):
3023 lhs = self.lhs_list[i].annotate(code)
3024 rhs = self.coerced_rhs_list[i].annotate(code)
3025 self.rhs.annotate(code)
3028 class ParallelAssignmentNode(AssignmentNode):
3029 # A combined packing/unpacking assignment:
3033 # This has been rearranged by the parser into
3035 # a = d ; b = e ; c = f
3037 # but we must evaluate all the right hand sides
3038 # before assigning to any of the left hand sides.
3040 # stats [AssignmentNode] The constituent assignments
3042 child_attrs = ["stats"]
3044 def analyse_declarations(self, env):
3045 for stat in self.stats:
3046 stat.analyse_declarations(env)
3048 def analyse_expressions(self, env):
3049 for stat in self.stats:
3050 stat.analyse_types(env, use_temp = 1)
3051 stat.allocate_rhs_temps(env)
3052 for stat in self.stats:
3053 stat.allocate_lhs_temps(env)
3055 # def analyse_expressions(self, env):
3056 # for stat in self.stats:
3057 # stat.analyse_expressions_1(env, use_temp = 1)
3058 # for stat in self.stats:
3059 # stat.analyse_expressions_2(env)
3061 def generate_execution_code(self, code):
3062 for stat in self.stats:
3063 stat.generate_rhs_evaluation_code(code)
3064 for stat in self.stats:
3065 stat.generate_assignment_code(code)
3067 def annotate(self, code):
3068 for stat in self.stats:
3072 class InPlaceAssignmentNode(AssignmentNode):
3073 # An in place arithmatic operand:
3079 # lhs ExprNode Left hand side
3080 # rhs ExprNode Right hand side
3081 # op char one of "+-*/%^&|"
3082 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3084 # This code is a bit tricky because in order to obey Python
3085 # semantics the sub-expressions (e.g. indices) of the lhs must
3086 # not be evaluated twice. So we must re-use the values calculated
3087 # in evaluation phase for the assignment phase as well.
3088 # Fortunately, the type of the lhs node is fairly constrained
3089 # (it must be a NameNode, AttributeNode, or IndexNode).
3091 child_attrs = ["lhs", "rhs"]
3094 def analyse_declarations(self, env):
3095 self.lhs.analyse_target_declaration(env)
3097 def analyse_types(self, env):
3098 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3099 self.rhs.analyse_types(env)
3100 self.lhs.analyse_target_types(env)
3101 if Options.incref_local_binop and self.dup.type.is_pyobject:
3102 self.dup = self.dup.coerce_to_temp(env)
3104 def allocate_rhs_temps(self, env):
3106 if self.lhs.type.is_pyobject:
3107 self.rhs = self.rhs.coerce_to_pyobject(env)
3108 elif self.rhs.type.is_pyobject:
3109 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3110 if self.lhs.type.is_pyobject:
3111 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3112 self.result_value.allocate_temps(env)
3114 # self.rhs = self.rhs.coerce_to_temp(env)
3115 self.rhs.allocate_temps(env)
3116 self.dup.allocate_subexpr_temps(env)
3117 self.dup.allocate_temp(env)
3119 def allocate_lhs_temps(self, env):
3120 self.lhs.allocate_target_temps(env, self.rhs)
3121 # self.lhs.release_target_temp(env)
3122 self.dup.release_temp(env)
3123 if self.dup.is_temp:
3124 self.dup.release_subexpr_temps(env)
3125 # self.rhs.release_temp(env)
3126 if self.lhs.type.is_pyobject:
3127 self.result_value.release_temp(env)
3129 def generate_execution_code(self, code):
3131 self.rhs.generate_evaluation_code(code)
3132 self.dup.generate_subexpr_evaluation_code(code)
3133 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3134 # This is because we're manually messing with subexpr nodes
3135 if self.dup.is_temp:
3136 self.dup.allocate_temp_result(code)
3137 # self.dup.generate_result_code is run only if it is not buffer access
3138 if self.operator == "**":
3142 if self.lhs.type.is_pyobject:
3143 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3144 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3145 self.dup.generate_result_code(code)
3147 "%s = %s(%s, %s%s); %s" % (
3148 self.result_value.result(),
3149 self.py_operation_function(),
3150 self.dup.py_result(),
3151 self.rhs.py_result(),
3153 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3154 code.put_gotref(self.result_value.py_result())
3155 self.result_value.generate_evaluation_code(code) # May be a type check...
3156 self.rhs.generate_disposal_code(code)
3157 self.rhs.free_temps(code)
3158 self.dup.generate_disposal_code(code)
3159 self.dup.free_temps(code)
3160 self.lhs.generate_assignment_code(self.result_value, code)
3162 c_op = self.operator
3166 if self.lhs.type.is_int and self.rhs.type.is_int:
3167 error(self.pos, "** with two C int types is ambiguous")
3169 error(self.pos, "No C inplace power operator")
3170 # have to do assignment directly to avoid side-effects
3171 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3172 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3174 self.dup.generate_result_code(code)
3175 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3176 self.rhs.generate_disposal_code(code)
3177 self.rhs.free_temps(code)
3178 if self.dup.is_temp:
3179 self.dup.generate_subexpr_disposal_code(code)
3180 self.dup.free_subexpr_temps(code)
3182 def create_dup_node(self, env):
3185 self.dup.analyse_types(env)
3186 if isinstance(self.lhs, ExprNodes.NameNode):
3187 target_lhs = ExprNodes.NameNode(self.dup.pos,
3188 name = self.dup.name,
3189 is_temp = self.dup.is_temp,
3190 entry = self.dup.entry)
3191 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3192 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3193 obj = ExprNodes.CloneNode(self.lhs.obj),
3194 attribute = self.dup.attribute,
3195 is_temp = self.dup.is_temp)
3196 elif isinstance(self.lhs, ExprNodes.IndexNode):
3198 index = ExprNodes.CloneNode(self.lhs.index)
3201 if self.lhs.indices:
3202 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3205 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3206 base = ExprNodes.CloneNode(self.dup.base),
3209 is_temp = self.dup.is_temp)
3212 self.lhs = target_lhs
3215 def py_operation_function(self):
3216 return self.py_functions[self.operator]
3219 "|": "PyNumber_InPlaceOr",
3220 "^": "PyNumber_InPlaceXor",
3221 "&": "PyNumber_InPlaceAnd",
3222 "+": "PyNumber_InPlaceAdd",
3223 "-": "PyNumber_InPlaceSubtract",
3224 "*": "PyNumber_InPlaceMultiply",
3225 "/": "PyNumber_InPlaceDivide",
3226 "%": "PyNumber_InPlaceRemainder",
3227 "<<": "PyNumber_InPlaceLshift",
3228 ">>": "PyNumber_InPlaceRshift",
3229 "**": "PyNumber_InPlacePower",
3230 "//": "PyNumber_InPlaceFloorDivide",
3233 def annotate(self, code):
3234 self.lhs.annotate(code)
3235 self.rhs.annotate(code)
3236 self.dup.annotate(code)
3239 class PrintStatNode(StatNode):
3242 # arg_tuple TupleNode
3243 # append_newline boolean
3245 child_attrs = ["arg_tuple"]
3247 def analyse_expressions(self, env):
3248 self.arg_tuple.analyse_expressions(env)
3249 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3250 self.arg_tuple.release_temp(env)
3251 env.use_utility_code(printing_utility_code)
3252 if len(self.arg_tuple.args) == 1 and self.append_newline:
3253 env.use_utility_code(printing_one_utility_code)
3256 gil_message = "Python print statement"
3258 def generate_execution_code(self, code):
3259 if len(self.arg_tuple.args) == 1 and self.append_newline:
3260 arg = self.arg_tuple.args[0]
3261 arg.generate_evaluation_code(code)
3264 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3266 code.error_goto(self.pos)))
3267 arg.generate_disposal_code(code)
3268 arg.free_temps(code)
3270 self.arg_tuple.generate_evaluation_code(code)
3272 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3273 self.arg_tuple.py_result(),
3274 self.append_newline,
3275 code.error_goto(self.pos)))
3276 self.arg_tuple.generate_disposal_code(code)
3277 self.arg_tuple.free_temps(code)
3279 def annotate(self, code):
3280 self.arg_tuple.annotate(code)
3283 class ExecStatNode(StatNode):
3288 child_attrs = ["args"]
3290 def analyse_expressions(self, env):
3291 for i, arg in enumerate(self.args):
3292 arg.analyse_expressions(env)
3293 arg = arg.coerce_to_pyobject(env)
3294 arg.release_temp(env)
3296 self.temp_result = env.allocate_temp_pyobject()
3297 env.release_temp(self.temp_result)
3298 env.use_utility_code(Builtin.pyexec_utility_code)
3301 gil_message = "Python exec statement"
3303 def generate_execution_code(self, code):
3305 for arg in self.args:
3306 arg.generate_evaluation_code(code)
3307 args.append( arg.py_result() )
3308 args = tuple(args + ['0', '0'][:3-len(args)])
3309 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3310 (self.temp_result,) + args))
3311 for arg in self.args:
3312 arg.generate_disposal_code(code)
3313 arg.free_temps(code)
3315 code.error_goto_if_null(self.temp_result, self.pos))
3316 code.put_gotref(self.temp_result)
3317 code.put_decref_clear(self.temp_result, py_object_type)
3319 def annotate(self, code):
3320 for arg in self.args:
3324 class DelStatNode(StatNode):
3329 child_attrs = ["args"]
3331 def analyse_declarations(self, env):
3332 for arg in self.args:
3333 arg.analyse_target_declaration(env)
3335 def analyse_expressions(self, env):
3336 for arg in self.args:
3337 arg.analyse_target_expression(env, None)
3338 if arg.type.is_pyobject:
3341 error(arg.pos, "Deletion of non-Python object")
3342 #arg.release_target_temp(env)
3344 gil_message = "Deleting Python object"
3346 def generate_execution_code(self, code):
3347 for arg in self.args:
3348 if arg.type.is_pyobject:
3349 arg.generate_deletion_code(code)
3350 # else error reported earlier
3352 def annotate(self, code):
3353 for arg in self.args:
3357 class PassStatNode(StatNode):
3362 def analyse_expressions(self, env):
3365 def generate_execution_code(self, code):
3369 class BreakStatNode(StatNode):
3373 def analyse_expressions(self, env):
3376 def generate_execution_code(self, code):
3377 if not code.break_label:
3378 error(self.pos, "break statement not inside loop")
3380 code.put_goto(code.break_label)
3383 class ContinueStatNode(StatNode):
3387 def analyse_expressions(self, env):
3390 def generate_execution_code(self, code):
3391 if code.funcstate.in_try_finally:
3392 error(self.pos, "continue statement inside try of try...finally")
3393 elif not code.continue_label:
3394 error(self.pos, "continue statement not inside loop")
3396 code.put_goto(code.continue_label)
3399 class ReturnStatNode(StatNode):
3402 # value ExprNode or None
3403 # return_type PyrexType
3404 # temps_in_use [Entry] Temps in use at time of return
3406 child_attrs = ["value"]
3408 def analyse_expressions(self, env):
3409 return_type = env.return_type
3410 self.return_type = return_type
3411 self.temps_in_use = env.temps_in_use()
3413 error(self.pos, "Return not inside a function body")
3416 self.value.analyse_types(env)
3417 if return_type.is_void or return_type.is_returncode:
3418 error(self.value.pos,
3419 "Return with value in void function")
3421 self.value = self.value.coerce_to(env.return_type, env)
3422 self.value.allocate_temps(env)
3423 self.value.release_temp(env)
3425 if (not return_type.is_void
3426 and not return_type.is_pyobject
3427 and not return_type.is_returncode):
3428 error(self.pos, "Return value required")
3429 if return_type.is_pyobject:
3432 gil_message = "Returning Python object"
3434 def generate_execution_code(self, code):
3435 code.mark_pos(self.pos)
3436 if not self.return_type:
3437 # error reported earlier
3439 if self.return_type.is_pyobject:
3440 code.put_xdecref(Naming.retval_cname,
3443 self.value.generate_evaluation_code(code)
3444 self.value.make_owned_reference(code)
3447 Naming.retval_cname,
3448 self.value.result_as(self.return_type)))
3449 self.value.generate_post_assignment_code(code)
3450 self.value.free_temps(code)
3452 if self.return_type.is_pyobject:
3453 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3454 elif self.return_type.is_returncode:
3457 Naming.retval_cname,
3458 self.return_type.default_value))
3459 # free temps the old way
3460 for entry in self.temps_in_use:
3461 code.put_var_decref_clear(entry)
3462 # free temps the new way
3463 for cname, type in code.funcstate.temps_holding_reference():
3464 code.put_decref_clear(cname, type)
3467 # code.return_label)
3468 code.put_goto(code.return_label)
3470 def annotate(self, code):
3472 self.value.annotate(code)
3475 class RaiseStatNode(StatNode):
3478 # exc_type ExprNode or None
3479 # exc_value ExprNode or None
3480 # exc_tb ExprNode or None
3482 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3484 def analyse_expressions(self, env):
3486 self.exc_type.analyse_types(env)
3487 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3488 self.exc_type.allocate_temps(env)
3490 self.exc_value.analyse_types(env)
3491 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3492 self.exc_value.allocate_temps(env)
3494 self.exc_tb.analyse_types(env)
3495 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3496 self.exc_tb.allocate_temps(env)
3498 self.exc_type.release_temp(env)
3500 self.exc_value.release_temp(env)
3502 self.exc_tb.release_temp(env)
3503 env.use_utility_code(raise_utility_code)
3504 env.use_utility_code(restore_exception_utility_code)
3507 gil_message = "Raising exception"
3509 def generate_execution_code(self, code):
3511 self.exc_type.generate_evaluation_code(code)
3512 type_code = self.exc_type.py_result()
3516 self.exc_value.generate_evaluation_code(code)
3517 value_code = self.exc_value.py_result()
3521 self.exc_tb.generate_evaluation_code(code)
3522 tb_code = self.exc_tb.py_result()
3525 if self.exc_type or self.exc_value or self.exc_tb:
3527 "__Pyx_Raise(%s, %s, %s);" % (
3534 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3536 obj.generate_disposal_code(code)
3537 obj.free_temps(code)
3539 code.error_goto(self.pos))
3541 def annotate(self, code):
3543 self.exc_type.annotate(code)
3545 self.exc_value.annotate(code)
3547 self.exc_tb.annotate(code)
3550 class ReraiseStatNode(StatNode):
3554 def analyse_expressions(self, env):
3556 env.use_utility_code(raise_utility_code)
3557 env.use_utility_code(restore_exception_utility_code)
3559 gil_message = "Raising exception"
3561 def generate_execution_code(self, code):
3562 vars = code.funcstate.exc_vars
3564 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3565 code.putln(code.error_goto(self.pos))
3567 error(self.pos, "Reraise not inside except clause")
3570 class AssertStatNode(StatNode):
3574 # value ExprNode or None
3576 child_attrs = ["cond", "value"]
3578 def analyse_expressions(self, env):
3579 self.cond = self.cond.analyse_boolean_expression(env)
3581 self.value.analyse_types(env)
3582 self.value = self.value.coerce_to_pyobject(env)
3583 self.value.allocate_temps(env)
3584 self.cond.release_temp(env)
3586 self.value.release_temp(env)
3588 #env.recycle_pending_temps() # TEMPORARY
3590 gil_message = "Raising exception"
3592 def generate_execution_code(self, code):
3593 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3594 self.cond.generate_evaluation_code(code)
3596 "if (unlikely(!%s)) {" %
3599 self.value.generate_evaluation_code(code)
3601 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3602 self.value.py_result())
3603 self.value.generate_disposal_code(code)
3604 self.value.free_temps(code)
3607 "PyErr_SetNone(PyExc_AssertionError);")
3609 code.error_goto(self.pos))
3612 self.cond.generate_disposal_code(code)
3613 self.cond.free_temps(code)
3614 code.putln("#endif")
3616 def annotate(self, code):
3617 self.cond.annotate(code)
3619 self.value.annotate(code)
3622 class IfStatNode(StatNode):
3625 # if_clauses [IfClauseNode]
3626 # else_clause StatNode or None
3628 child_attrs = ["if_clauses", "else_clause"]
3630 def analyse_control_flow(self, env):
3631 env.start_branching(self.pos)
3632 for if_clause in self.if_clauses:
3633 if_clause.analyse_control_flow(env)
3634 env.next_branch(if_clause.end_pos())
3635 if self.else_clause:
3636 self.else_clause.analyse_control_flow(env)
3637 env.finish_branching(self.end_pos())
3639 def analyse_declarations(self, env):
3640 for if_clause in self.if_clauses:
3641 if_clause.analyse_declarations(env)
3642 if self.else_clause:
3643 self.else_clause.analyse_declarations(env)
3645 def analyse_expressions(self, env):
3646 for if_clause in self.if_clauses:
3647 if_clause.analyse_expressions(env)
3648 if self.else_clause:
3649 self.else_clause.analyse_expressions(env)
3651 def generate_execution_code(self, code):
3652 code.mark_pos(self.pos)
3653 end_label = code.new_label()
3654 for if_clause in self.if_clauses:
3655 if_clause.generate_execution_code(code, end_label)
3656 if self.else_clause:
3657 code.putln("/*else*/ {")
3658 self.else_clause.generate_execution_code(code)
3660 code.put_label(end_label)
3662 def annotate(self, code):
3663 for if_clause in self.if_clauses:
3664 if_clause.annotate(code)
3665 if self.else_clause:
3666 self.else_clause.annotate(code)
3669 class IfClauseNode(Node):
3670 # if or elif clause in an if statement
3672 # condition ExprNode
3675 child_attrs = ["condition", "body"]
3677 def analyse_control_flow(self, env):
3678 self.body.analyse_control_flow(env)
3680 def analyse_declarations(self, env):
3681 self.condition.analyse_declarations(env)
3682 self.body.analyse_declarations(env)
3684 def analyse_expressions(self, env):
3686 self.condition.analyse_temp_boolean_expression(env)
3687 self.condition.release_temp(env)
3688 self.body.analyse_expressions(env)
3690 def generate_execution_code(self, code, end_label):
3691 self.condition.generate_evaluation_code(code)
3694 self.condition.result())
3695 self.condition.generate_disposal_code(code)
3696 self.condition.free_temps(code)
3697 self.body.generate_execution_code(code)
3701 code.put_goto(end_label)
3704 def annotate(self, code):
3705 self.condition.annotate(code)
3706 self.body.annotate(code)
3709 class SwitchCaseNode(StatNode):
3710 # Generated in the optimization of an if-elif-else node
3712 # conditions [ExprNode]
3715 child_attrs = ['conditions', 'body']
3717 def generate_execution_code(self, code):
3718 for cond in self.conditions:
3719 code.mark_pos(cond.pos)
3720 code.putln("case %s:" % cond.calculate_result_code())
3721 self.body.generate_execution_code(code)
3722 code.putln("break;")
3724 def annotate(self, code):
3725 for cond in self.conditions:
3727 self.body.annotate(code)
3729 class SwitchStatNode(StatNode):
3730 # Generated in the optimization of an if-elif-else node
3733 # cases [SwitchCaseNode]
3734 # else_clause StatNode or None
3736 child_attrs = ['test', 'cases', 'else_clause']
3738 def generate_execution_code(self, code):
3739 code.putln("switch (%s) {" % self.test.calculate_result_code())
3740 for case in self.cases:
3741 case.generate_execution_code(code)
3742 if self.else_clause is not None:
3743 code.putln("default:")
3744 self.else_clause.generate_execution_code(code)
3745 code.putln("break;")
3748 def annotate(self, code):
3749 self.test.annotate(code)
3750 for case in self.cases:
3752 if self.else_clause is not None:
3753 self.else_clause.annotate(code)
3755 class LoopNode(object):
3757 def analyse_control_flow(self, env):
3758 env.start_branching(self.pos)
3759 self.body.analyse_control_flow(env)
3760 env.next_branch(self.body.end_pos())
3761 if self.else_clause:
3762 self.else_clause.analyse_control_flow(env)
3763 env.finish_branching(self.end_pos())
3766 class WhileStatNode(LoopNode, StatNode):
3769 # condition ExprNode
3771 # else_clause StatNode
3773 child_attrs = ["condition", "body", "else_clause"]
3775 def analyse_declarations(self, 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.condition.analyse_temp_boolean_expression(env)
3783 self.condition.release_temp(env)
3784 #env.recycle_pending_temps() # TEMPORARY
3785 self.body.analyse_expressions(env)
3786 if self.else_clause:
3787 self.else_clause.analyse_expressions(env)
3789 def generate_execution_code(self, code):
3790 old_loop_labels = code.new_loop_labels()
3793 self.condition.generate_evaluation_code(code)
3794 self.condition.generate_disposal_code(code)
3797 self.condition.result())
3798 self.condition.free_temps(code)
3799 self.body.generate_execution_code(code)
3800 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)
3810 def annotate(self, code):
3811 self.condition.annotate(code)
3812 self.body.annotate(code)
3813 if self.else_clause:
3814 self.else_clause.annotate(code)
3817 def ForStatNode(pos, **kw):
3818 if 'iterator' in kw:
3819 return ForInStatNode(pos, **kw)
3821 return ForFromStatNode(pos, **kw)
3823 class ForInStatNode(LoopNode, StatNode):
3827 # iterator IteratorNode
3829 # else_clause StatNode
3830 # item NextNode used internally
3832 child_attrs = ["target", "iterator", "body", "else_clause"]
3835 def analyse_declarations(self, env):
3836 self.target.analyse_target_declaration(env)
3837 self.body.analyse_declarations(env)
3838 if self.else_clause:
3839 self.else_clause.analyse_declarations(env)
3841 def analyse_expressions(self, env):
3843 self.target.analyse_target_types(env)
3844 self.iterator.analyse_expressions(env)
3845 self.item = ExprNodes.NextNode(self.iterator, env)
3846 self.item = self.item.coerce_to(self.target.type, env)
3847 self.item.allocate_temps(env)
3848 self.target.allocate_target_temps(env, self.item)
3849 #self.item.release_temp(env)
3850 #self.target.release_target_temp(env)
3851 self.body.analyse_expressions(env)
3852 if self.else_clause:
3853 self.else_clause.analyse_expressions(env)
3854 self.iterator.release_temp(env)
3856 def generate_execution_code(self, code):
3857 old_loop_labels = code.new_loop_labels()
3858 self.iterator.allocate_counter_temp(code)
3859 self.iterator.generate_evaluation_code(code)
3862 self.item.generate_evaluation_code(code)
3863 self.target.generate_assignment_code(self.item, code)
3864 self.body.generate_execution_code(code)
3865 code.put_label(code.continue_label)
3868 break_label = code.break_label
3869 code.set_loop_labels(old_loop_labels)
3870 if self.else_clause:
3871 code.putln("/*else*/ {")
3872 self.else_clause.generate_execution_code(code)
3874 code.put_label(break_label)
3875 self.iterator.release_counter_temp(code)
3876 self.iterator.generate_disposal_code(code)
3877 self.iterator.free_temps(code)
3879 def annotate(self, code):
3880 self.target.annotate(code)
3881 self.iterator.annotate(code)
3882 self.body.annotate(code)
3883 if self.else_clause:
3884 self.else_clause.annotate(code)
3885 self.item.annotate(code)
3888 class ForFromStatNode(LoopNode, StatNode):
3889 # for name from expr rel name rel expr
3896 # step ExprNode or None
3898 # else_clause StatNode or None
3904 # loopvar_node ExprNode (usually a NameNode or temp node)
3905 # py_loopvar_node PyTempNode or None
3906 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3908 is_py_target = False
3910 py_loopvar_node = None
3913 def analyse_declarations(self, env):
3914 self.target.analyse_target_declaration(env)
3915 self.body.analyse_declarations(env)
3916 if self.else_clause:
3917 self.else_clause.analyse_declarations(env)
3919 def analyse_expressions(self, env):
3921 self.target.analyse_target_types(env)
3922 self.bound1.analyse_types(env)
3923 self.bound2.analyse_types(env)
3924 if self.step is not None:
3925 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3926 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3927 self.step.analyse_types(env)
3929 target_type = self.target.type
3930 if self.target.type.is_numeric:
3931 loop_type = self.target.type
3933 loop_type = PyrexTypes.c_int_type
3934 if not self.bound1.type.is_pyobject:
3935 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3936 if not self.bound2.type.is_pyobject:
3937 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3938 if self.step is not None and not self.step.type.is_pyobject:
3939 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3940 self.bound1 = self.bound1.coerce_to(loop_type, env)
3941 self.bound2 = self.bound2.coerce_to(loop_type, env)
3942 if not self.bound2.is_literal:
3943 self.bound2 = self.bound2.coerce_to_temp(env)
3944 if self.step is not None:
3945 self.step = self.step.coerce_to(loop_type, env)
3946 if not self.step.is_literal:
3947 self.step = self.step.coerce_to_temp(env)
3949 target_type = self.target.type
3950 if not (target_type.is_pyobject or target_type.is_numeric):
3951 error(self.target.pos,
3952 "for-from loop variable must be c numeric type or Python object")
3953 if target_type.is_numeric:
3954 self.is_py_target = False
3955 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3956 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3957 self.loopvar_node = self.target
3958 self.py_loopvar_node = None
3960 self.is_py_target = True
3961 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3962 c_loopvar_node.allocate_temps(env)
3963 self.loopvar_node = c_loopvar_node
3964 self.py_loopvar_node = \
3965 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3966 self.bound1.allocate_temps(env)
3967 self.bound2.allocate_temps(env)
3968 if self.step is not None:
3969 self.step.allocate_temps(env)
3970 if self.is_py_target:
3971 self.py_loopvar_node.allocate_temps(env)
3972 self.target.allocate_target_temps(env, self.py_loopvar_node)
3973 #self.target.release_target_temp(env)
3974 #self.py_loopvar_node.release_temp(env)
3975 self.body.analyse_expressions(env)
3976 if self.is_py_target:
3977 c_loopvar_node.release_temp(env)
3978 if self.else_clause:
3979 self.else_clause.analyse_expressions(env)
3980 self.bound1.release_temp(env)
3981 self.bound2.release_temp(env)
3982 if self.step is not None:
3983 self.step.release_temp(env)
3985 def generate_execution_code(self, code):
3986 old_loop_labels = code.new_loop_labels()
3987 from_range = self.from_range
3988 self.bound1.generate_evaluation_code(code)
3989 self.bound2.generate_evaluation_code(code)
3990 offset, incop = self.relation_table[self.relation1]
3991 if self.step is not None:
3992 self.step.generate_evaluation_code(code)
3993 step = self.step.result()
3994 incop = "%s=%s" % (incop[0], step)
3996 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3998 loopvar_name = self.loopvar_node.result()
4000 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4002 self.bound1.result(), offset,
4003 loopvar_name, self.relation2, self.bound2.result(),
4004 loopvar_name, incop))
4005 if self.py_loopvar_node:
4006 self.py_loopvar_node.generate_evaluation_code(code)
4007 self.target.generate_assignment_code(self.py_loopvar_node, code)
4009 code.putln("%s = %s;" % (
4010 self.target.result(), loopvar_name))
4011 self.body.generate_execution_code(code)
4012 code.put_label(code.continue_label)
4013 if self.py_loopvar_node:
4014 # This mess is to make for..from loops with python targets behave
4015 # exactly like those with C targets with regards to re-assignment
4016 # of the loop variable.
4018 if self.target.entry.is_pyglobal:
4019 # We know target is a NameNode, this is the only ugly case.
4020 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4021 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4022 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4023 target_node.result_code,
4024 Naming.module_cname,
4025 self.target.entry.interned_cname,
4026 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4027 code.put_gotref(target_node.result_code)
4029 target_node = self.target
4030 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4031 from_py_node.temp_code = loopvar_name
4032 from_py_node.generate_result_code(code)
4033 if self.target.entry.is_pyglobal:
4034 code.put_decref_clear(target_node.result_code, py_object_type)
4035 code.funcstate.release_temp(target_node.result_code)
4037 if self.py_loopvar_node:
4038 # This is potentially wasteful, but we don't want the semantics to
4039 # depend on whether or not the loop is a python type.
4040 self.py_loopvar_node.generate_evaluation_code(code)
4041 self.target.generate_assignment_code(self.py_loopvar_node, code)
4042 break_label = code.break_label
4043 code.set_loop_labels(old_loop_labels)
4044 if self.else_clause:
4045 code.putln("/*else*/ {")
4046 self.else_clause.generate_execution_code(code)
4048 code.put_label(break_label)
4049 self.bound1.generate_disposal_code(code)
4050 self.bound1.free_temps(code)
4051 self.bound2.generate_disposal_code(code)
4052 self.bound2.free_temps(code)
4053 if self.step is not None:
4054 self.step.generate_disposal_code(code)
4055 self.step.free_temps(code)
4057 code.funcstate.release_temp(loopvar_name)
4060 # {relop : (initial offset, increment op)}
4067 def annotate(self, code):
4068 self.target.annotate(code)
4069 self.bound1.annotate(code)
4070 self.bound2.annotate(code)
4072 self.bound2.annotate(code)
4073 self.body.annotate(code)
4074 if self.else_clause:
4075 self.else_clause.annotate(code)
4078 class WithStatNode(StatNode):
4080 Represents a Python with statement.
4082 This is only used at parse tree level; and is not present in
4083 analysis or generation phases.
4085 # manager The with statement manager object
4086 # target Node (lhs expression)
4088 child_attrs = ["manager", "target", "body"]
4090 class TryExceptStatNode(StatNode):
4091 # try .. except statement
4094 # except_clauses [ExceptClauseNode]
4095 # else_clause StatNode or None
4096 # cleanup_list [Entry] old style temps to clean up on error
4098 child_attrs = ["body", "except_clauses", "else_clause"]
4100 def analyse_control_flow(self, env):
4101 env.start_branching(self.pos)
4102 self.body.analyse_control_flow(env)
4103 successful_try = env.control_flow # grab this for later
4104 env.next_branch(self.body.end_pos())
4105 env.finish_branching(self.body.end_pos())
4107 env.start_branching(self.except_clauses[0].pos)
4108 for except_clause in self.except_clauses:
4109 except_clause.analyse_control_flow(env)
4110 env.next_branch(except_clause.end_pos())
4112 # the else cause it executed only when the try clause finishes
4113 env.control_flow.incoming = successful_try
4114 if self.else_clause:
4115 self.else_clause.analyse_control_flow(env)
4116 env.finish_branching(self.end_pos())
4118 def analyse_declarations(self, env):
4119 self.body.analyse_declarations(env)
4120 for except_clause in self.except_clauses:
4121 except_clause.analyse_declarations(env)
4122 if self.else_clause:
4123 self.else_clause.analyse_declarations(env)
4125 env.use_utility_code(reset_exception_utility_code)
4127 def analyse_expressions(self, env):
4128 self.body.analyse_expressions(env)
4129 self.cleanup_list = env.free_temp_entries[:]
4130 default_clause_seen = 0
4131 for except_clause in self.except_clauses:
4132 except_clause.analyse_expressions(env)
4133 if default_clause_seen:
4134 error(except_clause.pos, "default 'except:' must be last")
4135 if not except_clause.pattern:
4136 default_clause_seen = 1
4137 self.has_default_clause = default_clause_seen
4138 if self.else_clause:
4139 self.else_clause.analyse_expressions(env)
4142 gil_message = "Try-except statement"
4144 def generate_execution_code(self, code):
4145 old_return_label = code.return_label
4146 old_break_label = code.break_label
4147 old_continue_label = code.continue_label
4148 old_error_label = code.new_error_label()
4149 our_error_label = code.error_label
4150 except_end_label = code.new_label('exception_handled')
4151 except_error_label = code.new_label('except_error')
4152 except_return_label = code.new_label('except_return')
4153 try_return_label = code.new_label('try_return')
4154 try_break_label = code.new_label('try_break')
4155 try_continue_label = code.new_label('try_continue')
4156 try_end_label = code.new_label('try_end')
4159 code.putln("PyObject %s;" %
4160 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4161 code.putln("__Pyx_ExceptionSave(%s);" %
4162 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4163 for var in Naming.exc_save_vars:
4164 code.put_xgotref(var)
4167 code.return_label = try_return_label
4168 code.break_label = try_break_label
4169 code.continue_label = try_continue_label
4170 self.body.generate_execution_code(code)
4173 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4174 code.error_label = except_error_label
4175 code.return_label = except_return_label
4176 if self.else_clause:
4179 self.else_clause.generate_execution_code(code)
4182 for var in Naming.exc_save_vars:
4183 code.put_xdecref_clear(var, py_object_type)
4184 code.put_goto(try_end_label)
4185 if code.label_used(try_return_label):
4186 code.put_label(try_return_label)
4187 for var in Naming.exc_save_vars:
4188 code.put_xdecref_clear(var, py_object_type)
4189 code.put_goto(old_return_label)
4190 code.put_label(our_error_label)
4191 code.put_var_xdecrefs_clear(self.cleanup_list)
4192 for temp_name, type in temps_to_clean_up:
4193 code.put_xdecref_clear(temp_name, type)
4194 for except_clause in self.except_clauses:
4195 except_clause.generate_handling_code(code, except_end_label)
4197 error_label_used = code.label_used(except_error_label)
4198 if error_label_used or not self.has_default_clause:
4199 if error_label_used:
4200 code.put_label(except_error_label)
4201 for var in Naming.exc_save_vars:
4202 code.put_xdecref(var, py_object_type)
4203 code.put_goto(old_error_label)
4205 if code.label_used(try_break_label):
4206 code.put_label(try_break_label)
4207 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4208 code.putln("__Pyx_ExceptionReset(%s);" %
4209 ', '.join(Naming.exc_save_vars))
4210 code.put_goto(old_break_label)
4212 if code.label_used(try_continue_label):
4213 code.put_label(try_continue_label)
4214 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4215 code.putln("__Pyx_ExceptionReset(%s);" %
4216 ', '.join(Naming.exc_save_vars))
4217 code.put_goto(old_continue_label)
4219 if code.label_used(except_return_label):
4220 code.put_label(except_return_label)
4221 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4222 code.putln("__Pyx_ExceptionReset(%s);" %
4223 ', '.join(Naming.exc_save_vars))
4224 code.put_goto(old_return_label)
4226 if code.label_used(except_end_label):
4227 code.put_label(except_end_label)
4228 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4229 code.putln("__Pyx_ExceptionReset(%s);" %
4230 ', '.join(Naming.exc_save_vars))
4231 code.put_label(try_end_label)
4234 code.return_label = old_return_label
4235 code.break_label = old_break_label
4236 code.continue_label = old_continue_label
4237 code.error_label = old_error_label
4239 def annotate(self, code):
4240 self.body.annotate(code)
4241 for except_node in self.except_clauses:
4242 except_node.annotate(code)
4243 if self.else_clause:
4244 self.else_clause.annotate(code)
4247 class ExceptClauseNode(Node):
4248 # Part of try ... except statement.
4251 # target ExprNode or None
4253 # excinfo_target NameNode or None optional target for exception info
4254 # match_flag string result of exception match
4255 # exc_value ExcValueNode used internally
4256 # function_name string qualified name of enclosing function
4257 # exc_vars (string * 3) local exception variables
4259 # excinfo_target is never set by the parser, but can be set by a transform
4260 # in order to extract more extensive information about the exception as a
4261 # sys.exc_info()-style tuple into a target variable
4263 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4266 excinfo_target = None
4268 def analyse_declarations(self, env):
4270 self.target.analyse_target_declaration(env)
4271 if self.excinfo_target is not None:
4272 self.excinfo_target.analyse_target_declaration(env)
4273 self.body.analyse_declarations(env)
4275 def analyse_expressions(self, env):
4277 genv = env.global_scope()
4278 self.function_name = env.qualified_name
4280 self.pattern.analyse_expressions(env)
4281 self.pattern = self.pattern.coerce_to_pyobject(env)
4282 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4283 self.pattern.release_temp(env)
4284 env.release_temp(self.match_flag)
4286 if self.target or self.excinfo_target:
4287 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4289 self.exc_vars = None
4292 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4293 self.exc_value.allocate_temps(env)
4294 self.target.analyse_target_expression(env, self.exc_value)
4295 if self.excinfo_target is not None:
4297 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4298 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4299 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4300 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4302 self.excinfo_tuple.analyse_expressions(env)
4303 self.excinfo_tuple.allocate_temps(env)
4304 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4306 self.body.analyse_expressions(env)
4309 for var in self.exc_vars:
4310 env.release_temp(var)
4312 def generate_handling_code(self, code, end_label):
4313 code.mark_pos(self.pos)
4315 self.pattern.generate_evaluation_code(code)
4317 "%s = PyErr_ExceptionMatches(%s);" % (
4319 self.pattern.py_result()))
4320 self.pattern.generate_disposal_code(code)
4321 self.pattern.free_temps(code)
4326 code.putln("/*except:*/ {")
4329 exc_vars = self.exc_vars
4330 elif not getattr(self.body, 'stats', True):
4331 # most simple case: no exception variable, empty body (pass)
4332 # => reset the exception state, done
4333 code.putln("PyErr_Restore(0,0,0);")
4334 code.put_goto(end_label)
4338 # during type analysis, we didn't know if we need the
4339 # exception value, but apparently, we do
4340 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4344 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4345 # We always have to fetch the exception value even if
4346 # there is no target, because this also normalises the
4347 # exception and stores it in the thread state.
4348 code.globalstate.use_utility_code(get_exception_utility_code)
4349 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4350 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4351 code.error_goto(self.pos)))
4355 self.exc_value.generate_evaluation_code(code)
4356 self.target.generate_assignment_code(self.exc_value, code)
4357 if self.excinfo_target is not None:
4358 self.excinfo_tuple.generate_evaluation_code(code)
4359 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4362 old_break_label, old_continue_label = code.break_label, code.continue_label
4363 code.break_label = code.new_label('except_break')
4364 code.continue_label = code.new_label('except_continue')
4366 old_exc_vars = code.funcstate.exc_vars
4367 code.funcstate.exc_vars = exc_vars
4368 self.body.generate_execution_code(code)
4369 code.funcstate.exc_vars = old_exc_vars
4370 for var in exc_vars:
4371 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4372 code.put_goto(end_label)
4374 if code.label_used(code.break_label):
4375 code.put_label(code.break_label)
4376 for var in exc_vars:
4377 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4378 code.put_goto(old_break_label)
4379 code.break_label = old_break_label
4381 if code.label_used(code.continue_label):
4382 code.put_label(code.continue_label)
4383 for var in exc_vars:
4384 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4385 code.put_goto(old_continue_label)
4386 code.continue_label = old_continue_label
4388 if not self.exc_vars:
4389 # clean up locally allocated temps
4390 for temp in exc_vars:
4391 code.funcstate.release_temp(temp)
4396 def annotate(self, code):
4398 self.pattern.annotate(code)
4400 self.target.annotate(code)
4401 self.body.annotate(code)
4404 class TryFinallyStatNode(StatNode):
4405 # try ... finally statement
4408 # finally_clause StatNode
4410 # cleanup_list [Entry] old_style temps to clean up on error
4412 # The plan is that we funnel all continue, break
4413 # return and error gotos into the beginning of the
4414 # finally block, setting a variable to remember which
4415 # one we're doing. At the end of the finally block, we
4416 # switch on the variable to figure out where to go.
4417 # In addition, if we're doing an error, we save the
4418 # exception on entry to the finally block and restore
4421 child_attrs = ["body", "finally_clause"]
4423 preserve_exception = 1
4425 disallow_continue_in_try_finally = 0
4426 # There doesn't seem to be any point in disallowing
4427 # continue in the try block, since we have no problem
4430 def create_analysed(pos, env, body, finally_clause):
4431 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4432 node.cleanup_list = []
4434 create_analysed = staticmethod(create_analysed)
4436 def analyse_control_flow(self, env):
4437 env.start_branching(self.pos)
4438 self.body.analyse_control_flow(env)
4439 env.next_branch(self.body.end_pos())
4440 env.finish_branching(self.body.end_pos())
4441 self.finally_clause.analyse_control_flow(env)
4443 def analyse_declarations(self, env):
4444 self.body.analyse_declarations(env)
4445 self.finally_clause.analyse_declarations(env)
4447 def analyse_expressions(self, env):
4448 self.body.analyse_expressions(env)
4449 self.cleanup_list = env.free_temp_entries[:]
4450 self.finally_clause.analyse_expressions(env)
4453 gil_message = "Try-finally statement"
4455 def generate_execution_code(self, code):
4456 old_error_label = code.error_label
4457 old_labels = code.all_new_labels()
4458 new_labels = code.get_all_labels()
4459 new_error_label = code.error_label
4460 catch_label = code.new_label()
4463 if self.disallow_continue_in_try_finally:
4464 was_in_try_finally = code.funcstate.in_try_finally
4465 code.funcstate.in_try_finally = 1
4466 self.body.generate_execution_code(code)
4467 if self.disallow_continue_in_try_finally:
4468 code.funcstate.in_try_finally = was_in_try_finally
4471 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4475 error_label_used = 0
4476 for i, new_label in enumerate(new_labels):
4477 if new_label in code.labels_used:
4478 cases_used.append(i)
4479 if new_label == new_error_label:
4480 error_label_used = 1
4481 error_label_case = i
4485 if error_label_used and self.preserve_exception:
4487 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4489 "int %s;" % Naming.exc_lineno_name)
4490 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4491 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4492 code.putln(exc_var_init_zero)
4494 exc_var_init_zero = None
4495 code.use_label(catch_label)
4497 "__pyx_why = 0; goto %s;" % catch_label)
4498 for i in cases_used:
4499 new_label = new_labels[i]
4500 #if new_label and new_label != "<try>":
4501 if new_label == new_error_label and self.preserve_exception:
4502 self.put_error_catcher(code,
4503 new_error_label, i+1, catch_label, temps_to_clean_up)
4505 code.put('%s: ' % new_label)
4506 if exc_var_init_zero:
4507 code.putln(exc_var_init_zero)
4508 code.putln("__pyx_why = %s; goto %s;" % (
4511 code.put_label(catch_label)
4512 code.set_all_labels(old_labels)
4513 if error_label_used:
4514 code.new_error_label()
4515 finally_error_label = code.error_label
4516 self.finally_clause.generate_execution_code(code)
4517 if error_label_used:
4518 if finally_error_label in code.labels_used and self.preserve_exception:
4519 over_label = code.new_label()
4520 code.put_goto(over_label);
4521 code.put_label(finally_error_label)
4522 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4523 for var in Naming.exc_vars:
4524 code.putln("Py_XDECREF(%s);" % var)
4526 code.put_goto(old_error_label)
4527 code.put_label(over_label)
4528 code.error_label = old_error_label
4531 "switch (__pyx_why) {")
4532 for i in cases_used:
4533 old_label = old_labels[i]
4534 if old_label == old_error_label and self.preserve_exception:
4535 self.put_error_uncatcher(code, i+1, old_error_label)
4537 code.use_label(old_label)
4539 "case %s: goto %s;" % (
4547 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4548 code.globalstate.use_utility_code(restore_exception_utility_code)
4555 code.put_var_xdecrefs_clear(self.cleanup_list)
4556 for temp_name, type in temps_to_clean_up:
4557 code.put_xdecref_clear(temp_name, type)
4559 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4563 Naming.exc_lineno_name, Naming.lineno_cname))
4567 code.put_goto(catch_label)
4571 def put_error_uncatcher(self, code, i, error_label):
4572 code.globalstate.use_utility_code(restore_exception_utility_code)
4577 "__Pyx_ErrRestore(%s, %s, %s);" %
4581 Naming.lineno_cname, Naming.exc_lineno_name))
4582 for var in Naming.exc_vars:
4586 code.put_goto(error_label)
4590 def annotate(self, code):
4591 self.body.annotate(code)
4592 self.finally_clause.annotate(code)
4595 class GILStatNode(TryFinallyStatNode):
4596 # 'with gil' or 'with nogil' statement
4598 # state string 'gil' or 'nogil'
4602 preserve_exception = 0
4604 def __init__(self, pos, state, body):
4606 TryFinallyStatNode.__init__(self, pos,
4608 finally_clause = GILExitNode(pos, state = state))
4610 def analyse_expressions(self, env):
4611 env.use_utility_code(force_init_threads_utility_code)
4612 was_nogil = env.nogil
4614 TryFinallyStatNode.analyse_expressions(self, env)
4615 env.nogil = was_nogil
4617 def gil_check(self, env):
4620 def generate_execution_code(self, code):
4621 code.mark_pos(self.pos)
4622 if self.state == 'gil':
4623 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4625 code.putln("{ PyThreadState *_save;")
4626 code.putln("Py_UNBLOCK_THREADS")
4627 TryFinallyStatNode.generate_execution_code(self, code)
4631 class GILExitNode(StatNode):
4632 # Used as the 'finally' block in a GILStatNode
4634 # state string 'gil' or 'nogil'
4638 def analyse_expressions(self, env):
4641 def generate_execution_code(self, code):
4642 if self.state == 'gil':
4643 code.putln("PyGILState_Release();")
4645 code.putln("Py_BLOCK_THREADS")
4648 class CImportStatNode(StatNode):
4651 # module_name string Qualified name of module being imported
4652 # as_name string or None Name specified in "as" clause, if any
4656 def analyse_declarations(self, env):
4657 if not env.is_module_scope:
4658 error(self.pos, "cimport only allowed at module level")
4660 module_scope = env.find_module(self.module_name, self.pos)
4661 if "." in self.module_name:
4662 names = [EncodedString(name) for name in self.module_name.split(".")]
4664 top_module_scope = env.context.find_submodule(top_name)
4665 module_scope = top_module_scope
4666 for name in names[1:]:
4667 submodule_scope = module_scope.find_submodule(name)
4668 module_scope.declare_module(name, submodule_scope, self.pos)
4669 module_scope = submodule_scope
4671 env.declare_module(self.as_name, module_scope, self.pos)
4673 env.declare_module(top_name, top_module_scope, self.pos)
4675 name = self.as_name or self.module_name
4676 env.declare_module(name, module_scope, self.pos)
4678 def analyse_expressions(self, env):
4681 def generate_execution_code(self, code):
4685 class FromCImportStatNode(StatNode):
4686 # from ... cimport statement
4688 # module_name string Qualified name of module
4689 # imported_names [(pos, name, as_name, kind)] Names to be imported
4693 def analyse_declarations(self, env):
4694 if not env.is_module_scope:
4695 error(self.pos, "cimport only allowed at module level")
4697 module_scope = env.find_module(self.module_name, self.pos)
4698 env.add_imported_module(module_scope)
4699 for pos, name, as_name, kind in self.imported_names:
4701 for local_name, entry in module_scope.entries.items():
4702 env.add_imported_entry(local_name, entry, pos)
4704 entry = module_scope.lookup(name)
4706 if kind and not self.declaration_matches(entry, kind):
4707 entry.redeclared(pos)
4709 if kind == 'struct' or kind == 'union':
4710 entry = module_scope.declare_struct_or_union(name,
4711 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4712 elif kind == 'class':
4713 entry = module_scope.declare_c_class(name, pos = pos,
4714 module_name = self.module_name)
4716 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4717 if submodule_scope.parent_module is module_scope:
4718 env.declare_module(as_name or name, submodule_scope, self.pos)
4720 error(pos, "Name '%s' not declared in module '%s'"
4721 % (name, self.module_name))
4724 local_name = as_name or name
4725 env.add_imported_entry(local_name, entry, pos)
4727 def declaration_matches(self, entry, kind):
4728 if not entry.is_type:
4732 if not type.is_extension_type:
4735 if not type.is_struct_or_union:
4737 if kind != type.kind:
4741 def analyse_expressions(self, env):
4744 def generate_execution_code(self, code):
4748 class FromImportStatNode(StatNode):
4749 # from ... import statement
4752 # items [(string, NameNode)]
4753 # interned_items [(string, NameNode, ExprNode)]
4754 # item PyTempNode used internally
4755 # import_star boolean used internally
4757 child_attrs = ["module"]
4760 def analyse_declarations(self, env):
4761 for name, target in self.items:
4763 if not env.is_module_scope:
4764 error(self.pos, "import * only allowed at module level")
4766 env.has_import_star = 1
4767 self.import_star = 1
4769 target.analyse_target_declaration(env)
4771 def analyse_expressions(self, env):
4773 self.module.analyse_expressions(env)
4774 self.item = ExprNodes.PyTempNode(self.pos, env)
4775 self.item.allocate_temp(env)
4776 self.interned_items = []
4777 for name, target in self.items:
4779 for _, entry in env.entries.items():
4780 if not entry.is_type and entry.type.is_extension_type:
4781 env.use_utility_code(ExprNodes.type_test_utility_code)
4784 entry = env.lookup(target.name)
4785 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4786 continue # already cimported
4787 target.analyse_target_expression(env, None)
4788 if target.type is py_object_type:
4791 coerced_item = self.item.coerce_to(target.type, env)
4792 self.interned_items.append(
4793 (env.intern_identifier(name), target, coerced_item))
4794 #target.release_target_temp(env) # was release_temp ?!?
4795 self.module.release_temp(env)
4796 self.item.release_temp(env)
4798 def generate_execution_code(self, code):
4799 self.module.generate_evaluation_code(code)
4800 if self.import_star:
4802 'if (%s(%s) < 0) %s;' % (
4804 self.module.py_result(),
4805 code.error_goto(self.pos)))
4806 for cname, target, coerced_item in self.interned_items:
4808 '%s = PyObject_GetAttr(%s, %s); %s' % (
4810 self.module.py_result(),
4812 code.error_goto_if_null(self.item.result(), self.pos)))
4813 code.put_gotref(self.item.py_result())
4814 if coerced_item is None:
4815 target.generate_assignment_code(self.item, code)
4817 coerced_item.allocate_temp_result(code)
4818 coerced_item.generate_result_code(code)
4819 target.generate_assignment_code(coerced_item, code)
4820 if self.item.result() != coerced_item.result():
4821 code.put_decref_clear(self.item.result(), self.item.type)
4822 self.module.generate_disposal_code(code)
4823 self.module.free_temps(code)
4827 #------------------------------------------------------------------------------------
4829 # Runtime support code
4831 #------------------------------------------------------------------------------------
4833 utility_function_predeclarations = \
4836 #define INLINE __inline__
4838 #define INLINE __inline
4843 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4847 static int %(skip_dispatch_cname)s = 0;
4849 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4851 if Options.gcc_branch_hints:
4852 branch_prediction_macros = \
4855 /* Test for GCC > 2.95 */
4856 #if __GNUC__ > 2 || \
4857 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4858 #define likely(x) __builtin_expect(!!(x), 1)
4859 #define unlikely(x) __builtin_expect(!!(x), 0)
4860 #else /* __GNUC__ > 2 ... */
4861 #define likely(x) (x)
4862 #define unlikely(x) (x)
4863 #endif /* __GNUC__ > 2 ... */
4864 #else /* __GNUC__ */
4865 #define likely(x) (x)
4866 #define unlikely(x) (x)
4867 #endif /* __GNUC__ */
4870 branch_prediction_macros = \
4872 #define likely(x) (x)
4873 #define unlikely(x) (x)
4876 #get_name_predeclaration = \
4877 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4879 #get_name_interned_predeclaration = \
4880 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4882 #------------------------------------------------------------------------------------
4884 printing_utility_code = UtilityCode(
4886 static int __Pyx_Print(PyObject *, int); /*proto*/
4887 #if PY_MAJOR_VERSION >= 3
4888 static PyObject* %s = 0;
4889 static PyObject* %s = 0;
4891 """ % (Naming.print_function, Naming.print_function_kwargs),
4893 #if PY_MAJOR_VERSION < 3
4894 static PyObject *__Pyx_GetStdout(void) {
4895 PyObject *f = PySys_GetObject((char *)"stdout");
4897 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4902 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4907 if (!(f = __Pyx_GetStdout()))
4909 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4910 if (PyFile_SoftSpace(f, 1)) {
4911 if (PyFile_WriteString(" ", f) < 0)
4914 v = PyTuple_GET_ITEM(arg_tuple, i);
4915 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4917 if (PyString_Check(v)) {
4918 char *s = PyString_AsString(v);
4919 Py_ssize_t len = PyString_Size(v);
4921 isspace(Py_CHARMASK(s[len-1])) &&
4923 PyFile_SoftSpace(f, 0);
4927 if (PyFile_WriteString("\n", f) < 0)
4929 PyFile_SoftSpace(f, 0);
4934 #else /* Python 3 has a print function */
4936 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4937 PyObject* kwargs = 0;
4938 PyObject* result = 0;
4939 PyObject* end_string;
4940 if (!%(PRINT_FUNCTION)s) {
4941 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4942 if (!%(PRINT_FUNCTION)s)
4946 if (!%(PRINT_KWARGS)s) {
4947 %(PRINT_KWARGS)s = PyDict_New();
4948 if (!%(PRINT_KWARGS)s)
4950 end_string = PyUnicode_FromStringAndSize(" ", 1);
4953 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4954 Py_DECREF(end_string);
4957 Py_DECREF(end_string);
4959 kwargs = %(PRINT_KWARGS)s;
4961 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4969 """ % {'BUILTINS' : Naming.builtins_cname,
4970 'PRINT_FUNCTION' : Naming.print_function,
4971 'PRINT_KWARGS' : Naming.print_function_kwargs}
4975 printing_one_utility_code = UtilityCode(
4977 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4980 #if PY_MAJOR_VERSION < 3
4982 static int __Pyx_PrintOne(PyObject *o) {
4984 if (!(f = __Pyx_GetStdout()))
4986 if (PyFile_SoftSpace(f, 0)) {
4987 if (PyFile_WriteString(" ", f) < 0)
4990 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4992 if (PyFile_WriteString("\n", f) < 0)
4995 /* the line below is just to avoid compiler
4996 * compiler warnings about unused functions */
4997 return __Pyx_Print(NULL, 0);
5000 #else /* Python 3 has a print function */
5002 static int __Pyx_PrintOne(PyObject *o) {
5004 PyObject* arg_tuple = PyTuple_New(1);
5005 if (unlikely(!arg_tuple))
5008 PyTuple_SET_ITEM(arg_tuple, 0, o);
5009 res = __Pyx_Print(arg_tuple, 1);
5010 Py_DECREF(arg_tuple);
5016 requires=[printing_utility_code])
5020 #------------------------------------------------------------------------------------
5022 # The following function is based on do_raise() from ceval.c.
5024 raise_utility_code = UtilityCode(
5026 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5029 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5033 /* First, check the traceback argument, replacing None with NULL. */
5034 if (tb == Py_None) {
5038 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5039 PyErr_SetString(PyExc_TypeError,
5040 "raise: arg 3 must be a traceback or None");
5043 /* Next, replace a missing value with None */
5044 if (value == NULL) {
5048 #if PY_VERSION_HEX < 0x02050000
5049 if (!PyClass_Check(type))
5051 if (!PyType_Check(type))
5054 /* Raising an instance. The value should be a dummy. */
5055 if (value != Py_None) {
5056 PyErr_SetString(PyExc_TypeError,
5057 "instance exception may not have a separate value");
5060 /* Normalize to raise <class>, <instance> */
5063 #if PY_VERSION_HEX < 0x02050000
5064 if (PyInstance_Check(type)) {
5065 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5070 PyErr_SetString(PyExc_TypeError,
5071 "raise: exception must be an old-style class or instance");
5075 type = (PyObject*) Py_TYPE(type);
5077 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5078 PyErr_SetString(PyExc_TypeError,
5079 "raise: exception class must be a subclass of BaseException");
5084 __Pyx_ErrRestore(type, value, tb);
5094 #------------------------------------------------------------------------------------
5096 reraise_utility_code = UtilityCode(
5098 static void __Pyx_ReRaise(void); /*proto*/
5101 static void __Pyx_ReRaise(void) {
5102 PyThreadState *tstate = PyThreadState_GET();
5103 PyObject* tmp_type = tstate->curexc_type;
5104 PyObject* tmp_value = tstate->curexc_value;
5105 PyObject* tmp_tb = tstate->curexc_traceback;
5106 tstate->curexc_type = tstate->exc_type;
5107 tstate->curexc_value = tstate->exc_value;
5108 tstate->curexc_traceback = tstate->exc_traceback;
5109 tstate->exc_type = 0;
5110 tstate->exc_value = 0;
5111 tstate->exc_traceback = 0;
5112 Py_XDECREF(tmp_type);
5113 Py_XDECREF(tmp_value);
5118 #------------------------------------------------------------------------------------
5120 arg_type_test_utility_code = UtilityCode(
5122 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5123 const char *name, int exact); /*proto*/
5126 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5127 const char *name, int exact)
5130 PyErr_Format(PyExc_SystemError, "Missing type object");
5133 if (none_allowed && obj == Py_None) return 1;
5135 if (Py_TYPE(obj) == type) return 1;
5138 if (PyObject_TypeCheck(obj, type)) return 1;
5140 PyErr_Format(PyExc_TypeError,
5141 "Argument '%s' has incorrect type (expected %s, got %s)",
5142 name, type->tp_name, Py_TYPE(obj)->tp_name);
5147 #------------------------------------------------------------------------------------
5149 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5150 # many or too few positional arguments were found. This handles
5151 # Py_ssize_t formatting correctly.
5153 raise_argtuple_invalid_utility_code = UtilityCode(
5155 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5156 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5159 static void __Pyx_RaiseArgtupleInvalid(
5160 const char* func_name,
5164 Py_ssize_t num_found)
5166 Py_ssize_t num_expected;
5167 const char *number, *more_or_less;
5169 if (num_found < num_min) {
5170 num_expected = num_min;
5171 more_or_less = "at least";
5173 num_expected = num_max;
5174 more_or_less = "at most";
5177 more_or_less = "exactly";
5179 number = (num_expected == 1) ? "" : "s";
5180 PyErr_Format(PyExc_TypeError,
5181 #if PY_VERSION_HEX < 0x02050000
5182 "%s() takes %s %d positional argument%s (%d given)",
5184 "%s() takes %s %zd positional argument%s (%zd given)",
5186 func_name, more_or_less, num_expected, number, num_found);
5190 raise_keyword_required_utility_code = UtilityCode(
5192 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5195 static INLINE void __Pyx_RaiseKeywordRequired(
5196 const char* func_name,
5199 PyErr_Format(PyExc_TypeError,
5200 #if PY_MAJOR_VERSION >= 3
5201 "%s() needs keyword-only argument %U", func_name, kw_name);
5203 "%s() needs keyword-only argument %s", func_name,
5204 PyString_AS_STRING(kw_name));
5209 raise_double_keywords_utility_code = UtilityCode(
5211 static void __Pyx_RaiseDoubleKeywordsError(
5212 const char* func_name, PyObject* kw_name); /*proto*/
5215 static void __Pyx_RaiseDoubleKeywordsError(
5216 const char* func_name,
5219 PyErr_Format(PyExc_TypeError,
5220 #if PY_MAJOR_VERSION >= 3
5221 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5223 "%s() got multiple values for keyword argument '%s'", func_name,
5224 PyString_AS_STRING(kw_name));
5229 #------------------------------------------------------------------------------------
5231 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5232 # were passed to a function, or if any keywords were passed to a
5233 # function that does not accept them.
5235 keyword_string_check_utility_code = UtilityCode(
5237 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5238 const char* function_name, int kw_allowed); /*proto*/
5241 static INLINE int __Pyx_CheckKeywordStrings(
5243 const char* function_name,
5248 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5249 #if PY_MAJOR_VERSION < 3
5250 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5252 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5254 goto invalid_keyword_type;
5256 if ((!kw_allowed) && unlikely(key))
5257 goto invalid_keyword;
5259 invalid_keyword_type:
5260 PyErr_Format(PyExc_TypeError,
5261 "%s() keywords must be strings", function_name);
5264 PyErr_Format(PyExc_TypeError,
5265 #if PY_MAJOR_VERSION < 3
5266 "%s() got an unexpected keyword argument '%s'",
5267 function_name, PyString_AsString(key));
5269 "%s() got an unexpected keyword argument '%U'",
5270 function_name, key);
5276 #------------------------------------------------------------------------------------
5278 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5279 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5280 # keywords will raise an invalid keyword error.
5282 # Three kinds of errors are checked: 1) non-string keywords, 2)
5283 # unexpected keywords and 3) overlap with positional arguments.
5285 # If num_posargs is greater 0, it denotes the number of positional
5286 # arguments that were passed and that must therefore not appear
5287 # amongst the keywords as well.
5289 # This method does not check for required keyword arguments.
5292 parse_keywords_utility_code = UtilityCode(
5294 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5295 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5296 const char* function_name); /*proto*/
5299 static int __Pyx_ParseOptionalKeywords(
5301 PyObject **argnames[],
5304 Py_ssize_t num_pos_args,
5305 const char* function_name)
5307 PyObject *key = 0, *value = 0;
5310 PyObject*** first_kw_arg = argnames + num_pos_args;
5312 while (PyDict_Next(kwds, &pos, &key, &value)) {
5313 name = first_kw_arg;
5314 while (*name && (**name != key)) name++;
5316 values[name-argnames] = value;
5318 #if PY_MAJOR_VERSION < 3
5319 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5321 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5323 goto invalid_keyword_type;
5325 for (name = first_kw_arg; *name; name++) {
5326 #if PY_MAJOR_VERSION >= 3
5327 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5328 PyUnicode_Compare(**name, key) == 0) break;
5330 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5331 _PyString_Eq(**name, key)) break;
5335 values[name-argnames] = value;
5337 /* unexpected keyword found */
5338 for (name=argnames; name != first_kw_arg; name++) {
5339 if (**name == key) goto arg_passed_twice;
5340 #if PY_MAJOR_VERSION >= 3
5341 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5342 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5344 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5345 _PyString_Eq(**name, key)) goto arg_passed_twice;
5349 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5351 goto invalid_keyword;
5359 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5361 invalid_keyword_type:
5362 PyErr_Format(PyExc_TypeError,
5363 "%s() keywords must be strings", function_name);
5366 PyErr_Format(PyExc_TypeError,
5367 #if PY_MAJOR_VERSION < 3
5368 "%s() got an unexpected keyword argument '%s'",
5369 function_name, PyString_AsString(key));
5371 "%s() got an unexpected keyword argument '%U'",
5372 function_name, key);
5379 #------------------------------------------------------------------------------------
5381 traceback_utility_code = UtilityCode(
5383 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5386 #include "compile.h"
5387 #include "frameobject.h"
5388 #include "traceback.h"
5390 static void __Pyx_AddTraceback(const char *funcname) {
5391 PyObject *py_srcfile = 0;
5392 PyObject *py_funcname = 0;
5393 PyObject *py_globals = 0;
5394 PyObject *empty_string = 0;
5395 PyCodeObject *py_code = 0;
5396 PyFrameObject *py_frame = 0;
5398 #if PY_MAJOR_VERSION < 3
5399 py_srcfile = PyString_FromString(%(FILENAME)s);
5401 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5403 if (!py_srcfile) goto bad;
5405 #if PY_MAJOR_VERSION < 3
5406 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5408 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5412 #if PY_MAJOR_VERSION < 3
5413 py_funcname = PyString_FromString(funcname);
5415 py_funcname = PyUnicode_FromString(funcname);
5418 if (!py_funcname) goto bad;
5419 py_globals = PyModule_GetDict(%(GLOBALS)s);
5420 if (!py_globals) goto bad;
5421 #if PY_MAJOR_VERSION < 3
5422 empty_string = PyString_FromStringAndSize("", 0);
5424 empty_string = PyBytes_FromStringAndSize("", 0);
5426 if (!empty_string) goto bad;
5427 py_code = PyCode_New(
5428 0, /*int argcount,*/
5429 #if PY_MAJOR_VERSION >= 3
5430 0, /*int kwonlyargcount,*/
5433 0, /*int stacksize,*/
5435 empty_string, /*PyObject *code,*/
5436 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5437 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5438 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5439 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5440 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5441 py_srcfile, /*PyObject *filename,*/
5442 py_funcname, /*PyObject *name,*/
5443 %(LINENO)s, /*int firstlineno,*/
5444 empty_string /*PyObject *lnotab*/
5446 if (!py_code) goto bad;
5447 py_frame = PyFrame_New(
5448 PyThreadState_GET(), /*PyThreadState *tstate,*/
5449 py_code, /*PyCodeObject *code,*/
5450 py_globals, /*PyObject *globals,*/
5451 0 /*PyObject *locals*/
5453 if (!py_frame) goto bad;
5454 py_frame->f_lineno = %(LINENO)s;
5455 PyTraceBack_Here(py_frame);
5457 Py_XDECREF(py_srcfile);
5458 Py_XDECREF(py_funcname);
5459 Py_XDECREF(empty_string);
5460 Py_XDECREF(py_code);
5461 Py_XDECREF(py_frame);
5464 'FILENAME': Naming.filename_cname,
5465 'LINENO': Naming.lineno_cname,
5466 'CFILENAME': Naming.cfilenm_cname,
5467 'CLINENO': Naming.clineno_cname,
5468 'GLOBALS': Naming.module_cname,
5469 'EMPTY_TUPLE' : Naming.empty_tuple,
5472 restore_exception_utility_code = UtilityCode(
5474 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5475 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5478 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5479 PyObject *tmp_type, *tmp_value, *tmp_tb;
5480 PyThreadState *tstate = PyThreadState_GET();
5482 #if PY_MAJOR_VERSION >= 3
5483 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5484 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5485 tmp_type = tstate->exc_type;
5486 tmp_value = tstate->exc_value;
5487 tmp_tb = tstate->exc_traceback;
5488 PyErr_NormalizeException(&type, &value, &tb);
5489 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5490 tstate->exc_type = 0;
5491 tstate->exc_value = 0;
5492 tstate->exc_traceback = 0;
5493 PyException_SetContext(value, tmp_value);
5494 Py_DECREF(tmp_type);
5499 tmp_type = tstate->curexc_type;
5500 tmp_value = tstate->curexc_value;
5501 tmp_tb = tstate->curexc_traceback;
5502 tstate->curexc_type = type;
5503 tstate->curexc_value = value;
5504 tstate->curexc_traceback = tb;
5505 Py_XDECREF(tmp_type);
5506 Py_XDECREF(tmp_value);
5510 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5511 PyThreadState *tstate = PyThreadState_GET();
5512 *type = tstate->curexc_type;
5513 *value = tstate->curexc_value;
5514 *tb = tstate->curexc_traceback;
5516 tstate->curexc_type = 0;
5517 tstate->curexc_value = 0;
5518 tstate->curexc_traceback = 0;
5523 #------------------------------------------------------------------------------------
5525 unraisable_exception_utility_code = UtilityCode(
5527 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5530 static void __Pyx_WriteUnraisable(const char *name) {
5531 PyObject *old_exc, *old_val, *old_tb;
5533 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5534 #if PY_MAJOR_VERSION < 3
5535 ctx = PyString_FromString(name);
5537 ctx = PyUnicode_FromString(name);
5539 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5541 PyErr_WriteUnraisable(Py_None);
5543 PyErr_WriteUnraisable(ctx);
5548 requires=[restore_exception_utility_code])
5550 #------------------------------------------------------------------------------------
5552 set_vtable_utility_code = UtilityCode(
5554 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5557 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5558 PyObject *pycobj = 0;
5561 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5564 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5577 #------------------------------------------------------------------------------------
5579 get_vtable_utility_code = UtilityCode(
5581 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5584 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5588 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5591 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5592 if (!*(void **)vtabptr)
5605 #------------------------------------------------------------------------------------
5607 init_string_tab_utility_code = UtilityCode(
5609 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5612 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5614 #if PY_MAJOR_VERSION < 3
5615 if (t->is_unicode && (!t->is_identifier)) {
5616 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5617 } else if (t->intern) {
5618 *t->p = PyString_InternFromString(t->s);
5620 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5622 #else /* Python 3+ has unicode identifiers */
5623 if (t->is_identifier || (t->is_unicode && t->intern)) {
5624 *t->p = PyUnicode_InternFromString(t->s);
5625 } else if (t->is_unicode) {
5626 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5628 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5639 #------------------------------------------------------------------------------------
5641 get_exception_utility_code = UtilityCode(
5643 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5646 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5647 PyObject *tmp_type, *tmp_value, *tmp_tb;
5648 PyThreadState *tstate = PyThreadState_GET();
5649 *type = tstate->curexc_type;
5650 *value = tstate->curexc_value;
5651 *tb = tstate->curexc_traceback;
5652 tstate->curexc_type = 0;
5653 tstate->curexc_value = 0;
5654 tstate->curexc_traceback = 0;
5655 PyErr_NormalizeException(type, value, tb);
5656 if (PyErr_Occurred())
5661 tmp_type = tstate->exc_type;
5662 tmp_value = tstate->exc_value;
5663 tmp_tb = tstate->exc_traceback;
5664 tstate->exc_type = *type;
5665 tstate->exc_value = *value;
5666 tstate->exc_traceback = *tb;
5667 /* Make sure tstate is in a consistent state when we XDECREF
5668 these objects (XDECREF may run arbitrary code). */
5669 Py_XDECREF(tmp_type);
5670 Py_XDECREF(tmp_value);
5682 #------------------------------------------------------------------------------------
5684 reset_exception_utility_code = UtilityCode(
5686 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5687 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5690 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5691 PyThreadState *tstate = PyThreadState_GET();
5692 *type = tstate->exc_type;
5693 *value = tstate->exc_value;
5694 *tb = tstate->exc_traceback;
5700 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5701 PyObject *tmp_type, *tmp_value, *tmp_tb;
5702 PyThreadState *tstate = PyThreadState_GET();
5703 tmp_type = tstate->exc_type;
5704 tmp_value = tstate->exc_value;
5705 tmp_tb = tstate->exc_traceback;
5706 tstate->exc_type = type;
5707 tstate->exc_value = value;
5708 tstate->exc_traceback = tb;
5709 Py_XDECREF(tmp_type);
5710 Py_XDECREF(tmp_value);
5715 #------------------------------------------------------------------------------------
5717 force_init_threads_utility_code = UtilityCode(
5719 #ifndef __PYX_FORCE_INIT_THREADS
5720 #if PY_VERSION_HEX < 0x02040200
5721 #define __PYX_FORCE_INIT_THREADS 1
5723 #define __PYX_FORCE_INIT_THREADS 0
5728 #------------------------------------------------------------------------------------