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
677 # is_self_arg boolean Is self argument of C method
680 arg_name = None # in case the argument name was interpreted as a type
682 def analyse(self, env, could_be_name = False):
683 # Return type descriptor.
684 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
686 if self.is_basic_c_type:
687 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
689 error(self.pos, "Unrecognised type modifier combination")
690 elif self.name == "object" and not self.module_path:
691 type = py_object_type
692 elif self.name is None:
693 if self.is_self_arg and env.is_c_class_scope:
694 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
695 type = env.parent_type
697 type = py_object_type
700 scope = env.find_imported_module(self.module_path, self.pos)
704 if scope.is_c_class_scope:
705 scope = scope.global_scope()
706 entry = scope.lookup(self.name)
707 if entry and entry.is_type:
710 if self.is_self_arg and env.is_c_class_scope:
711 type = env.parent_type
713 type = py_object_type
714 self.arg_name = self.name
716 error(self.pos, "'%s' is not a type identifier" % self.name)
720 return PyrexTypes.error_type
722 class CBufferAccessTypeNode(CBaseTypeNode):
724 # positional_args [ExprNode] List of positional arguments
725 # keyword_args DictNode Keyword arguments
726 # base_type_node CBaseTypeNode
729 # type PyrexType.BufferType ...containing the right options
732 child_attrs = ["base_type_node", "positional_args",
733 "keyword_args", "dtype_node"]
739 def analyse(self, env, could_be_name = False):
740 base_type = self.base_type_node.analyse(env)
741 if base_type.is_error: return base_type
744 options = Buffer.analyse_buffer_options(
747 self.positional_args,
749 base_type.buffer_defaults)
751 self.type = PyrexTypes.BufferType(base_type, **options)
754 class CComplexBaseTypeNode(CBaseTypeNode):
755 # base_type CBaseTypeNode
756 # declarator CDeclaratorNode
758 child_attrs = ["base_type", "declarator"]
760 def analyse(self, env, could_be_name = False):
761 base = self.base_type.analyse(env, could_be_name)
762 _, type = self.declarator.analyse(base, env)
766 class CVarDefNode(StatNode):
767 # C variable definition or forward/extern function declaration.
769 # visibility 'private' or 'public' or 'extern'
770 # base_type CBaseTypeNode
771 # declarators [CDeclaratorNode]
774 # need_properties [entry]
776 # decorators [cython.locals(...)] or None
777 # directive_locals { string : NameNode } locals defined by cython.locals(...)
779 child_attrs = ["base_type", "declarators"]
783 directive_locals = {}
785 def analyse_declarations(self, env, dest_scope = None):
788 self.dest_scope = dest_scope
789 base_type = self.base_type.analyse(env)
790 if (dest_scope.is_c_class_scope
791 and self.visibility == 'public'
792 and base_type.is_pyobject
793 and (base_type.is_builtin_type or base_type.is_extension_type)):
794 self.need_properties = []
796 visibility = 'private'
798 need_property = False
799 visibility = self.visibility
801 for declarator in self.declarators:
802 name_declarator, type = declarator.analyse(base_type, env)
803 if not type.is_complete():
804 if not (self.visibility == 'extern' and type.is_array):
805 error(declarator.pos,
806 "Variable type '%s' is incomplete" % type)
807 if self.visibility == 'extern' and type.is_pyobject:
808 error(declarator.pos,
809 "Python object cannot be declared extern")
810 name = name_declarator.name
811 cname = name_declarator.cname
813 error(declarator.pos, "Missing name in declaration.")
815 if type.is_cfunction:
816 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
817 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
819 if entry is not None:
820 entry.directive_locals = self.directive_locals
822 if self.directive_locals:
823 s.error("Decorators can only be followed by functions")
824 if self.in_pxd and self.visibility != 'extern':
826 "Only 'extern' C variable declaration allowed in .pxd file")
827 entry = dest_scope.declare_var(name, type, declarator.pos,
828 cname = cname, visibility = visibility, is_cdef = 1)
830 self.need_properties.append(entry)
831 entry.needs_property = 1
834 class CStructOrUnionDefNode(StatNode):
836 # cname string or None
837 # kind "struct" or "union"
838 # typedef_flag boolean
839 # visibility "public" or "private"
841 # attributes [CVarDefNode] or None
845 child_attrs = ["attributes"]
847 def analyse_declarations(self, env):
849 if self.visibility == 'extern' and self.packed:
850 error(self.pos, "Cannot declare extern struct as 'packed'")
851 if self.attributes is not None:
852 scope = StructOrUnionScope(self.name)
853 self.entry = env.declare_struct_or_union(
854 self.name, self.kind, scope, self.typedef_flag, self.pos,
855 self.cname, visibility = self.visibility, packed = self.packed)
856 if self.attributes is not None:
857 if self.in_pxd and not env.in_cinclude:
858 self.entry.defined_in_pxd = 1
859 for attr in self.attributes:
860 attr.analyse_declarations(env, scope)
861 if self.visibility != 'extern':
862 need_typedef_indirection = False
863 for attr in scope.var_entries:
866 type = type.base_type
867 if type == self.entry.type:
868 error(attr.pos, "Struct cannot contain itself as a member.")
869 if self.typedef_flag:
871 type = type.base_type
872 if type == self.entry.type:
873 need_typedef_indirection = True
874 if need_typedef_indirection:
875 # C can't handle typedef structs that refer to themselves.
876 struct_entry = self.entry
877 cname = env.new_const_cname()
878 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
879 struct_entry.type.typedef_flag = False
880 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
882 def analyse_expressions(self, env):
885 def generate_execution_code(self, code):
889 class CEnumDefNode(StatNode):
890 # name string or None
891 # cname string or None
892 # items [CEnumDefItemNode]
893 # typedef_flag boolean
894 # visibility "public" or "private"
898 child_attrs = ["items"]
900 def analyse_declarations(self, env):
901 self.entry = env.declare_enum(self.name, self.pos,
902 cname = self.cname, typedef_flag = self.typedef_flag,
903 visibility = self.visibility)
904 if self.items is not None:
905 if self.in_pxd and not env.in_cinclude:
906 self.entry.defined_in_pxd = 1
907 for item in self.items:
908 item.analyse_declarations(env, self.entry)
910 def analyse_expressions(self, env):
911 if self.visibility == 'public':
912 self.temp = env.allocate_temp_pyobject()
913 env.release_temp(self.temp)
915 def generate_execution_code(self, code):
916 if self.visibility == 'public':
917 for item in self.entry.enum_values:
918 code.putln("%s = PyInt_FromLong(%s); %s" % (
921 code.error_goto_if_null(self.temp, item.pos)))
922 code.put_gotref(self.temp)
923 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
927 code.error_goto(item.pos)))
928 code.put_decref_clear(self.temp, PyrexTypes.py_object_type)
931 class CEnumDefItemNode(StatNode):
933 # cname string or None
934 # value ExprNode or None
936 child_attrs = ["value"]
938 def analyse_declarations(self, env, enum_entry):
940 self.value.analyse_const_expression(env)
941 if not self.value.type.is_int:
942 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
943 self.value.analyse_const_expression(env)
944 value = self.value.result()
947 entry = env.declare_const(self.name, enum_entry.type,
948 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
949 enum_entry.enum_values.append(entry)
952 class CTypeDefNode(StatNode):
953 # base_type CBaseTypeNode
954 # declarator CDeclaratorNode
955 # visibility "public" or "private"
958 child_attrs = ["base_type", "declarator"]
960 def analyse_declarations(self, env):
961 base = self.base_type.analyse(env)
962 name_declarator, type = self.declarator.analyse(base, env)
963 name = name_declarator.name
964 cname = name_declarator.cname
965 entry = env.declare_typedef(name, type, self.pos,
966 cname = cname, visibility = self.visibility)
967 if self.in_pxd and not env.in_cinclude:
968 entry.defined_in_pxd = 1
970 def analyse_expressions(self, env):
972 def generate_execution_code(self, code):
976 class FuncDefNode(StatNode, BlockNode):
977 # Base class for function definition nodes.
979 # return_type PyrexType
980 # #filename string C name of filename string const
982 # needs_closure boolean Whether or not this function has inner functions/classes/yield
983 # directive_locals { string : NameNode } locals defined by cython.locals(...)
987 needs_closure = False
989 def analyse_default_values(self, env):
990 genv = env.global_scope()
991 for arg in self.args:
994 if not hasattr(arg, 'default_entry'):
995 arg.default.analyse_types(env)
996 arg.default = arg.default.coerce_to(arg.type, genv)
997 if arg.default.is_literal:
998 arg.default_entry = arg.default
999 arg.default_result_code = arg.default.calculate_result_code()
1000 if arg.default.type != arg.type and not arg.type.is_int:
1001 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1003 arg.default.allocate_temps(genv)
1004 arg.default_entry = genv.add_default_value(arg.type)
1005 if arg.type.is_pyobject:
1006 arg.default_entry.init = 0
1007 arg.default_entry.used = 1
1008 arg.default_result_code = arg.default_entry.cname
1011 "This argument cannot have a default value")
1014 def need_gil_acquisition(self, lenv):
1017 def create_local_scope(self, env):
1019 while env.is_py_class_scope or env.is_c_class_scope:
1020 env = env.outer_scope
1021 if self.needs_closure:
1022 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1024 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1025 lenv.return_type = self.return_type
1026 type = self.entry.type
1027 if type.is_cfunction:
1028 lenv.nogil = type.nogil and not type.with_gil
1029 self.local_scope = lenv
1030 lenv.directives = env.directives
1033 def generate_function_definitions(self, env, code):
1036 lenv = self.local_scope
1038 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1039 self.entry.scope.is_c_class_scope)
1041 # Generate C code for header and body of function
1042 code.enter_cfunc_scope()
1043 code.return_from_error_cleanup_label = code.new_label()
1045 # ----- Top-level constants used by this function
1046 code.mark_pos(self.pos)
1047 self.generate_interned_num_decls(lenv, code)
1048 self.generate_interned_string_decls(lenv, code)
1049 self.generate_py_string_decls(lenv, code)
1050 self.generate_cached_builtins_decls(lenv, code)
1052 #code.put_var_declarations(lenv.const_entries, static = 1)
1053 self.generate_const_definitions(lenv, code)
1054 # ----- Function header
1057 self.py_func.generate_function_header(code,
1058 with_pymethdef = env.is_py_class_scope,
1060 self.generate_function_header(code,
1061 with_pymethdef = env.is_py_class_scope)
1062 # ----- Local variable declarations
1063 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1064 self.generate_argument_declarations(lenv, code)
1065 if self.needs_closure:
1066 code.putln("/* TODO: declare and create scope object */")
1067 code.put_var_declarations(lenv.var_entries)
1069 if not self.return_type.is_void:
1070 if self.return_type.is_pyobject:
1074 (self.return_type.declaration_code(
1075 Naming.retval_cname),
1077 tempvardecl_code = code.insertion_point()
1078 self.generate_keyword_list(code)
1079 # ----- Extern library function declarations
1080 lenv.generate_library_function_declarations(code)
1081 # ----- GIL acquisition
1082 acquire_gil = self.need_gil_acquisition(lenv)
1084 env.use_utility_code(force_init_threads_utility_code)
1085 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1086 # ----- Automatic lead-ins for certain special functions
1088 code.put_setup_refcount_context(self.entry.name)
1089 if is_getbuffer_slot:
1090 self.getbuffer_init(code)
1091 # ----- Fetch arguments
1092 self.generate_argument_parsing_code(env, code)
1093 # If an argument is assigned to in the body, we must
1094 # incref it to properly keep track of refcounts.
1095 for entry in lenv.arg_entries:
1096 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1097 code.put_var_incref(entry)
1098 # ----- Initialise local variables
1099 for entry in lenv.var_entries:
1100 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1101 code.put_init_var_to_py_none(entry)
1102 # ----- Initialise local buffer auxiliary variables
1103 for entry in lenv.var_entries + lenv.arg_entries:
1104 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1105 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1106 # ----- Check and convert arguments
1107 self.generate_argument_type_tests(code)
1108 # ----- Acquire buffer arguments
1109 for entry in lenv.arg_entries:
1110 if entry.type.is_buffer:
1111 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1112 # ----- Function body
1113 self.body.generate_execution_code(code)
1114 # ----- Default return value
1116 if self.return_type.is_pyobject:
1117 #if self.return_type.is_extension_type:
1118 # lhs = "(PyObject *)%s" % Naming.retval_cname
1120 lhs = Naming.retval_cname
1121 code.put_init_to_py_none(lhs, self.return_type)
1123 val = self.return_type.default_value
1125 code.putln("%s = %s;" % (Naming.retval_cname, val))
1126 # ----- Error cleanup
1127 if code.error_label in code.labels_used:
1128 code.put_goto(code.return_label)
1129 code.put_label(code.error_label)
1130 # cleanup temps the old way
1131 code.put_var_xdecrefs(lenv.temp_entries)
1132 # cleanup temps the new way
1133 for cname, type in code.funcstate.all_managed_temps():
1134 code.put_xdecref(cname, type)
1136 # Clean up buffers -- this calls a Python function
1137 # so need to save and restore error state
1138 buffers_present = len(lenv.buffer_entries) > 0
1140 code.globalstate.use_utility_code(restore_exception_utility_code)
1141 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1142 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1143 for entry in lenv.buffer_entries:
1144 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1145 #code.putln("%s = 0;" % entry.cname)
1146 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1148 err_val = self.error_value()
1149 exc_check = self.caller_will_check_exceptions()
1150 if err_val is not None or exc_check:
1151 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1153 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1154 % self.entry.qualified_name, 0)
1156 '__Pyx_WriteUnraisable("%s");' %
1157 self.entry.qualified_name)
1158 env.use_utility_code(unraisable_exception_utility_code)
1159 env.use_utility_code(restore_exception_utility_code)
1160 default_retval = self.return_type.default_value
1161 if err_val is None and default_retval:
1162 err_val = default_retval
1163 if err_val is not None:
1166 Naming.retval_cname,
1169 if is_getbuffer_slot:
1170 self.getbuffer_error_cleanup(code)
1172 # If we are using the non-error cleanup section we should
1173 # jump past it if we have an error. The if-test below determine
1174 # whether this section is used.
1175 if buffers_present or is_getbuffer_slot:
1176 code.put_goto(code.return_from_error_cleanup_label)
1179 # ----- Non-error return cleanup
1180 # If you add anything here, remember to add a condition to the
1181 # if-test above in the error block (so that it can jump past this
1183 code.put_label(code.return_label)
1184 for entry in lenv.buffer_entries:
1186 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1187 if is_getbuffer_slot:
1188 self.getbuffer_normal_cleanup(code)
1189 # ----- Return cleanup for both error and no-error return
1190 code.put_label(code.return_from_error_cleanup_label)
1191 if not Options.init_local_none:
1192 for entry in lenv.var_entries:
1193 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1194 entry.xdecref_cleanup = 1
1195 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1196 # Decref any increfed args
1197 for entry in lenv.arg_entries:
1198 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1199 code.put_var_decref(entry)
1201 # code.putln("/* TODO: decref scope object */")
1203 # This code is duplicated in ModuleNode.generate_module_init_func
1205 default_retval = self.return_type.default_value
1206 err_val = self.error_value()
1207 if err_val is None and default_retval:
1208 err_val = default_retval
1209 if self.return_type.is_pyobject:
1210 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1212 code.put_finish_refcount_context()
1215 code.putln("PyGILState_Release(_save);")
1217 if not self.return_type.is_void:
1218 code.putln("return %s;" % Naming.retval_cname)
1221 # ----- Go back and insert temp variable declarations
1222 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1223 tempvardecl_code.put_temp_declarations(code.funcstate)
1224 # ----- Python version
1225 code.exit_cfunc_scope()
1227 self.py_func.generate_function_definitions(env, code)
1228 self.generate_wrapper_functions(code)
1230 def declare_argument(self, env, arg):
1231 if arg.type.is_void:
1232 error(arg.pos, "Invalid use of 'void'")
1233 elif not arg.type.is_complete() and not arg.type.is_array:
1235 "Argument type '%s' is incomplete" % arg.type)
1236 return env.declare_arg(arg.name, arg.type, arg.pos)
1238 def generate_wrapper_functions(self, code):
1241 def generate_execution_code(self, code):
1242 # Evaluate and store argument default values
1243 for arg in self.args:
1244 default = arg.default
1246 if not default.is_literal:
1247 default.generate_evaluation_code(code)
1248 default.make_owned_reference(code)
1251 arg.default_entry.cname,
1252 default.result_as(arg.default_entry.type)))
1253 if default.is_temp and default.type.is_pyobject:
1254 code.putln("%s = 0;" % default.result())
1255 default.free_temps(code)
1256 code.put_var_giveref(arg.default_entry)
1257 # For Python class methods, create and store function object
1259 self.assmt.generate_execution_code(code)
1262 # Special code for the __getbuffer__ function
1264 def getbuffer_init(self, code):
1265 info = self.local_scope.arg_entries[1].cname
1266 # Python 3.0 betas have a bug in memoryview which makes it call
1267 # getbuffer with a NULL parameter. For now we work around this;
1268 # the following line should be removed when this bug is fixed.
1269 code.putln("if (%s == NULL) return 0;" % info)
1270 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1271 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1273 def getbuffer_error_cleanup(self, code):
1274 info = self.local_scope.arg_entries[1].cname
1275 code.put_gotref("%s->obj" % info)
1276 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1279 def getbuffer_normal_cleanup(self, code):
1280 info = self.local_scope.arg_entries[1].cname
1281 code.putln("if (%s->obj == Py_None) {" % info)
1282 code.put_gotref("Py_None")
1283 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1286 class CFuncDefNode(FuncDefNode):
1287 # C function definition.
1289 # modifiers ['inline']
1290 # visibility 'private' or 'public' or 'extern'
1291 # base_type CBaseTypeNode
1292 # declarator CDeclaratorNode
1295 # decorators [DecoratorNode] list of decorators
1297 # with_gil boolean Acquire GIL around body
1299 # py_func wrapper for calling from Python
1300 # overridable whether or not this is a cpdef function
1301 # inline_in_pxd whether this is an inline function in a pxd file
1303 child_attrs = ["base_type", "declarator", "body", "py_func"]
1305 inline_in_pxd = False
1307 directive_locals = {}
1309 def unqualified_name(self):
1310 return self.entry.name
1312 def analyse_declarations(self, env):
1313 directive_locals = self.directive_locals = env.directives['locals']
1314 base_type = self.base_type.analyse(env)
1315 # The 2 here is because we need both function and argument names.
1316 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1317 if not type.is_cfunction:
1319 "Suite attached to non-function declaration")
1320 # Remember the actual type according to the function header
1321 # written here, because the type in the symbol table entry
1322 # may be different if we're overriding a C method inherited
1323 # from the base type of an extension type.
1325 type.is_overridable = self.overridable
1326 declarator = self.declarator
1327 while not hasattr(declarator, 'args'):
1328 declarator = declarator.base
1329 self.args = declarator.args
1330 for formal_arg, type_arg in zip(self.args, type.args):
1331 formal_arg.type = type_arg.type
1332 formal_arg.name = type_arg.name
1333 formal_arg.cname = type_arg.cname
1334 name = name_declarator.name
1335 cname = name_declarator.cname
1336 self.entry = env.declare_cfunction(
1337 name, type, self.pos,
1338 cname = cname, visibility = self.visibility,
1339 defining = self.body is not None,
1340 api = self.api, modifiers = self.modifiers)
1341 self.entry.inline_func_in_pxd = self.inline_in_pxd
1342 self.return_type = type.return_type
1344 if self.overridable and not env.is_module_scope:
1345 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1346 # An error will be produced in the cdef function
1347 self.overridable = False
1349 if self.overridable:
1351 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1352 self.py_func = DefNode(pos = self.pos,
1353 name = self.entry.name,
1356 starstar_arg = None,
1358 body = py_func_body,
1360 self.py_func.is_module_scope = env.is_module_scope
1361 self.py_func.analyse_declarations(env)
1362 self.entry.as_variable = self.py_func.entry
1363 # Reset scope entry the above cfunction
1364 env.entries[name] = self.entry
1365 self.py_func.interned_attr_cname = env.intern_identifier(
1366 self.py_func.entry.name)
1367 if not env.is_module_scope or Options.lookup_module_cpdef:
1368 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1369 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1371 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1373 args = self.type.args
1374 if omit_optional_args:
1375 args = args[:len(args) - self.type.optional_arg_count]
1376 arg_names = [arg.name for arg in args]
1378 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1380 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1381 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1382 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1383 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)
1384 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1386 def declare_arguments(self, env):
1387 for arg in self.type.args:
1389 error(arg.pos, "Missing argument name")
1390 self.declare_argument(env, arg)
1392 def need_gil_acquisition(self, lenv):
1394 with_gil = self.type.with_gil
1395 if type.nogil and not with_gil:
1396 if type.return_type.is_pyobject:
1398 "Function with Python return type cannot be declared nogil")
1399 for entry in lenv.var_entries + lenv.temp_entries:
1400 if entry.type.is_pyobject:
1401 error(self.pos, "Function declared nogil has Python locals or temporaries")
1404 def analyse_expressions(self, env):
1405 self.local_scope.directives = env.directives
1406 self.analyse_default_values(env)
1407 if self.py_func is not None:
1408 self.py_func.analyse_expressions(env)
1410 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1413 visibility = self.entry.visibility
1414 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1415 arg_decls.append(arg.declaration_code())
1416 if with_dispatch and self.overridable:
1417 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1418 if type.optional_arg_count and with_opt_args:
1419 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1420 if type.has_varargs:
1421 arg_decls.append("...")
1423 arg_decls = ["void"]
1425 cname = self.entry.func_cname
1426 entity = type.function_header_code(cname, ', '.join(arg_decls))
1427 if visibility == 'public':
1428 dll_linkage = "DL_EXPORT"
1431 header = self.return_type.declaration_code(entity,
1432 dll_linkage = dll_linkage)
1433 if visibility == 'extern':
1434 storage_class = "%s " % Naming.extern_c_macro
1435 elif visibility == 'public':
1438 storage_class = "static "
1439 code.putln("%s%s %s {" % (
1441 ' '.join(self.modifiers).upper(), # macro forms
1444 def generate_argument_declarations(self, env, code):
1445 for arg in self.args:
1447 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1449 def generate_keyword_list(self, code):
1452 def generate_argument_parsing_code(self, env, code):
1454 if self.type.optional_arg_count:
1455 code.putln('if (%s) {' % Naming.optional_args_cname)
1456 for arg in self.args:
1458 # FIXME: simple name prefixing doesn't work when
1459 # argument name mangling is in place
1460 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1461 declarator = arg.declarator
1462 while not hasattr(declarator, 'name'):
1463 declarator = declarator.base
1464 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1466 for _ in range(self.type.optional_arg_count):
1470 def generate_argument_conversion_code(self, code):
1473 def generate_argument_type_tests(self, code):
1474 # Generate type tests for args whose type in a parent
1475 # class is a supertype of the declared type.
1476 for arg in self.type.args:
1477 if arg.needs_type_test:
1478 self.generate_arg_type_test(arg, code)
1480 def generate_arg_type_test(self, arg, code):
1481 # Generate type test for one argument.
1482 if arg.type.typeobj_is_available():
1483 typeptr_cname = arg.type.typeptr_cname
1484 arg_code = "((PyObject *)%s)" % arg.cname
1486 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1491 type.is_builtin_type,
1492 code.error_goto(arg.pos)))
1494 error(arg.pos, "Cannot test type of extern C class "
1495 "without type object name specification")
1497 def error_value(self):
1498 if self.return_type.is_pyobject:
1502 return self.entry.type.exception_value
1504 def caller_will_check_exceptions(self):
1505 return self.entry.type.exception_check
1507 def generate_wrapper_functions(self, code):
1508 # If the C signature of a function has changed, we need to generate
1509 # wrappers to put in the slots here.
1512 func_type = entry.type
1513 while entry.prev_entry is not None:
1515 entry = entry.prev_entry
1516 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1518 self.generate_function_header(code,
1520 with_dispatch = entry.type.is_overridable,
1521 with_opt_args = entry.type.optional_arg_count,
1522 cname = entry.func_cname)
1523 if not self.return_type.is_void:
1525 args = self.type.args
1526 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1527 if entry.type.is_overridable:
1528 arglist.append(Naming.skip_dispatch_cname)
1529 elif func_type.is_overridable:
1531 if entry.type.optional_arg_count:
1532 arglist.append(Naming.optional_args_cname)
1533 elif func_type.optional_arg_count:
1534 arglist.append('NULL')
1535 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1539 class PyArgDeclNode(Node):
1540 # Argument which must be a Python object (used
1541 # for * and ** arguments).
1544 # entry Symtab.Entry
1548 class DecoratorNode(Node):
1551 # decorator NameNode or CallNode
1552 child_attrs = ['decorator']
1555 class DefNode(FuncDefNode):
1556 # A Python function definition.
1558 # name string the Python name of the function
1559 # decorators [DecoratorNode] list of decorators
1560 # args [CArgDeclNode] formal arguments
1561 # star_arg PyArgDeclNode or None * argument
1562 # starstar_arg PyArgDeclNode or None ** argument
1563 # doc EncodedString or None
1566 # The following subnode is constructed internally
1567 # when the def statement is inside a Python class definition.
1569 # assmt AssignmentNode Function construction/assignment
1571 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1575 num_required_kw_args = 0
1576 reqd_kw_flags_cname = "0"
1582 def __init__(self, pos, **kwds):
1583 FuncDefNode.__init__(self, pos, **kwds)
1585 for arg in self.args:
1592 self.num_kwonly_args = k
1593 self.num_required_kw_args = rk
1594 self.num_required_args = r
1596 def as_cfunction(self, cfunc=None, scope=None):
1598 error(self.star_arg.pos, "cdef function cannot have star argument")
1599 if self.starstar_arg:
1600 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1603 for formal_arg in self.args:
1604 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1605 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1607 type = py_object_type,
1608 pos = formal_arg.pos))
1609 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1611 has_varargs = False,
1612 exception_value = None,
1613 exception_check = False,
1616 is_overridable = True)
1617 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1619 cfunc_type = cfunc.type
1620 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1621 error(self.pos, "wrong number of arguments")
1622 error(declarator.pos, "previous declaration here")
1623 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1624 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1625 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1626 formal_arg.type = type_arg.type
1627 formal_arg.name_declarator = name_declarator
1629 if cfunc_type.exception_value is None:
1630 exception_value = None
1632 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1633 declarator = CFuncDeclaratorNode(self.pos,
1634 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1636 has_varargs = False,
1637 exception_check = cfunc_type.exception_check,
1638 exception_value = exception_value,
1639 with_gil = cfunc_type.with_gil,
1640 nogil = cfunc_type.nogil)
1641 return CFuncDefNode(self.pos,
1643 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1644 declarator = declarator,
1647 overridable = cfunc_type.is_overridable,
1649 with_gil = cfunc_type.with_gil,
1650 nogil = cfunc_type.nogil,
1651 visibility = 'private',
1653 directive_locals = getattr(cfunc, 'directive_locals', {}))
1655 def analyse_declarations(self, env):
1656 directive_locals = self.directive_locals = env.directives['locals']
1657 for arg in self.args:
1658 if hasattr(arg, 'name'):
1660 name_declarator = None
1662 base_type = arg.base_type.analyse(env)
1663 name_declarator, type = \
1664 arg.declarator.analyse(base_type, env)
1665 arg.name = name_declarator.name
1666 if arg.name in directive_locals:
1667 type_node = directive_locals[arg.name]
1668 other_type = type_node.analyse_as_type(env)
1669 if other_type is None:
1670 error(type_node.pos, "Not a type")
1671 elif (type is not PyrexTypes.py_object_type
1672 and not type.same_as(other_type)):
1673 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1674 error(type_node.pos, "Previous declaration here")
1677 if name_declarator and name_declarator.cname:
1679 "Python function argument cannot have C name specification")
1680 arg.type = type.as_argument_type()
1682 arg.needs_conversion = 0
1683 arg.needs_type_test = 0
1685 if arg.not_none and not arg.type.is_extension_type:
1687 "Only extension type arguments can have 'not None'")
1688 self.declare_pyfunction(env)
1689 self.analyse_signature(env)
1690 self.return_type = self.entry.signature.return_type()
1692 def analyse_signature(self, env):
1693 any_type_tests_needed = 0
1694 # Use the simpler calling signature for zero- and one-argument functions.
1695 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1696 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1697 if len(self.args) == 0:
1698 self.entry.signature = TypeSlots.pyfunction_noargs
1699 elif len(self.args) == 1:
1700 if self.args[0].default is None and not self.args[0].kw_only:
1701 self.entry.signature = TypeSlots.pyfunction_onearg
1702 elif self.entry.signature is TypeSlots.pymethod_signature:
1703 if len(self.args) == 1:
1704 self.entry.signature = TypeSlots.unaryfunc
1705 elif len(self.args) == 2:
1706 if self.args[1].default is None and not self.args[1].kw_only:
1707 self.entry.signature = TypeSlots.ibinaryfunc
1708 elif self.entry.is_special:
1709 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1710 sig = self.entry.signature
1711 nfixed = sig.num_fixed_args()
1712 for i in range(nfixed):
1713 if i < len(self.args):
1716 if sig.is_self_arg(i):
1718 arg.hdr_type = arg.type = env.parent_type
1719 arg.needs_conversion = 0
1721 arg.hdr_type = sig.fixed_arg_type(i)
1722 if not arg.type.same_as(arg.hdr_type):
1723 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1724 arg.needs_type_test = 1
1725 any_type_tests_needed = 1
1727 arg.needs_conversion = 1
1728 if arg.needs_conversion:
1729 arg.hdr_cname = Naming.arg_prefix + arg.name
1731 arg.hdr_cname = Naming.var_prefix + arg.name
1733 self.bad_signature()
1735 if nfixed < len(self.args):
1736 if not sig.has_generic_args:
1737 self.bad_signature()
1738 for arg in self.args:
1739 if arg.is_generic and \
1740 (arg.type.is_extension_type or arg.type.is_builtin_type):
1741 arg.needs_type_test = 1
1742 any_type_tests_needed = 1
1743 if any_type_tests_needed:
1744 env.use_utility_code(arg_type_test_utility_code)
1746 def bad_signature(self):
1747 sig = self.entry.signature
1748 expected_str = "%d" % sig.num_fixed_args()
1749 if sig.has_generic_args:
1750 expected_str = expected_str + " or more"
1752 if name.startswith("__") and name.endswith("__"):
1753 desc = "Special method"
1757 "%s %s has wrong number of arguments "
1758 "(%d declared, %s expected)" % (
1759 desc, self.name, len(self.args), expected_str))
1761 def signature_has_nongeneric_args(self):
1762 argcount = len(self.args)
1763 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1767 def signature_has_generic_args(self):
1768 return self.entry.signature.has_generic_args
1770 def declare_pyfunction(self, env):
1771 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1773 entry = env.lookup_here(self.name)
1774 if entry and entry.type.is_cfunction and not self.is_wrapper:
1775 warning(self.pos, "Overriding cdef method with def method.", 5)
1776 entry = env.declare_pyfunction(self.name, self.pos)
1778 prefix = env.scope_prefix
1779 entry.func_cname = \
1780 Naming.pyfunc_prefix + prefix + name
1781 entry.pymethdef_cname = \
1782 Naming.pymethdef_prefix + prefix + name
1783 if Options.docstrings:
1784 entry.doc = embed_position(self.pos, self.doc)
1786 Naming.funcdoc_prefix + prefix + name
1790 def declare_arguments(self, env):
1791 for arg in self.args:
1793 error(arg.pos, "Missing argument name")
1794 if arg.needs_conversion:
1795 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1796 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1797 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1798 if arg.type.is_pyobject:
1799 arg.entry.init = "0"
1800 arg.entry.init_to_none = 0
1802 arg.entry = self.declare_argument(env, arg)
1804 arg.entry.is_self_arg = arg.is_self_arg
1805 if not arg.is_self_arg:
1806 arg.name_entry = env.get_string_const(
1807 arg.name, identifier = True)
1808 env.add_py_string(arg.name_entry, identifier = True)
1810 if arg.is_self_arg or \
1811 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1812 arg.entry.is_declared_generic = 1
1813 self.declare_python_arg(env, self.star_arg)
1814 self.declare_python_arg(env, self.starstar_arg)
1816 def declare_python_arg(self, env, arg):
1818 entry = env.declare_var(arg.name,
1819 PyrexTypes.py_object_type, arg.pos)
1822 entry.init_to_none = 0
1823 entry.xdecref_cleanup = 1
1825 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1827 def analyse_expressions(self, env):
1828 self.local_scope.directives = env.directives
1829 self.analyse_default_values(env)
1830 if env.is_py_class_scope:
1831 self.synthesize_assignment_node(env)
1833 def synthesize_assignment_node(self, env):
1835 self.assmt = SingleAssignmentNode(self.pos,
1836 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1837 rhs = ExprNodes.UnboundMethodNode(self.pos,
1838 class_cname = env.class_obj_cname,
1839 function = ExprNodes.PyCFunctionNode(self.pos,
1840 pymethdef_cname = self.entry.pymethdef_cname)))
1841 self.assmt.analyse_declarations(env)
1842 self.assmt.analyse_expressions(env)
1844 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1846 sig = self.entry.signature
1847 if sig.has_dummy_arg:
1848 arg_code_list.append(
1849 "PyObject *%s" % Naming.self_cname)
1850 for arg in self.args:
1851 if not arg.is_generic:
1853 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1855 arg_code_list.append(
1856 arg.hdr_type.declaration_code(arg.hdr_cname))
1857 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1858 arg_code_list.append("PyObject *unused")
1859 if sig.has_generic_args:
1860 arg_code_list.append(
1861 "PyObject *%s, PyObject *%s"
1862 % (Naming.args_cname, Naming.kwds_cname))
1863 arg_code = ", ".join(arg_code_list)
1864 dc = self.return_type.declaration_code(self.entry.func_cname)
1865 header = "static %s(%s)" % (dc, arg_code)
1866 code.putln("%s; /*proto*/" % header)
1869 if self.entry.doc and Options.docstrings:
1870 docstr = self.entry.doc
1871 if not isinstance(docstr, str):
1872 docstr = docstr.utf8encode()
1874 'static char %s[] = "%s";' % (
1875 self.entry.doc_cname,
1876 split_docstring(escape_byte_string(docstr))))
1879 "static PyMethodDef %s = " %
1880 self.entry.pymethdef_cname)
1881 code.put_pymethoddef(self.entry, ";")
1882 code.putln("%s {" % header)
1884 def generate_argument_declarations(self, env, code):
1885 for arg in self.args:
1886 if arg.is_generic: # or arg.needs_conversion:
1887 if arg.needs_conversion:
1888 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1890 code.put_var_declaration(arg.entry)
1892 def generate_keyword_list(self, code):
1893 if self.signature_has_generic_args() and \
1894 self.signature_has_nongeneric_args():
1896 "static PyObject **%s[] = {" %
1897 Naming.pykwdlist_cname)
1898 for arg in self.args:
1900 code.put('&%s,' % arg.name_entry.pystring_cname)
1903 def generate_argument_parsing_code(self, env, code):
1904 # Generate PyArg_ParseTuple call for generic
1905 # arguments, if any.
1906 if self.entry.signature.has_dummy_arg:
1907 # get rid of unused argument warning
1908 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1910 old_error_label = code.new_error_label()
1911 our_error_label = code.error_label
1912 end_label = code.new_label("argument_unpacking_done")
1914 has_kwonly_args = self.num_kwonly_args > 0
1915 has_star_or_kw_args = self.star_arg is not None \
1916 or self.starstar_arg is not None or has_kwonly_args
1918 if not self.signature_has_generic_args():
1919 if has_star_or_kw_args:
1920 error(self.pos, "This method cannot have * or keyword arguments")
1921 self.generate_argument_conversion_code(code)
1923 elif not self.signature_has_nongeneric_args():
1924 # func(*args) or func(**kw) or func(*args, **kw)
1925 self.generate_stararg_copy_code(code)
1928 positional_args = []
1931 for arg in self.args:
1932 arg_entry = arg.entry
1936 if not arg.is_self_arg:
1938 kw_only_args.append(arg)
1940 positional_args.append(arg)
1942 kw_only_args.append(arg)
1945 error(arg.pos, "Non-default argument following default argument")
1946 elif not arg.is_self_arg:
1947 positional_args.append(arg)
1949 self.generate_tuple_and_keyword_parsing_code(
1950 positional_args, kw_only_args, end_label, code)
1952 code.error_label = old_error_label
1953 if code.label_used(our_error_label):
1954 if not code.label_used(end_label):
1955 code.put_goto(end_label)
1956 code.put_label(our_error_label)
1957 if has_star_or_kw_args:
1958 self.generate_arg_decref(self.star_arg, code)
1959 if self.starstar_arg:
1960 if self.starstar_arg.entry.xdecref_cleanup:
1961 code.put_var_xdecref(self.starstar_arg.entry)
1963 code.put_var_decref(self.starstar_arg.entry)
1964 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1965 code.putln("return %s;" % self.error_value())
1966 if code.label_used(end_label):
1967 code.put_label(end_label)
1969 def generate_arg_assignment(self, arg, item, code):
1970 if arg.type.is_pyobject:
1972 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1973 code.putln("%s = %s;" % (arg.entry.cname, item))
1975 func = arg.type.from_py_function
1977 code.putln("%s = %s(%s); %s" % (
1981 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1983 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1985 def generate_arg_xdecref(self, arg, code):
1987 code.put_var_xdecref(arg.entry)
1989 def generate_arg_decref(self, arg, code):
1991 code.put_var_decref(arg.entry)
1993 def generate_stararg_copy_code(self, code):
1994 if not self.star_arg:
1995 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1996 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1998 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1999 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2002 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2004 if self.starstar_arg:
2006 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2008 kwarg_check = "%s" % Naming.kwds_cname
2010 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2011 Naming.kwds_cname, Naming.kwds_cname)
2013 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2014 kwarg_check, Naming.kwds_cname, self.name,
2015 bool(self.starstar_arg), self.error_value()))
2017 if self.starstar_arg:
2018 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2019 self.starstar_arg.entry.cname,
2022 code.putln("if (unlikely(!%s)) return %s;" % (
2023 self.starstar_arg.entry.cname, self.error_value()))
2024 self.starstar_arg.entry.xdecref_cleanup = 0
2025 code.put_gotref(self.starstar_arg.entry.cname)
2029 code.put_incref(Naming.args_cname, py_object_type)
2030 code.putln("%s = %s;" % (
2031 self.star_arg.entry.cname,
2033 self.star_arg.entry.xdecref_cleanup = 0
2035 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2036 kw_only_args, success_label, code):
2037 argtuple_error_label = code.new_label("argtuple_error")
2039 min_positional_args = self.num_required_args - self.num_required_kw_args
2040 if len(self.args) > 0 and self.args[0].is_self_arg:
2041 min_positional_args -= 1
2042 max_positional_args = len(positional_args)
2043 has_fixed_positional_count = not self.star_arg and \
2044 min_positional_args == max_positional_args
2046 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2047 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2048 if self.num_required_kw_args:
2049 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2051 if self.starstar_arg or self.star_arg:
2052 self.generate_stararg_init_code(max_positional_args, code)
2054 # --- optimised code when we receive keyword arguments
2055 if self.num_required_kw_args:
2056 likely_hint = "likely"
2058 likely_hint = "unlikely"
2059 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2060 self.generate_keyword_unpacking_code(
2061 min_positional_args, max_positional_args,
2062 has_fixed_positional_count,
2063 positional_args, kw_only_args, argtuple_error_label, code)
2065 # --- optimised code when we do not receive any keyword arguments
2066 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2067 # Python raises arg tuple related errors first, so we must
2068 # check the length here
2069 if min_positional_args == max_positional_args and not self.star_arg:
2073 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2074 Naming.args_cname, compare, min_positional_args))
2075 code.put_goto(argtuple_error_label)
2077 if self.num_required_kw_args:
2078 # pure error case: keywords required but not passed
2079 if max_positional_args > min_positional_args and not self.star_arg:
2080 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2081 Naming.args_cname, max_positional_args))
2082 code.put_goto(argtuple_error_label)
2083 code.putln('} else {')
2084 for i, arg in enumerate(kw_only_args):
2086 # required keyword-only argument missing
2087 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2088 self.name.utf8encode(),
2089 arg.name_entry.pystring_cname))
2090 code.putln(code.error_goto(self.pos))
2093 elif min_positional_args == max_positional_args:
2094 # parse the exact number of positional arguments from the
2096 code.putln('} else {')
2097 for i, arg in enumerate(positional_args):
2098 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2099 self.generate_arg_assignment(arg, item, code)
2100 self.generate_arg_default_assignments(code)
2103 # parse the positional arguments from the variable length
2105 code.putln('} else {')
2106 self.generate_arg_default_assignments(code)
2107 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2109 code.putln('default:')
2110 reversed_args = list(enumerate(positional_args))[::-1]
2111 for i, arg in reversed_args:
2112 if i >= min_positional_args-1:
2113 if min_positional_args > 1:
2114 code.putln('case %2d:' % (i+1)) # pure code beautification
2116 code.put('case %2d: ' % (i+1))
2117 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2118 self.generate_arg_assignment(arg, item, code)
2119 if min_positional_args == 0:
2120 code.put('case 0: ')
2121 code.putln('break;')
2123 if min_positional_args:
2124 for i in range(min_positional_args-1, -1, -1):
2125 code.putln('case %2d:' % i)
2126 code.put_goto(argtuple_error_label)
2128 code.put('default: ')
2129 code.put_goto(argtuple_error_label)
2134 if code.label_used(argtuple_error_label):
2135 code.put_goto(success_label)
2136 code.put_label(argtuple_error_label)
2137 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2138 self.name.utf8encode(), has_fixed_positional_count,
2139 min_positional_args, max_positional_args,
2141 code.putln(code.error_goto(self.pos))
2143 def generate_arg_default_assignments(self, code):
2144 for arg in self.args:
2145 if arg.is_generic and arg.default:
2149 arg.default_result_code))
2151 def generate_stararg_init_code(self, max_positional_args, code):
2152 if self.starstar_arg:
2153 self.starstar_arg.entry.xdecref_cleanup = 0
2154 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2155 self.starstar_arg.entry.cname,
2156 self.starstar_arg.entry.cname,
2157 self.error_value()))
2158 code.put_gotref(self.starstar_arg.entry.cname)
2160 self.star_arg.entry.xdecref_cleanup = 0
2161 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2163 max_positional_args))
2164 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2165 self.star_arg.entry.cname, Naming.args_cname,
2166 max_positional_args, Naming.args_cname))
2167 code.put_gotref(self.star_arg.entry.cname)
2168 if self.starstar_arg:
2170 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2171 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2172 code.putln('return %s;' % self.error_value())
2175 code.putln("if (unlikely(!%s)) return %s;" % (
2176 self.star_arg.entry.cname, self.error_value()))
2177 code.putln('} else {')
2178 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2179 code.put_incref(Naming.empty_tuple, py_object_type)
2182 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2183 has_fixed_positional_count, positional_args,
2184 kw_only_args, argtuple_error_label, code):
2185 all_args = tuple(positional_args) + tuple(kw_only_args)
2186 max_args = len(all_args)
2189 for i, arg in enumerate(all_args):
2190 if arg.default and arg.type.is_pyobject:
2191 default_value = arg.default_result_code
2192 if arg.type is not PyrexTypes.py_object_type:
2193 default_value = "(PyObject*)"+default_value
2194 default_args.append((i, default_value))
2196 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2198 # it looks funny to separate the init-to-0 from setting the
2199 # default value, but C89 needs this
2200 code.putln("PyObject* values[%d] = {%s};" % (
2201 max_args, ','.join(['0']*max_args)))
2202 for i, default_value in default_args:
2203 code.putln('values[%d] = %s;' % (i, default_value))
2205 # parse the tuple and check that it's not too long
2206 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2208 code.putln('default:')
2209 for i in range(max_positional_args-1, -1, -1):
2210 code.put('case %2d: ' % (i+1))
2211 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2212 i, Naming.args_cname, i))
2213 code.putln('case 0: break;')
2214 if not self.star_arg:
2215 code.put('default: ') # more arguments than allowed
2216 code.put_goto(argtuple_error_label)
2219 # now fill up the positional/required arguments with values
2221 if self.num_required_args or max_positional_args > 0:
2222 last_required_arg = -1
2223 for i, arg in enumerate(all_args):
2225 last_required_arg = i
2226 if last_required_arg < max_positional_args:
2227 last_required_arg = max_positional_args-1
2228 num_required_args = self.num_required_args
2229 if max_positional_args > 0:
2230 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2231 for i, arg in enumerate(all_args[:last_required_arg+1]):
2232 if max_positional_args > 0 and i <= max_positional_args:
2233 if self.star_arg and i == max_positional_args:
2234 code.putln('default:')
2236 code.putln('case %2d:' % i)
2239 # handled separately below
2241 code.putln('if (kw_args > %d) {' % num_required_args)
2242 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2243 Naming.kwds_cname, arg.name_entry.pystring_cname))
2244 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2247 num_required_args -= 1
2248 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2249 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2250 code.putln('if (likely(values[%d])) kw_args--;' % i);
2251 if i < min_positional_args:
2253 # special case: we know arg 0 is missing
2255 code.put_goto(argtuple_error_label)
2257 # print the correct number of values (args or
2258 # kwargs) that were passed into positional
2259 # arguments up to this point
2260 code.putln('else {')
2261 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2262 self.name.utf8encode(), has_fixed_positional_count,
2263 min_positional_args, max_positional_args, i))
2264 code.putln(code.error_goto(self.pos))
2267 code.putln('else {')
2268 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2269 self.name.utf8encode(), arg.name_entry.pystring_cname))
2270 code.putln(code.error_goto(self.pos))
2272 if max_positional_args > 0:
2275 if kw_only_args and not self.starstar_arg:
2276 # unpack optional keyword-only arguments
2277 # checking for interned strings in a dict is faster than iterating
2278 # but it's too likely that we must iterate if we expect **kwargs
2280 for i, arg in enumerate(all_args[max_positional_args:]):
2281 if not arg.kw_only or not arg.default:
2283 optional_args.append((i+max_positional_args, arg))
2285 # this mimics an unrolled loop so that we can "break" out of it
2286 code.putln('while (kw_args > 0) {')
2287 code.putln('PyObject* value;')
2288 for i, arg in optional_args:
2290 'value = PyDict_GetItem(%s, %s);' % (
2291 Naming.kwds_cname, arg.name_entry.pystring_cname))
2293 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2294 code.putln('break;')
2297 code.putln('if (unlikely(kw_args > 0)) {')
2298 # non-positional/-required kw args left in dict: default args,
2299 # kw-only args, **kwargs or error
2301 # This is sort of a catch-all: except for checking required
2302 # arguments, this will always do the right thing for unpacking
2303 # keyword arguments, so that we can concentrate on optimising
2304 # common cases above.
2305 if max_positional_args == 0:
2308 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2309 Naming.args_cname, max_positional_args,
2310 Naming.args_cname, max_positional_args))
2311 pos_arg_count = "used_pos_args"
2313 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2314 code.globalstate.use_utility_code(parse_keywords_utility_code)
2316 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2318 Naming.pykwdlist_cname,
2319 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2321 self.name.utf8encode()))
2322 code.putln(code.error_goto(self.pos))
2325 # convert arg values to their final type and assign them
2326 for i, arg in enumerate(all_args):
2327 if arg.default and not arg.type.is_pyobject:
2328 code.putln("if (values[%d]) {" % i)
2329 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2330 if arg.default and not arg.type.is_pyobject:
2331 code.putln('} else {')
2335 arg.default_result_code))
2338 def generate_argument_conversion_code(self, code):
2339 # Generate code to convert arguments from
2340 # signature type to declared type, if needed.
2341 for arg in self.args:
2342 if arg.needs_conversion:
2343 self.generate_arg_conversion(arg, code)
2345 def generate_arg_conversion(self, arg, code):
2346 # Generate conversion code for one argument.
2347 old_type = arg.hdr_type
2349 if old_type.is_pyobject:
2351 code.putln("if (%s) {" % arg.hdr_cname)
2353 code.putln("assert(%s); {" % arg.hdr_cname)
2354 self.generate_arg_conversion_from_pyobject(arg, code)
2356 elif new_type.is_pyobject:
2357 self.generate_arg_conversion_to_pyobject(arg, code)
2359 if new_type.assignable_from(old_type):
2361 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2364 "Cannot convert 1 argument from '%s' to '%s'" %
2365 (old_type, new_type))
2367 def generate_arg_conversion_from_pyobject(self, arg, code):
2369 func = new_type.from_py_function
2370 # copied from CoerceFromPyTypeNode
2372 code.putln("%s = %s(%s); %s" % (
2376 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2379 "Cannot convert Python object argument to type '%s'"
2382 def generate_arg_conversion_to_pyobject(self, arg, code):
2383 old_type = arg.hdr_type
2384 func = old_type.to_py_function
2386 code.putln("%s = %s(%s); %s" % (
2390 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2391 code.put_var_gotref(arg.entry)
2394 "Cannot convert argument of type '%s' to Python object"
2397 def generate_argument_type_tests(self, code):
2398 # Generate type tests for args whose signature
2399 # type is PyObject * and whose declared type is
2400 # a subtype thereof.
2401 for arg in self.args:
2402 if arg.needs_type_test:
2403 self.generate_arg_type_test(arg, code)
2405 def generate_arg_type_test(self, arg, code):
2406 # Generate type test for one argument.
2407 if arg.type.typeobj_is_available():
2408 typeptr_cname = arg.type.typeptr_cname
2409 arg_code = "((PyObject *)%s)" % arg.entry.cname
2411 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2416 arg.type.is_builtin_type,
2417 code.error_goto(arg.pos)))
2419 error(arg.pos, "Cannot test type of extern C class "
2420 "without type object name specification")
2422 def error_value(self):
2423 return self.entry.signature.error_value
2425 def caller_will_check_exceptions(self):
2428 class OverrideCheckNode(StatNode):
2429 # A Node for dispatching to the def method if it
2438 child_attrs = ['body']
2442 def analyse_expressions(self, env):
2443 self.args = env.arg_entries
2444 if self.py_func.is_module_scope:
2449 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2450 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2451 call_node = ExprNodes.SimpleCallNode(self.pos,
2452 function=self.func_node,
2453 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2454 self.body = ReturnStatNode(self.pos, value=call_node)
2455 self.body.analyse_expressions(env)
2457 def generate_execution_code(self, code):
2458 # Check to see if we are an extension type
2459 if self.py_func.is_module_scope:
2460 self_arg = "((PyObject *)%s)" % Naming.module_cname
2462 self_arg = "((PyObject *)%s)" % self.args[0].cname
2463 code.putln("/* Check if called by wrapper */")
2464 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2465 code.putln("/* Check if overriden in Python */")
2466 if self.py_func.is_module_scope:
2467 code.putln("else {")
2469 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2470 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2471 # need to get attribute manually--scope would return cdef method
2472 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2473 code.put_gotref(self.func_node.py_result())
2474 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2475 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2476 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2477 self.body.generate_execution_code(code)
2479 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2482 class ClassDefNode(StatNode, BlockNode):
2485 class PyClassDefNode(ClassDefNode):
2486 # A Python class definition.
2488 # name EncodedString Name of the class
2489 # doc string or None
2490 # body StatNode Attribute definition code
2491 # entry Symtab.Entry
2492 # scope PyClassScope
2494 # The following subnodes are constructed internally:
2496 # dict DictNode Class dictionary
2497 # classobj ClassNode Class object
2498 # target NameNode Variable to assign class object to
2500 child_attrs = ["body", "dict", "classobj", "target"]
2502 def __init__(self, pos, name, bases, doc, body):
2503 StatNode.__init__(self, pos)
2508 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2509 if self.doc and Options.docstrings:
2510 doc = embed_position(self.pos, self.doc)
2511 doc_node = ExprNodes.StringNode(pos, value = doc)
2514 self.classobj = ExprNodes.ClassNode(pos, name = name,
2515 bases = bases, dict = self.dict, doc = doc_node)
2516 self.target = ExprNodes.NameNode(pos, name = name)
2518 def as_cclass(self):
2520 Return this node as if it were declared as an extension class
2522 bases = self.classobj.bases.args
2524 base_class_name = None
2525 base_class_module = None
2526 elif len(bases) == 1:
2529 from ExprNodes import AttributeNode, NameNode
2530 while isinstance(base, AttributeNode):
2531 path.insert(0, base.attribute)
2533 if isinstance(base, NameNode):
2534 path.insert(0, base.name)
2535 base_class_name = path[-1]
2537 base_class_module = u'.'.join(path[:-1])
2539 base_class_module = None
2541 error(self.classobj.bases.args.pos, "Invalid base class")
2543 error(self.classobj.bases.args.pos, "C class may only have one base class")
2546 return CClassDefNode(self.pos,
2547 visibility = 'private',
2549 class_name = self.name,
2550 base_class_module = base_class_module,
2551 base_class_name = base_class_name,
2556 def create_scope(self, env):
2558 while env.is_py_class_scope or env.is_c_class_scope:
2559 env = env.outer_scope
2560 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2563 def analyse_declarations(self, env):
2564 self.target.analyse_target_declaration(env)
2565 cenv = self.create_scope(env)
2566 cenv.directives = env.directives
2567 cenv.class_obj_cname = self.target.entry.cname
2568 self.body.analyse_declarations(cenv)
2570 def analyse_expressions(self, env):
2571 self.dict.analyse_expressions(env)
2572 self.classobj.analyse_expressions(env)
2573 genv = env.global_scope()
2575 cenv.class_dict_cname = self.dict.result()
2576 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2577 self.body.analyse_expressions(cenv)
2578 self.target.analyse_target_expression(env, self.classobj)
2579 self.dict.release_temp(env)
2580 #self.classobj.release_temp(env)
2581 #self.target.release_target_temp(env)
2583 def generate_function_definitions(self, env, code):
2584 self.generate_py_string_decls(self.scope, code)
2585 self.body.generate_function_definitions(self.scope, code)
2587 def generate_execution_code(self, code):
2588 self.dict.generate_evaluation_code(code)
2589 self.classobj.generate_evaluation_code(code)
2590 self.body.generate_execution_code(code)
2591 self.target.generate_assignment_code(self.classobj, code)
2592 self.dict.generate_disposal_code(code)
2593 self.dict.free_temps(code)
2596 class CClassDefNode(ClassDefNode):
2597 # An extension type definition.
2599 # visibility 'private' or 'public' or 'extern'
2600 # typedef_flag boolean
2602 # module_name string or None For import of extern type objects
2603 # class_name string Unqualified name of class
2604 # as_name string or None Name to declare as in this scope
2605 # base_class_module string or None Module containing the base class
2606 # base_class_name string or None Name of the base class
2607 # objstruct_name string or None Specified C name of object struct
2608 # typeobj_name string or None Specified C name of type object
2609 # in_pxd boolean Is in a .pxd file
2610 # doc string or None
2611 # body StatNode or None
2612 # entry Symtab.Entry
2613 # base_type PyExtensionType or None
2614 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2615 # buffer_defaults_pos
2617 child_attrs = ["body"]
2618 buffer_defaults_node = None
2619 buffer_defaults_pos = None
2620 typedef_flag = False
2622 objstruct_name = None
2625 def analyse_declarations(self, env):
2626 #print "CClassDefNode.analyse_declarations:", self.class_name
2627 #print "...visibility =", self.visibility
2628 #print "...module_name =", self.module_name
2631 if self.buffer_defaults_node:
2632 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2633 env, [], self.buffer_defaults_node,
2634 need_complete=False)
2636 buffer_defaults = None
2638 if env.in_cinclude and not self.objstruct_name:
2639 error(self.pos, "Object struct name specification required for "
2640 "C class defined in 'extern from' block")
2641 self.base_type = None
2642 # Now that module imports are cached, we need to
2643 # import the modules for extern classes.
2644 if self.module_name:
2646 for module in env.cimported_modules:
2647 if module.name == self.module_name:
2648 self.module = module
2649 if self.module is None:
2650 self.module = ModuleScope(self.module_name, None, env.context)
2651 self.module.has_extern_class = 1
2652 env.add_imported_module(self.module)
2654 if self.base_class_name:
2655 if self.base_class_module:
2656 base_class_scope = env.find_module(self.base_class_module, self.pos)
2658 base_class_scope = env
2659 if self.base_class_name == 'object':
2660 # extension classes are special and don't need to inherit from object
2661 if base_class_scope is None or base_class_scope.lookup('object') is None:
2662 self.base_class_name = None
2663 self.base_class_module = None
2664 base_class_scope = None
2665 if base_class_scope:
2666 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2667 if base_class_entry:
2668 if not base_class_entry.is_type:
2669 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2670 elif not base_class_entry.type.is_extension_type:
2671 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2672 elif not base_class_entry.type.is_complete():
2673 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2675 self.base_type = base_class_entry.type
2676 has_body = self.body is not None
2677 if self.module_name and self.visibility != 'extern':
2678 module_path = self.module_name.split(".")
2679 home_scope = env.find_imported_module(module_path, self.pos)
2685 if self.visibility == 'extern':
2686 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2687 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2689 self.entry = home_scope.declare_c_class(
2690 name = self.class_name,
2692 defining = has_body and self.in_pxd,
2693 implementing = has_body and not self.in_pxd,
2694 module_name = self.module_name,
2695 base_type = self.base_type,
2696 objstruct_cname = self.objstruct_name,
2697 typeobj_cname = self.typeobj_name,
2698 visibility = self.visibility,
2699 typedef_flag = self.typedef_flag,
2701 buffer_defaults = buffer_defaults)
2702 if home_scope is not env and self.visibility == 'extern':
2703 env.add_imported_entry(self.class_name, self.entry, pos)
2704 scope = self.entry.type.scope
2705 if scope is not None:
2706 scope.directives = env.directives
2708 if self.doc and Options.docstrings:
2709 scope.doc = embed_position(self.pos, self.doc)
2712 self.body.analyse_declarations(scope)
2716 scope.implemented = 1
2717 env.allocate_vtable_names(self.entry)
2719 def analyse_expressions(self, env):
2721 scope = self.entry.type.scope
2722 self.body.analyse_expressions(scope)
2724 def generate_function_definitions(self, env, code):
2725 self.generate_py_string_decls(self.entry.type.scope, code)
2727 self.body.generate_function_definitions(
2728 self.entry.type.scope, code)
2730 def generate_execution_code(self, code):
2731 # This is needed to generate evaluation code for
2732 # default values of method arguments.
2734 self.body.generate_execution_code(code)
2736 def annotate(self, code):
2738 self.body.annotate(code)
2741 class PropertyNode(StatNode):
2742 # Definition of a property in an extension type.
2745 # doc EncodedString or None Doc string
2748 child_attrs = ["body"]
2750 def analyse_declarations(self, env):
2751 entry = env.declare_property(self.name, self.doc, self.pos)
2753 if self.doc and Options.docstrings:
2754 doc_entry = env.get_string_const(
2755 self.doc, identifier = False)
2756 entry.doc_cname = doc_entry.cname
2757 entry.scope.directives = env.directives
2758 self.body.analyse_declarations(entry.scope)
2760 def analyse_expressions(self, env):
2761 self.body.analyse_expressions(env)
2763 def generate_function_definitions(self, env, code):
2764 self.body.generate_function_definitions(env, code)
2766 def generate_execution_code(self, code):
2769 def annotate(self, code):
2770 self.body.annotate(code)
2773 class GlobalNode(StatNode):
2774 # Global variable declaration.
2780 def analyse_declarations(self, env):
2781 for name in self.names:
2782 env.declare_global(name, self.pos)
2784 def analyse_expressions(self, env):
2787 def generate_execution_code(self, code):
2791 class ExprStatNode(StatNode):
2792 # Expression used as a statement.
2796 child_attrs = ["expr"]
2798 def analyse_declarations(self, env):
2800 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2801 func = self.expr.function.as_cython_attribute()
2802 if func == u'declare':
2803 args, kwds = self.expr.explicit_args_kwds()
2805 error(self.expr.pos, "Variable names must be specified.")
2806 for var, type_node in kwds.key_value_pairs:
2807 type = type_node.analyse_as_type(env)
2809 error(type_node.pos, "Unknown type")
2811 env.declare_var(var.value, type, var.pos, is_cdef = True)
2812 self.__class__ = PassStatNode
2814 def analyse_expressions(self, env):
2815 self.expr.analyse_expressions(env)
2816 self.expr.release_temp(env)
2818 def generate_execution_code(self, code):
2819 self.expr.generate_evaluation_code(code)
2820 if not self.expr.is_temp and self.expr.result():
2821 code.putln("%s;" % self.expr.result())
2822 self.expr.generate_disposal_code(code)
2823 self.expr.free_temps(code)
2825 def annotate(self, code):
2826 self.expr.annotate(code)
2829 class AssignmentNode(StatNode):
2830 # Abstract base class for assignment nodes.
2832 # The analyse_expressions and generate_execution_code
2833 # phases of assignments are split into two sub-phases
2834 # each, to enable all the right hand sides of a
2835 # parallel assignment to be evaluated before assigning
2836 # to any of the left hand sides.
2838 def analyse_expressions(self, env):
2839 self.analyse_types(env)
2840 self.allocate_rhs_temps(env)
2841 self.allocate_lhs_temps(env)
2843 # def analyse_expressions(self, env):
2844 # self.analyse_expressions_1(env)
2845 # self.analyse_expressions_2(env)
2847 def generate_execution_code(self, code):
2848 self.generate_rhs_evaluation_code(code)
2849 self.generate_assignment_code(code)
2852 class SingleAssignmentNode(AssignmentNode):
2853 # The simplest case:
2857 # lhs ExprNode Left hand side
2858 # rhs ExprNode Right hand side
2859 # first bool Is this guaranteed the first assignment to lhs?
2861 child_attrs = ["lhs", "rhs"]
2863 declaration_only = False
2865 def analyse_declarations(self, env):
2868 # handle declarations of the form x = cython.foo()
2869 if isinstance(self.rhs, ExprNodes.CallNode):
2870 func_name = self.rhs.function.as_cython_attribute()
2872 args, kwds = self.rhs.explicit_args_kwds()
2874 if func_name in ['declare', 'typedef']:
2875 if len(args) > 2 or kwds is not None:
2876 error(rhs.pos, "Can only declare one type at a time.")
2878 type = args[0].analyse_as_type(env)
2880 error(args[0].pos, "Unknown type")
2883 if func_name == 'declare':
2884 if isinstance(lhs, ExprNodes.NameNode):
2885 vars = [(lhs.name, lhs.pos)]
2886 elif isinstance(lhs, ExprNodes.TupleNode):
2887 vars = [(var.name, var.pos) for var in lhs.args]
2889 error(lhs.pos, "Invalid declaration")
2891 for var, pos in vars:
2892 env.declare_var(var, type, pos, is_cdef = True)
2897 self.declaration_only = True
2899 self.declaration_only = True
2900 if not isinstance(lhs, ExprNodes.NameNode):
2901 error(lhs.pos, "Invalid declaration.")
2902 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2904 elif func_name in ['struct', 'union']:
2905 self.declaration_only = True
2906 if len(args) > 0 or kwds is None:
2907 error(rhs.pos, "Struct or union members must be given by name.")
2910 for member, type_node in kwds.key_value_pairs:
2911 type = type_node.analyse_as_type(env)
2913 error(type_node.pos, "Unknown type")
2915 members.append((member.value, type, member.pos))
2916 if len(members) < len(kwds.key_value_pairs):
2918 if not isinstance(self.lhs, ExprNodes.NameNode):
2919 error(self.lhs.pos, "Invalid declaration.")
2920 name = self.lhs.name
2921 scope = StructOrUnionScope(name)
2922 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2923 for member, type, pos in members:
2924 scope.declare_var(member, type, pos)
2926 if self.declaration_only:
2929 self.lhs.analyse_target_declaration(env)
2931 def analyse_types(self, env, use_temp = 0):
2932 self.rhs.analyse_types(env)
2933 self.lhs.analyse_target_types(env)
2934 self.lhs.gil_assignment_check(env)
2935 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2937 self.rhs = self.rhs.coerce_to_temp(env)
2939 def allocate_rhs_temps(self, env):
2940 self.rhs.allocate_temps(env)
2942 def allocate_lhs_temps(self, env):
2943 self.lhs.allocate_target_temps(env, self.rhs)
2944 #self.lhs.release_target_temp(env)
2945 #self.rhs.release_temp(env)
2947 def generate_rhs_evaluation_code(self, code):
2948 self.rhs.generate_evaluation_code(code)
2950 def generate_assignment_code(self, code):
2951 self.lhs.generate_assignment_code(self.rhs, code)
2953 def annotate(self, code):
2954 self.lhs.annotate(code)
2955 self.rhs.annotate(code)
2958 class CascadedAssignmentNode(AssignmentNode):
2959 # An assignment with multiple left hand sides:
2963 # lhs_list [ExprNode] Left hand sides
2964 # rhs ExprNode Right hand sides
2968 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2970 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2971 coerced_rhs_list = None
2973 def analyse_declarations(self, env):
2974 for lhs in self.lhs_list:
2975 lhs.analyse_target_declaration(env)
2977 def analyse_types(self, env, use_temp = 0):
2978 self.rhs.analyse_types(env)
2980 self.rhs = self.rhs.coerce_to_temp(env)
2982 self.rhs = self.rhs.coerce_to_simple(env)
2983 from ExprNodes import CloneNode
2984 self.coerced_rhs_list = []
2985 for lhs in self.lhs_list:
2986 lhs.analyse_target_types(env)
2987 lhs.gil_assignment_check(env)
2988 rhs = CloneNode(self.rhs)
2989 rhs = rhs.coerce_to(lhs.type, env)
2990 self.coerced_rhs_list.append(rhs)
2992 def allocate_rhs_temps(self, env):
2993 self.rhs.allocate_temps(env)
2995 def allocate_lhs_temps(self, env):
2996 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2997 rhs.allocate_temps(env)
2998 lhs.allocate_target_temps(env, rhs)
2999 #lhs.release_target_temp(env)
3000 #rhs.release_temp(env)
3001 self.rhs.release_temp(env)
3003 def generate_rhs_evaluation_code(self, code):
3004 self.rhs.generate_evaluation_code(code)
3006 def generate_assignment_code(self, code):
3007 for i in range(len(self.lhs_list)):
3008 lhs = self.lhs_list[i]
3009 rhs = self.coerced_rhs_list[i]
3010 rhs.generate_evaluation_code(code)
3011 lhs.generate_assignment_code(rhs, code)
3012 # Assignment has disposed of the cloned RHS
3013 self.rhs.generate_disposal_code(code)
3014 self.rhs.free_temps(code)
3016 def annotate(self, code):
3017 for i in range(len(self.lhs_list)):
3018 lhs = self.lhs_list[i].annotate(code)
3019 rhs = self.coerced_rhs_list[i].annotate(code)
3020 self.rhs.annotate(code)
3023 class ParallelAssignmentNode(AssignmentNode):
3024 # A combined packing/unpacking assignment:
3028 # This has been rearranged by the parser into
3030 # a = d ; b = e ; c = f
3032 # but we must evaluate all the right hand sides
3033 # before assigning to any of the left hand sides.
3035 # stats [AssignmentNode] The constituent assignments
3037 child_attrs = ["stats"]
3039 def analyse_declarations(self, env):
3040 for stat in self.stats:
3041 stat.analyse_declarations(env)
3043 def analyse_expressions(self, env):
3044 for stat in self.stats:
3045 stat.analyse_types(env, use_temp = 1)
3046 stat.allocate_rhs_temps(env)
3047 for stat in self.stats:
3048 stat.allocate_lhs_temps(env)
3050 # def analyse_expressions(self, env):
3051 # for stat in self.stats:
3052 # stat.analyse_expressions_1(env, use_temp = 1)
3053 # for stat in self.stats:
3054 # stat.analyse_expressions_2(env)
3056 def generate_execution_code(self, code):
3057 for stat in self.stats:
3058 stat.generate_rhs_evaluation_code(code)
3059 for stat in self.stats:
3060 stat.generate_assignment_code(code)
3062 def annotate(self, code):
3063 for stat in self.stats:
3067 class InPlaceAssignmentNode(AssignmentNode):
3068 # An in place arithmatic operand:
3074 # lhs ExprNode Left hand side
3075 # rhs ExprNode Right hand side
3076 # op char one of "+-*/%^&|"
3077 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3079 # This code is a bit tricky because in order to obey Python
3080 # semantics the sub-expressions (e.g. indices) of the lhs must
3081 # not be evaluated twice. So we must re-use the values calculated
3082 # in evaluation phase for the assignment phase as well.
3083 # Fortunately, the type of the lhs node is fairly constrained
3084 # (it must be a NameNode, AttributeNode, or IndexNode).
3086 child_attrs = ["lhs", "rhs"]
3089 def analyse_declarations(self, env):
3090 self.lhs.analyse_target_declaration(env)
3092 def analyse_types(self, env):
3093 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3094 self.rhs.analyse_types(env)
3095 self.lhs.analyse_target_types(env)
3096 if Options.incref_local_binop and self.dup.type.is_pyobject:
3097 self.dup = self.dup.coerce_to_temp(env)
3099 def allocate_rhs_temps(self, env):
3101 if self.lhs.type.is_pyobject:
3102 self.rhs = self.rhs.coerce_to_pyobject(env)
3103 elif self.rhs.type.is_pyobject:
3104 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3105 if self.lhs.type.is_pyobject:
3106 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3107 self.result_value.allocate_temps(env)
3109 # self.rhs = self.rhs.coerce_to_temp(env)
3110 self.rhs.allocate_temps(env)
3111 self.dup.allocate_subexpr_temps(env)
3112 self.dup.allocate_temp(env)
3114 def allocate_lhs_temps(self, env):
3115 self.lhs.allocate_target_temps(env, self.rhs)
3116 # self.lhs.release_target_temp(env)
3117 self.dup.release_temp(env)
3118 if self.dup.is_temp:
3119 self.dup.release_subexpr_temps(env)
3120 # self.rhs.release_temp(env)
3121 if self.lhs.type.is_pyobject:
3122 self.result_value.release_temp(env)
3124 def generate_execution_code(self, code):
3126 self.rhs.generate_evaluation_code(code)
3127 self.dup.generate_subexpr_evaluation_code(code)
3128 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3129 # This is because we're manually messing with subexpr nodes
3130 if self.dup.is_temp:
3131 self.dup.allocate_temp_result(code)
3132 # self.dup.generate_result_code is run only if it is not buffer access
3133 if self.operator == "**":
3137 if self.lhs.type.is_pyobject:
3138 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3139 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3140 self.dup.generate_result_code(code)
3142 "%s = %s(%s, %s%s); %s" % (
3143 self.result_value.result(),
3144 self.py_operation_function(),
3145 self.dup.py_result(),
3146 self.rhs.py_result(),
3148 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3149 code.put_gotref(self.result_value.py_result())
3150 self.result_value.generate_evaluation_code(code) # May be a type check...
3151 self.rhs.generate_disposal_code(code)
3152 self.rhs.free_temps(code)
3153 self.dup.generate_disposal_code(code)
3154 self.dup.free_temps(code)
3155 self.lhs.generate_assignment_code(self.result_value, code)
3157 c_op = self.operator
3161 if self.lhs.type.is_int and self.rhs.type.is_int:
3162 error(self.pos, "** with two C int types is ambiguous")
3164 error(self.pos, "No C inplace power operator")
3165 # have to do assignment directly to avoid side-effects
3166 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3167 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3169 self.dup.generate_result_code(code)
3170 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3171 self.rhs.generate_disposal_code(code)
3172 self.rhs.free_temps(code)
3173 if self.dup.is_temp:
3174 self.dup.generate_subexpr_disposal_code(code)
3175 self.dup.free_subexpr_temps(code)
3177 def create_dup_node(self, env):
3180 self.dup.analyse_types(env)
3181 if isinstance(self.lhs, ExprNodes.NameNode):
3182 target_lhs = ExprNodes.NameNode(self.dup.pos,
3183 name = self.dup.name,
3184 is_temp = self.dup.is_temp,
3185 entry = self.dup.entry)
3186 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3187 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3188 obj = ExprNodes.CloneNode(self.lhs.obj),
3189 attribute = self.dup.attribute,
3190 is_temp = self.dup.is_temp)
3191 elif isinstance(self.lhs, ExprNodes.IndexNode):
3193 index = ExprNodes.CloneNode(self.lhs.index)
3196 if self.lhs.indices:
3197 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3200 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3201 base = ExprNodes.CloneNode(self.dup.base),
3204 is_temp = self.dup.is_temp)
3207 self.lhs = target_lhs
3210 def py_operation_function(self):
3211 return self.py_functions[self.operator]
3214 "|": "PyNumber_InPlaceOr",
3215 "^": "PyNumber_InPlaceXor",
3216 "&": "PyNumber_InPlaceAnd",
3217 "+": "PyNumber_InPlaceAdd",
3218 "-": "PyNumber_InPlaceSubtract",
3219 "*": "PyNumber_InPlaceMultiply",
3220 "/": "PyNumber_InPlaceDivide",
3221 "%": "PyNumber_InPlaceRemainder",
3222 "<<": "PyNumber_InPlaceLshift",
3223 ">>": "PyNumber_InPlaceRshift",
3224 "**": "PyNumber_InPlacePower",
3225 "//": "PyNumber_InPlaceFloorDivide",
3228 def annotate(self, code):
3229 self.lhs.annotate(code)
3230 self.rhs.annotate(code)
3231 self.dup.annotate(code)
3234 class PrintStatNode(StatNode):
3237 # arg_tuple TupleNode
3238 # append_newline boolean
3240 child_attrs = ["arg_tuple"]
3242 def analyse_expressions(self, env):
3243 self.arg_tuple.analyse_expressions(env)
3244 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3245 self.arg_tuple.release_temp(env)
3246 env.use_utility_code(printing_utility_code)
3247 if len(self.arg_tuple.args) == 1 and self.append_newline:
3248 env.use_utility_code(printing_one_utility_code)
3251 gil_message = "Python print statement"
3253 def generate_execution_code(self, code):
3254 if len(self.arg_tuple.args) == 1 and self.append_newline:
3255 arg = self.arg_tuple.args[0]
3256 arg.generate_evaluation_code(code)
3259 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3261 code.error_goto(self.pos)))
3262 arg.generate_disposal_code(code)
3263 arg.free_temps(code)
3265 self.arg_tuple.generate_evaluation_code(code)
3267 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3268 self.arg_tuple.py_result(),
3269 self.append_newline,
3270 code.error_goto(self.pos)))
3271 self.arg_tuple.generate_disposal_code(code)
3272 self.arg_tuple.free_temps(code)
3274 def annotate(self, code):
3275 self.arg_tuple.annotate(code)
3278 class ExecStatNode(StatNode):
3283 child_attrs = ["args"]
3285 def analyse_expressions(self, env):
3286 for i, arg in enumerate(self.args):
3287 arg.analyse_expressions(env)
3288 arg = arg.coerce_to_pyobject(env)
3289 arg.release_temp(env)
3291 self.temp_result = env.allocate_temp_pyobject()
3292 env.release_temp(self.temp_result)
3293 env.use_utility_code(Builtin.pyexec_utility_code)
3296 gil_message = "Python exec statement"
3298 def generate_execution_code(self, code):
3300 for arg in self.args:
3301 arg.generate_evaluation_code(code)
3302 args.append( arg.py_result() )
3303 args = tuple(args + ['0', '0'][:3-len(args)])
3304 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3305 (self.temp_result,) + args))
3306 for arg in self.args:
3307 arg.generate_disposal_code(code)
3308 arg.free_temps(code)
3310 code.error_goto_if_null(self.temp_result, self.pos))
3311 code.put_gotref(self.temp_result)
3312 code.put_decref_clear(self.temp_result, py_object_type)
3314 def annotate(self, code):
3315 for arg in self.args:
3319 class DelStatNode(StatNode):
3324 child_attrs = ["args"]
3326 def analyse_declarations(self, env):
3327 for arg in self.args:
3328 arg.analyse_target_declaration(env)
3330 def analyse_expressions(self, env):
3331 for arg in self.args:
3332 arg.analyse_target_expression(env, None)
3333 if arg.type.is_pyobject:
3336 error(arg.pos, "Deletion of non-Python object")
3337 #arg.release_target_temp(env)
3339 gil_message = "Deleting Python object"
3341 def generate_execution_code(self, code):
3342 for arg in self.args:
3343 if arg.type.is_pyobject:
3344 arg.generate_deletion_code(code)
3345 # else error reported earlier
3347 def annotate(self, code):
3348 for arg in self.args:
3352 class PassStatNode(StatNode):
3357 def analyse_expressions(self, env):
3360 def generate_execution_code(self, code):
3364 class BreakStatNode(StatNode):
3368 def analyse_expressions(self, env):
3371 def generate_execution_code(self, code):
3372 if not code.break_label:
3373 error(self.pos, "break statement not inside loop")
3375 code.put_goto(code.break_label)
3378 class ContinueStatNode(StatNode):
3382 def analyse_expressions(self, env):
3385 def generate_execution_code(self, code):
3386 if code.funcstate.in_try_finally:
3387 error(self.pos, "continue statement inside try of try...finally")
3388 elif not code.continue_label:
3389 error(self.pos, "continue statement not inside loop")
3391 code.put_goto(code.continue_label)
3394 class ReturnStatNode(StatNode):
3397 # value ExprNode or None
3398 # return_type PyrexType
3399 # temps_in_use [Entry] Temps in use at time of return
3401 child_attrs = ["value"]
3403 def analyse_expressions(self, env):
3404 return_type = env.return_type
3405 self.return_type = return_type
3406 self.temps_in_use = env.temps_in_use()
3408 error(self.pos, "Return not inside a function body")
3411 self.value.analyse_types(env)
3412 if return_type.is_void or return_type.is_returncode:
3413 error(self.value.pos,
3414 "Return with value in void function")
3416 self.value = self.value.coerce_to(env.return_type, env)
3417 self.value.allocate_temps(env)
3418 self.value.release_temp(env)
3420 if (not return_type.is_void
3421 and not return_type.is_pyobject
3422 and not return_type.is_returncode):
3423 error(self.pos, "Return value required")
3424 if return_type.is_pyobject:
3427 gil_message = "Returning Python object"
3429 def generate_execution_code(self, code):
3430 code.mark_pos(self.pos)
3431 if not self.return_type:
3432 # error reported earlier
3434 if self.return_type.is_pyobject:
3435 code.put_xdecref(Naming.retval_cname,
3438 self.value.generate_evaluation_code(code)
3439 self.value.make_owned_reference(code)
3442 Naming.retval_cname,
3443 self.value.result_as(self.return_type)))
3444 self.value.generate_post_assignment_code(code)
3445 self.value.free_temps(code)
3447 if self.return_type.is_pyobject:
3448 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3449 elif self.return_type.is_returncode:
3452 Naming.retval_cname,
3453 self.return_type.default_value))
3454 # free temps the old way
3455 for entry in self.temps_in_use:
3456 code.put_var_decref_clear(entry)
3457 # free temps the new way
3458 for cname, type in code.funcstate.temps_holding_reference():
3459 code.put_decref_clear(cname, type)
3462 # code.return_label)
3463 code.put_goto(code.return_label)
3465 def annotate(self, code):
3467 self.value.annotate(code)
3470 class RaiseStatNode(StatNode):
3473 # exc_type ExprNode or None
3474 # exc_value ExprNode or None
3475 # exc_tb ExprNode or None
3477 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3479 def analyse_expressions(self, env):
3481 self.exc_type.analyse_types(env)
3482 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3483 self.exc_type.allocate_temps(env)
3485 self.exc_value.analyse_types(env)
3486 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3487 self.exc_value.allocate_temps(env)
3489 self.exc_tb.analyse_types(env)
3490 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3491 self.exc_tb.allocate_temps(env)
3493 self.exc_type.release_temp(env)
3495 self.exc_value.release_temp(env)
3497 self.exc_tb.release_temp(env)
3498 env.use_utility_code(raise_utility_code)
3499 env.use_utility_code(restore_exception_utility_code)
3502 gil_message = "Raising exception"
3504 def generate_execution_code(self, code):
3506 self.exc_type.generate_evaluation_code(code)
3507 type_code = self.exc_type.py_result()
3511 self.exc_value.generate_evaluation_code(code)
3512 value_code = self.exc_value.py_result()
3516 self.exc_tb.generate_evaluation_code(code)
3517 tb_code = self.exc_tb.py_result()
3520 if self.exc_type or self.exc_value or self.exc_tb:
3522 "__Pyx_Raise(%s, %s, %s);" % (
3529 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3531 obj.generate_disposal_code(code)
3532 obj.free_temps(code)
3534 code.error_goto(self.pos))
3536 def annotate(self, code):
3538 self.exc_type.annotate(code)
3540 self.exc_value.annotate(code)
3542 self.exc_tb.annotate(code)
3545 class ReraiseStatNode(StatNode):
3549 def analyse_expressions(self, env):
3551 env.use_utility_code(raise_utility_code)
3552 env.use_utility_code(restore_exception_utility_code)
3554 gil_message = "Raising exception"
3556 def generate_execution_code(self, code):
3557 vars = code.funcstate.exc_vars
3559 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3560 code.putln(code.error_goto(self.pos))
3562 error(self.pos, "Reraise not inside except clause")
3565 class AssertStatNode(StatNode):
3569 # value ExprNode or None
3571 child_attrs = ["cond", "value"]
3573 def analyse_expressions(self, env):
3574 self.cond = self.cond.analyse_boolean_expression(env)
3576 self.value.analyse_types(env)
3577 self.value = self.value.coerce_to_pyobject(env)
3578 self.value.allocate_temps(env)
3579 self.cond.release_temp(env)
3581 self.value.release_temp(env)
3583 #env.recycle_pending_temps() # TEMPORARY
3585 gil_message = "Raising exception"
3587 def generate_execution_code(self, code):
3588 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3589 self.cond.generate_evaluation_code(code)
3591 "if (unlikely(!%s)) {" %
3594 self.value.generate_evaluation_code(code)
3596 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3597 self.value.py_result())
3598 self.value.generate_disposal_code(code)
3599 self.value.free_temps(code)
3602 "PyErr_SetNone(PyExc_AssertionError);")
3604 code.error_goto(self.pos))
3607 self.cond.generate_disposal_code(code)
3608 self.cond.free_temps(code)
3609 code.putln("#endif")
3611 def annotate(self, code):
3612 self.cond.annotate(code)
3614 self.value.annotate(code)
3617 class IfStatNode(StatNode):
3620 # if_clauses [IfClauseNode]
3621 # else_clause StatNode or None
3623 child_attrs = ["if_clauses", "else_clause"]
3625 def analyse_control_flow(self, env):
3626 env.start_branching(self.pos)
3627 for if_clause in self.if_clauses:
3628 if_clause.analyse_control_flow(env)
3629 env.next_branch(if_clause.end_pos())
3630 if self.else_clause:
3631 self.else_clause.analyse_control_flow(env)
3632 env.finish_branching(self.end_pos())
3634 def analyse_declarations(self, env):
3635 for if_clause in self.if_clauses:
3636 if_clause.analyse_declarations(env)
3637 if self.else_clause:
3638 self.else_clause.analyse_declarations(env)
3640 def analyse_expressions(self, env):
3641 for if_clause in self.if_clauses:
3642 if_clause.analyse_expressions(env)
3643 if self.else_clause:
3644 self.else_clause.analyse_expressions(env)
3646 def generate_execution_code(self, code):
3647 code.mark_pos(self.pos)
3648 end_label = code.new_label()
3649 for if_clause in self.if_clauses:
3650 if_clause.generate_execution_code(code, end_label)
3651 if self.else_clause:
3652 code.putln("/*else*/ {")
3653 self.else_clause.generate_execution_code(code)
3655 code.put_label(end_label)
3657 def annotate(self, code):
3658 for if_clause in self.if_clauses:
3659 if_clause.annotate(code)
3660 if self.else_clause:
3661 self.else_clause.annotate(code)
3664 class IfClauseNode(Node):
3665 # if or elif clause in an if statement
3667 # condition ExprNode
3670 child_attrs = ["condition", "body"]
3672 def analyse_control_flow(self, env):
3673 self.body.analyse_control_flow(env)
3675 def analyse_declarations(self, env):
3676 self.condition.analyse_declarations(env)
3677 self.body.analyse_declarations(env)
3679 def analyse_expressions(self, env):
3681 self.condition.analyse_temp_boolean_expression(env)
3682 self.condition.release_temp(env)
3683 self.body.analyse_expressions(env)
3685 def generate_execution_code(self, code, end_label):
3686 self.condition.generate_evaluation_code(code)
3689 self.condition.result())
3690 self.condition.generate_disposal_code(code)
3691 self.condition.free_temps(code)
3692 self.body.generate_execution_code(code)
3696 code.put_goto(end_label)
3699 def annotate(self, code):
3700 self.condition.annotate(code)
3701 self.body.annotate(code)
3704 class SwitchCaseNode(StatNode):
3705 # Generated in the optimization of an if-elif-else node
3707 # conditions [ExprNode]
3710 child_attrs = ['conditions', 'body']
3712 def generate_execution_code(self, code):
3713 for cond in self.conditions:
3714 code.mark_pos(cond.pos)
3715 code.putln("case %s:" % cond.calculate_result_code())
3716 self.body.generate_execution_code(code)
3717 code.putln("break;")
3719 def annotate(self, code):
3720 for cond in self.conditions:
3722 self.body.annotate(code)
3724 class SwitchStatNode(StatNode):
3725 # Generated in the optimization of an if-elif-else node
3728 # cases [SwitchCaseNode]
3729 # else_clause StatNode or None
3731 child_attrs = ['test', 'cases', 'else_clause']
3733 def generate_execution_code(self, code):
3734 code.putln("switch (%s) {" % self.test.calculate_result_code())
3735 for case in self.cases:
3736 case.generate_execution_code(code)
3737 if self.else_clause is not None:
3738 code.putln("default:")
3739 self.else_clause.generate_execution_code(code)
3740 code.putln("break;")
3743 def annotate(self, code):
3744 self.test.annotate(code)
3745 for case in self.cases:
3747 if self.else_clause is not None:
3748 self.else_clause.annotate(code)
3750 class LoopNode(object):
3752 def analyse_control_flow(self, env):
3753 env.start_branching(self.pos)
3754 self.body.analyse_control_flow(env)
3755 env.next_branch(self.body.end_pos())
3756 if self.else_clause:
3757 self.else_clause.analyse_control_flow(env)
3758 env.finish_branching(self.end_pos())
3761 class WhileStatNode(LoopNode, StatNode):
3764 # condition ExprNode
3766 # else_clause StatNode
3768 child_attrs = ["condition", "body", "else_clause"]
3770 def analyse_declarations(self, env):
3771 self.body.analyse_declarations(env)
3772 if self.else_clause:
3773 self.else_clause.analyse_declarations(env)
3775 def analyse_expressions(self, env):
3777 self.condition.analyse_temp_boolean_expression(env)
3778 self.condition.release_temp(env)
3779 #env.recycle_pending_temps() # TEMPORARY
3780 self.body.analyse_expressions(env)
3781 if self.else_clause:
3782 self.else_clause.analyse_expressions(env)
3784 def generate_execution_code(self, code):
3785 old_loop_labels = code.new_loop_labels()
3788 self.condition.generate_evaluation_code(code)
3789 self.condition.generate_disposal_code(code)
3792 self.condition.result())
3793 self.condition.free_temps(code)
3794 self.body.generate_execution_code(code)
3795 code.put_label(code.continue_label)
3797 break_label = code.break_label
3798 code.set_loop_labels(old_loop_labels)
3799 if self.else_clause:
3800 code.putln("/*else*/ {")
3801 self.else_clause.generate_execution_code(code)
3803 code.put_label(break_label)
3805 def annotate(self, code):
3806 self.condition.annotate(code)
3807 self.body.annotate(code)
3808 if self.else_clause:
3809 self.else_clause.annotate(code)
3812 def ForStatNode(pos, **kw):
3813 if 'iterator' in kw:
3814 return ForInStatNode(pos, **kw)
3816 return ForFromStatNode(pos, **kw)
3818 class ForInStatNode(LoopNode, StatNode):
3822 # iterator IteratorNode
3824 # else_clause StatNode
3825 # item NextNode used internally
3827 child_attrs = ["target", "iterator", "body", "else_clause"]
3830 def analyse_declarations(self, env):
3831 self.target.analyse_target_declaration(env)
3832 self.body.analyse_declarations(env)
3833 if self.else_clause:
3834 self.else_clause.analyse_declarations(env)
3836 def analyse_expressions(self, env):
3838 self.target.analyse_target_types(env)
3839 self.iterator.analyse_expressions(env)
3840 self.item = ExprNodes.NextNode(self.iterator, env)
3841 self.item = self.item.coerce_to(self.target.type, env)
3842 self.item.allocate_temps(env)
3843 self.target.allocate_target_temps(env, self.item)
3844 #self.item.release_temp(env)
3845 #self.target.release_target_temp(env)
3846 self.body.analyse_expressions(env)
3847 if self.else_clause:
3848 self.else_clause.analyse_expressions(env)
3849 self.iterator.release_temp(env)
3851 def generate_execution_code(self, code):
3852 old_loop_labels = code.new_loop_labels()
3853 self.iterator.allocate_counter_temp(code)
3854 self.iterator.generate_evaluation_code(code)
3857 self.item.generate_evaluation_code(code)
3858 self.target.generate_assignment_code(self.item, code)
3859 self.body.generate_execution_code(code)
3860 code.put_label(code.continue_label)
3863 break_label = code.break_label
3864 code.set_loop_labels(old_loop_labels)
3865 if self.else_clause:
3866 code.putln("/*else*/ {")
3867 self.else_clause.generate_execution_code(code)
3869 code.put_label(break_label)
3870 self.iterator.release_counter_temp(code)
3871 self.iterator.generate_disposal_code(code)
3872 self.iterator.free_temps(code)
3874 def annotate(self, code):
3875 self.target.annotate(code)
3876 self.iterator.annotate(code)
3877 self.body.annotate(code)
3878 if self.else_clause:
3879 self.else_clause.annotate(code)
3880 self.item.annotate(code)
3883 class ForFromStatNode(LoopNode, StatNode):
3884 # for name from expr rel name rel expr
3891 # step ExprNode or None
3893 # else_clause StatNode or None
3899 # loopvar_node ExprNode (usually a NameNode or temp node)
3900 # py_loopvar_node PyTempNode or None
3901 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3903 is_py_target = False
3905 py_loopvar_node = None
3908 def analyse_declarations(self, env):
3909 self.target.analyse_target_declaration(env)
3910 self.body.analyse_declarations(env)
3911 if self.else_clause:
3912 self.else_clause.analyse_declarations(env)
3914 def analyse_expressions(self, env):
3916 self.target.analyse_target_types(env)
3917 self.bound1.analyse_types(env)
3918 self.bound2.analyse_types(env)
3919 if self.step is not None:
3920 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3921 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3922 self.step.analyse_types(env)
3924 target_type = self.target.type
3925 if self.target.type.is_numeric:
3926 loop_type = self.target.type
3928 loop_type = PyrexTypes.c_int_type
3929 if not self.bound1.type.is_pyobject:
3930 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3931 if not self.bound2.type.is_pyobject:
3932 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3933 if self.step is not None and not self.step.type.is_pyobject:
3934 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3935 self.bound1 = self.bound1.coerce_to(loop_type, env)
3936 self.bound2 = self.bound2.coerce_to(loop_type, env)
3937 if not self.bound2.is_literal:
3938 self.bound2 = self.bound2.coerce_to_temp(env)
3939 if self.step is not None:
3940 self.step = self.step.coerce_to(loop_type, env)
3941 if not self.step.is_literal:
3942 self.step = self.step.coerce_to_temp(env)
3944 target_type = self.target.type
3945 if not (target_type.is_pyobject or target_type.is_numeric):
3946 error(self.target.pos,
3947 "for-from loop variable must be c numeric type or Python object")
3948 if target_type.is_numeric:
3949 self.is_py_target = False
3950 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3951 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3952 self.loopvar_node = self.target
3953 self.py_loopvar_node = None
3955 self.is_py_target = True
3956 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3957 c_loopvar_node.allocate_temps(env)
3958 self.loopvar_node = c_loopvar_node
3959 self.py_loopvar_node = \
3960 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3961 self.bound1.allocate_temps(env)
3962 self.bound2.allocate_temps(env)
3963 if self.step is not None:
3964 self.step.allocate_temps(env)
3965 if self.is_py_target:
3966 self.py_loopvar_node.allocate_temps(env)
3967 self.target.allocate_target_temps(env, self.py_loopvar_node)
3968 #self.target.release_target_temp(env)
3969 #self.py_loopvar_node.release_temp(env)
3970 self.body.analyse_expressions(env)
3971 if self.is_py_target:
3972 c_loopvar_node.release_temp(env)
3973 if self.else_clause:
3974 self.else_clause.analyse_expressions(env)
3975 self.bound1.release_temp(env)
3976 self.bound2.release_temp(env)
3977 if self.step is not None:
3978 self.step.release_temp(env)
3980 def generate_execution_code(self, code):
3981 old_loop_labels = code.new_loop_labels()
3982 from_range = self.from_range
3983 self.bound1.generate_evaluation_code(code)
3984 self.bound2.generate_evaluation_code(code)
3985 offset, incop = self.relation_table[self.relation1]
3986 if self.step is not None:
3987 self.step.generate_evaluation_code(code)
3988 step = self.step.result()
3989 incop = "%s=%s" % (incop[0], step)
3991 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3993 loopvar_name = self.loopvar_node.result()
3995 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3997 self.bound1.result(), offset,
3998 loopvar_name, self.relation2, self.bound2.result(),
3999 loopvar_name, incop))
4000 if self.py_loopvar_node:
4001 self.py_loopvar_node.generate_evaluation_code(code)
4002 self.target.generate_assignment_code(self.py_loopvar_node, code)
4004 code.putln("%s = %s;" % (
4005 self.target.result(), loopvar_name))
4006 self.body.generate_execution_code(code)
4007 code.put_label(code.continue_label)
4008 if self.py_loopvar_node:
4009 # This mess is to make for..from loops with python targets behave
4010 # exactly like those with C targets with regards to re-assignment
4011 # of the loop variable.
4013 if self.target.entry.is_pyglobal:
4014 # We know target is a NameNode, this is the only ugly case.
4015 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4016 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4017 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4018 target_node.result_code,
4019 Naming.module_cname,
4020 self.target.entry.interned_cname,
4021 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4022 code.put_gotref(target_node.result_code)
4024 target_node = self.target
4025 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4026 from_py_node.temp_code = loopvar_name
4027 from_py_node.generate_result_code(code)
4028 if self.target.entry.is_pyglobal:
4029 code.put_decref_clear(target_node.result_code, py_object_type)
4030 code.funcstate.release_temp(target_node.result_code)
4032 if self.py_loopvar_node:
4033 # This is potentially wasteful, but we don't want the semantics to
4034 # depend on whether or not the loop is a python type.
4035 self.py_loopvar_node.generate_evaluation_code(code)
4036 self.target.generate_assignment_code(self.py_loopvar_node, code)
4037 break_label = code.break_label
4038 code.set_loop_labels(old_loop_labels)
4039 if self.else_clause:
4040 code.putln("/*else*/ {")
4041 self.else_clause.generate_execution_code(code)
4043 code.put_label(break_label)
4044 self.bound1.generate_disposal_code(code)
4045 self.bound1.free_temps(code)
4046 self.bound2.generate_disposal_code(code)
4047 self.bound2.free_temps(code)
4048 if self.step is not None:
4049 self.step.generate_disposal_code(code)
4050 self.step.free_temps(code)
4052 code.funcstate.release_temp(loopvar_name)
4055 # {relop : (initial offset, increment op)}
4062 def annotate(self, code):
4063 self.target.annotate(code)
4064 self.bound1.annotate(code)
4065 self.bound2.annotate(code)
4067 self.bound2.annotate(code)
4068 self.body.annotate(code)
4069 if self.else_clause:
4070 self.else_clause.annotate(code)
4073 class WithStatNode(StatNode):
4075 Represents a Python with statement.
4077 This is only used at parse tree level; and is not present in
4078 analysis or generation phases.
4080 # manager The with statement manager object
4081 # target Node (lhs expression)
4083 child_attrs = ["manager", "target", "body"]
4085 class TryExceptStatNode(StatNode):
4086 # try .. except statement
4089 # except_clauses [ExceptClauseNode]
4090 # else_clause StatNode or None
4091 # cleanup_list [Entry] old style temps to clean up on error
4093 child_attrs = ["body", "except_clauses", "else_clause"]
4095 def analyse_control_flow(self, env):
4096 env.start_branching(self.pos)
4097 self.body.analyse_control_flow(env)
4098 successful_try = env.control_flow # grab this for later
4099 env.next_branch(self.body.end_pos())
4100 env.finish_branching(self.body.end_pos())
4102 env.start_branching(self.except_clauses[0].pos)
4103 for except_clause in self.except_clauses:
4104 except_clause.analyse_control_flow(env)
4105 env.next_branch(except_clause.end_pos())
4107 # the else cause it executed only when the try clause finishes
4108 env.control_flow.incoming = successful_try
4109 if self.else_clause:
4110 self.else_clause.analyse_control_flow(env)
4111 env.finish_branching(self.end_pos())
4113 def analyse_declarations(self, env):
4114 self.body.analyse_declarations(env)
4115 for except_clause in self.except_clauses:
4116 except_clause.analyse_declarations(env)
4117 if self.else_clause:
4118 self.else_clause.analyse_declarations(env)
4120 env.use_utility_code(reset_exception_utility_code)
4122 def analyse_expressions(self, env):
4123 self.body.analyse_expressions(env)
4124 self.cleanup_list = env.free_temp_entries[:]
4125 default_clause_seen = 0
4126 for except_clause in self.except_clauses:
4127 except_clause.analyse_expressions(env)
4128 if default_clause_seen:
4129 error(except_clause.pos, "default 'except:' must be last")
4130 if not except_clause.pattern:
4131 default_clause_seen = 1
4132 self.has_default_clause = default_clause_seen
4133 if self.else_clause:
4134 self.else_clause.analyse_expressions(env)
4137 gil_message = "Try-except statement"
4139 def generate_execution_code(self, code):
4140 old_return_label = code.return_label
4141 old_break_label = code.break_label
4142 old_continue_label = code.continue_label
4143 old_error_label = code.new_error_label()
4144 our_error_label = code.error_label
4145 except_end_label = code.new_label('exception_handled')
4146 except_error_label = code.new_label('except_error')
4147 except_return_label = code.new_label('except_return')
4148 try_return_label = code.new_label('try_return')
4149 try_break_label = code.new_label('try_break')
4150 try_continue_label = code.new_label('try_continue')
4151 try_end_label = code.new_label('try_end')
4154 code.putln("PyObject %s;" %
4155 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4156 code.putln("__Pyx_ExceptionSave(%s);" %
4157 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4158 for var in Naming.exc_save_vars:
4159 code.put_xgotref(var)
4162 code.return_label = try_return_label
4163 code.break_label = try_break_label
4164 code.continue_label = try_continue_label
4165 self.body.generate_execution_code(code)
4168 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4169 code.error_label = except_error_label
4170 code.return_label = except_return_label
4171 if self.else_clause:
4174 self.else_clause.generate_execution_code(code)
4177 for var in Naming.exc_save_vars:
4178 code.put_xdecref_clear(var, py_object_type)
4179 code.put_goto(try_end_label)
4180 if code.label_used(try_return_label):
4181 code.put_label(try_return_label)
4182 for var in Naming.exc_save_vars:
4183 code.put_xdecref_clear(var, py_object_type)
4184 code.put_goto(old_return_label)
4185 code.put_label(our_error_label)
4186 code.put_var_xdecrefs_clear(self.cleanup_list)
4187 for temp_name, type in temps_to_clean_up:
4188 code.put_xdecref_clear(temp_name, type)
4189 for except_clause in self.except_clauses:
4190 except_clause.generate_handling_code(code, except_end_label)
4192 error_label_used = code.label_used(except_error_label)
4193 if error_label_used or not self.has_default_clause:
4194 if error_label_used:
4195 code.put_label(except_error_label)
4196 for var in Naming.exc_save_vars:
4197 code.put_xdecref(var, py_object_type)
4198 code.put_goto(old_error_label)
4200 if code.label_used(try_break_label):
4201 code.put_label(try_break_label)
4202 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4203 code.putln("__Pyx_ExceptionReset(%s);" %
4204 ', '.join(Naming.exc_save_vars))
4205 code.put_goto(old_break_label)
4207 if code.label_used(try_continue_label):
4208 code.put_label(try_continue_label)
4209 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4210 code.putln("__Pyx_ExceptionReset(%s);" %
4211 ', '.join(Naming.exc_save_vars))
4212 code.put_goto(old_continue_label)
4214 if code.label_used(except_return_label):
4215 code.put_label(except_return_label)
4216 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4217 code.putln("__Pyx_ExceptionReset(%s);" %
4218 ', '.join(Naming.exc_save_vars))
4219 code.put_goto(old_return_label)
4221 if code.label_used(except_end_label):
4222 code.put_label(except_end_label)
4223 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4224 code.putln("__Pyx_ExceptionReset(%s);" %
4225 ', '.join(Naming.exc_save_vars))
4226 code.put_label(try_end_label)
4229 code.return_label = old_return_label
4230 code.break_label = old_break_label
4231 code.continue_label = old_continue_label
4232 code.error_label = old_error_label
4234 def annotate(self, code):
4235 self.body.annotate(code)
4236 for except_node in self.except_clauses:
4237 except_node.annotate(code)
4238 if self.else_clause:
4239 self.else_clause.annotate(code)
4242 class ExceptClauseNode(Node):
4243 # Part of try ... except statement.
4246 # target ExprNode or None
4248 # excinfo_target NameNode or None optional target for exception info
4249 # match_flag string result of exception match
4250 # exc_value ExcValueNode used internally
4251 # function_name string qualified name of enclosing function
4252 # exc_vars (string * 3) local exception variables
4254 # excinfo_target is never set by the parser, but can be set by a transform
4255 # in order to extract more extensive information about the exception as a
4256 # sys.exc_info()-style tuple into a target variable
4258 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4261 excinfo_target = None
4263 def analyse_declarations(self, env):
4265 self.target.analyse_target_declaration(env)
4266 if self.excinfo_target is not None:
4267 self.excinfo_target.analyse_target_declaration(env)
4268 self.body.analyse_declarations(env)
4270 def analyse_expressions(self, env):
4272 genv = env.global_scope()
4273 self.function_name = env.qualified_name
4275 self.pattern.analyse_expressions(env)
4276 self.pattern = self.pattern.coerce_to_pyobject(env)
4277 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4278 self.pattern.release_temp(env)
4279 env.release_temp(self.match_flag)
4281 if self.target or self.excinfo_target:
4282 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4284 self.exc_vars = None
4287 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4288 self.exc_value.allocate_temps(env)
4289 self.target.analyse_target_expression(env, self.exc_value)
4290 if self.excinfo_target is not None:
4292 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4293 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4294 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4295 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4297 self.excinfo_tuple.analyse_expressions(env)
4298 self.excinfo_tuple.allocate_temps(env)
4299 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4301 self.body.analyse_expressions(env)
4304 for var in self.exc_vars:
4305 env.release_temp(var)
4307 def generate_handling_code(self, code, end_label):
4308 code.mark_pos(self.pos)
4310 self.pattern.generate_evaluation_code(code)
4312 "%s = PyErr_ExceptionMatches(%s);" % (
4314 self.pattern.py_result()))
4315 self.pattern.generate_disposal_code(code)
4316 self.pattern.free_temps(code)
4321 code.putln("/*except:*/ {")
4324 exc_vars = self.exc_vars
4325 elif not getattr(self.body, 'stats', True):
4326 # most simple case: no exception variable, empty body (pass)
4327 # => reset the exception state, done
4328 code.putln("PyErr_Restore(0,0,0);")
4329 code.put_goto(end_label)
4333 # during type analysis, we didn't know if we need the
4334 # exception value, but apparently, we do
4335 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4339 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4340 # We always have to fetch the exception value even if
4341 # there is no target, because this also normalises the
4342 # exception and stores it in the thread state.
4343 code.globalstate.use_utility_code(get_exception_utility_code)
4344 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4345 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4346 code.error_goto(self.pos)))
4350 self.exc_value.generate_evaluation_code(code)
4351 self.target.generate_assignment_code(self.exc_value, code)
4352 if self.excinfo_target is not None:
4353 self.excinfo_tuple.generate_evaluation_code(code)
4354 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4357 old_break_label, old_continue_label = code.break_label, code.continue_label
4358 code.break_label = code.new_label('except_break')
4359 code.continue_label = code.new_label('except_continue')
4361 old_exc_vars = code.funcstate.exc_vars
4362 code.funcstate.exc_vars = exc_vars
4363 self.body.generate_execution_code(code)
4364 code.funcstate.exc_vars = old_exc_vars
4365 for var in exc_vars:
4366 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4367 code.put_goto(end_label)
4369 if code.label_used(code.break_label):
4370 code.put_label(code.break_label)
4371 for var in exc_vars:
4372 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4373 code.put_goto(old_break_label)
4374 code.break_label = old_break_label
4376 if code.label_used(code.continue_label):
4377 code.put_label(code.continue_label)
4378 for var in exc_vars:
4379 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4380 code.put_goto(old_continue_label)
4381 code.continue_label = old_continue_label
4383 if not self.exc_vars:
4384 # clean up locally allocated temps
4385 for temp in exc_vars:
4386 code.funcstate.release_temp(temp)
4391 def annotate(self, code):
4393 self.pattern.annotate(code)
4395 self.target.annotate(code)
4396 self.body.annotate(code)
4399 class TryFinallyStatNode(StatNode):
4400 # try ... finally statement
4403 # finally_clause StatNode
4405 # cleanup_list [Entry] old_style temps to clean up on error
4407 # The plan is that we funnel all continue, break
4408 # return and error gotos into the beginning of the
4409 # finally block, setting a variable to remember which
4410 # one we're doing. At the end of the finally block, we
4411 # switch on the variable to figure out where to go.
4412 # In addition, if we're doing an error, we save the
4413 # exception on entry to the finally block and restore
4416 child_attrs = ["body", "finally_clause"]
4418 preserve_exception = 1
4420 disallow_continue_in_try_finally = 0
4421 # There doesn't seem to be any point in disallowing
4422 # continue in the try block, since we have no problem
4425 def create_analysed(pos, env, body, finally_clause):
4426 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4427 node.cleanup_list = []
4429 create_analysed = staticmethod(create_analysed)
4431 def analyse_control_flow(self, env):
4432 env.start_branching(self.pos)
4433 self.body.analyse_control_flow(env)
4434 env.next_branch(self.body.end_pos())
4435 env.finish_branching(self.body.end_pos())
4436 self.finally_clause.analyse_control_flow(env)
4438 def analyse_declarations(self, env):
4439 self.body.analyse_declarations(env)
4440 self.finally_clause.analyse_declarations(env)
4442 def analyse_expressions(self, env):
4443 self.body.analyse_expressions(env)
4444 self.cleanup_list = env.free_temp_entries[:]
4445 self.finally_clause.analyse_expressions(env)
4448 gil_message = "Try-finally statement"
4450 def generate_execution_code(self, code):
4451 old_error_label = code.error_label
4452 old_labels = code.all_new_labels()
4453 new_labels = code.get_all_labels()
4454 new_error_label = code.error_label
4455 catch_label = code.new_label()
4458 if self.disallow_continue_in_try_finally:
4459 was_in_try_finally = code.funcstate.in_try_finally
4460 code.funcstate.in_try_finally = 1
4461 self.body.generate_execution_code(code)
4462 if self.disallow_continue_in_try_finally:
4463 code.funcstate.in_try_finally = was_in_try_finally
4466 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4470 error_label_used = 0
4471 for i, new_label in enumerate(new_labels):
4472 if new_label in code.labels_used:
4473 cases_used.append(i)
4474 if new_label == new_error_label:
4475 error_label_used = 1
4476 error_label_case = i
4480 if error_label_used and self.preserve_exception:
4482 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4484 "int %s;" % Naming.exc_lineno_name)
4485 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4486 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4487 code.putln(exc_var_init_zero)
4489 exc_var_init_zero = None
4490 code.use_label(catch_label)
4492 "__pyx_why = 0; goto %s;" % catch_label)
4493 for i in cases_used:
4494 new_label = new_labels[i]
4495 #if new_label and new_label != "<try>":
4496 if new_label == new_error_label and self.preserve_exception:
4497 self.put_error_catcher(code,
4498 new_error_label, i+1, catch_label, temps_to_clean_up)
4500 code.put('%s: ' % new_label)
4501 if exc_var_init_zero:
4502 code.putln(exc_var_init_zero)
4503 code.putln("__pyx_why = %s; goto %s;" % (
4506 code.put_label(catch_label)
4507 code.set_all_labels(old_labels)
4508 if error_label_used:
4509 code.new_error_label()
4510 finally_error_label = code.error_label
4511 self.finally_clause.generate_execution_code(code)
4512 if error_label_used:
4513 if finally_error_label in code.labels_used and self.preserve_exception:
4514 over_label = code.new_label()
4515 code.put_goto(over_label);
4516 code.put_label(finally_error_label)
4517 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4518 for var in Naming.exc_vars:
4519 code.putln("Py_XDECREF(%s);" % var)
4521 code.put_goto(old_error_label)
4522 code.put_label(over_label)
4523 code.error_label = old_error_label
4526 "switch (__pyx_why) {")
4527 for i in cases_used:
4528 old_label = old_labels[i]
4529 if old_label == old_error_label and self.preserve_exception:
4530 self.put_error_uncatcher(code, i+1, old_error_label)
4532 code.use_label(old_label)
4534 "case %s: goto %s;" % (
4542 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4543 code.globalstate.use_utility_code(restore_exception_utility_code)
4550 code.put_var_xdecrefs_clear(self.cleanup_list)
4551 for temp_name, type in temps_to_clean_up:
4552 code.put_xdecref_clear(temp_name, type)
4554 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4558 Naming.exc_lineno_name, Naming.lineno_cname))
4562 code.put_goto(catch_label)
4566 def put_error_uncatcher(self, code, i, error_label):
4567 code.globalstate.use_utility_code(restore_exception_utility_code)
4572 "__Pyx_ErrRestore(%s, %s, %s);" %
4576 Naming.lineno_cname, Naming.exc_lineno_name))
4577 for var in Naming.exc_vars:
4581 code.put_goto(error_label)
4585 def annotate(self, code):
4586 self.body.annotate(code)
4587 self.finally_clause.annotate(code)
4590 class GILStatNode(TryFinallyStatNode):
4591 # 'with gil' or 'with nogil' statement
4593 # state string 'gil' or 'nogil'
4597 preserve_exception = 0
4599 def __init__(self, pos, state, body):
4601 TryFinallyStatNode.__init__(self, pos,
4603 finally_clause = GILExitNode(pos, state = state))
4605 def analyse_expressions(self, env):
4606 env.use_utility_code(force_init_threads_utility_code)
4607 was_nogil = env.nogil
4609 TryFinallyStatNode.analyse_expressions(self, env)
4610 env.nogil = was_nogil
4612 def gil_check(self, env):
4615 def generate_execution_code(self, code):
4616 code.mark_pos(self.pos)
4617 if self.state == 'gil':
4618 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4620 code.putln("{ PyThreadState *_save;")
4621 code.putln("Py_UNBLOCK_THREADS")
4622 TryFinallyStatNode.generate_execution_code(self, code)
4626 class GILExitNode(StatNode):
4627 # Used as the 'finally' block in a GILStatNode
4629 # state string 'gil' or 'nogil'
4633 def analyse_expressions(self, env):
4636 def generate_execution_code(self, code):
4637 if self.state == 'gil':
4638 code.putln("PyGILState_Release();")
4640 code.putln("Py_BLOCK_THREADS")
4643 class CImportStatNode(StatNode):
4646 # module_name string Qualified name of module being imported
4647 # as_name string or None Name specified in "as" clause, if any
4651 def analyse_declarations(self, env):
4652 if not env.is_module_scope:
4653 error(self.pos, "cimport only allowed at module level")
4655 module_scope = env.find_module(self.module_name, self.pos)
4656 if "." in self.module_name:
4657 names = [EncodedString(name) for name in self.module_name.split(".")]
4659 top_module_scope = env.context.find_submodule(top_name)
4660 module_scope = top_module_scope
4661 for name in names[1:]:
4662 submodule_scope = module_scope.find_submodule(name)
4663 module_scope.declare_module(name, submodule_scope, self.pos)
4664 module_scope = submodule_scope
4666 env.declare_module(self.as_name, module_scope, self.pos)
4668 env.declare_module(top_name, top_module_scope, self.pos)
4670 name = self.as_name or self.module_name
4671 env.declare_module(name, module_scope, self.pos)
4673 def analyse_expressions(self, env):
4676 def generate_execution_code(self, code):
4680 class FromCImportStatNode(StatNode):
4681 # from ... cimport statement
4683 # module_name string Qualified name of module
4684 # imported_names [(pos, name, as_name, kind)] Names to be imported
4688 def analyse_declarations(self, env):
4689 if not env.is_module_scope:
4690 error(self.pos, "cimport only allowed at module level")
4692 module_scope = env.find_module(self.module_name, self.pos)
4693 env.add_imported_module(module_scope)
4694 for pos, name, as_name, kind in self.imported_names:
4696 for local_name, entry in module_scope.entries.items():
4697 env.add_imported_entry(local_name, entry, pos)
4699 entry = module_scope.lookup(name)
4701 if kind and not self.declaration_matches(entry, kind):
4702 entry.redeclared(pos)
4704 if kind == 'struct' or kind == 'union':
4705 entry = module_scope.declare_struct_or_union(name,
4706 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4707 elif kind == 'class':
4708 entry = module_scope.declare_c_class(name, pos = pos,
4709 module_name = self.module_name)
4711 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4712 if submodule_scope.parent_module is module_scope:
4713 env.declare_module(as_name or name, submodule_scope, self.pos)
4715 error(pos, "Name '%s' not declared in module '%s'"
4716 % (name, self.module_name))
4719 local_name = as_name or name
4720 env.add_imported_entry(local_name, entry, pos)
4722 def declaration_matches(self, entry, kind):
4723 if not entry.is_type:
4727 if not type.is_extension_type:
4730 if not type.is_struct_or_union:
4732 if kind != type.kind:
4736 def analyse_expressions(self, env):
4739 def generate_execution_code(self, code):
4743 class FromImportStatNode(StatNode):
4744 # from ... import statement
4747 # items [(string, NameNode)]
4748 # interned_items [(string, NameNode, ExprNode)]
4749 # item PyTempNode used internally
4750 # import_star boolean used internally
4752 child_attrs = ["module"]
4755 def analyse_declarations(self, env):
4756 for name, target in self.items:
4758 if not env.is_module_scope:
4759 error(self.pos, "import * only allowed at module level")
4761 env.has_import_star = 1
4762 self.import_star = 1
4764 target.analyse_target_declaration(env)
4766 def analyse_expressions(self, env):
4768 self.module.analyse_expressions(env)
4769 self.item = ExprNodes.PyTempNode(self.pos, env)
4770 self.item.allocate_temp(env)
4771 self.interned_items = []
4772 for name, target in self.items:
4774 for _, entry in env.entries.items():
4775 if not entry.is_type and entry.type.is_extension_type:
4776 env.use_utility_code(ExprNodes.type_test_utility_code)
4779 entry = env.lookup(target.name)
4780 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4781 continue # already cimported
4782 target.analyse_target_expression(env, None)
4783 if target.type is py_object_type:
4786 coerced_item = self.item.coerce_to(target.type, env)
4787 self.interned_items.append(
4788 (env.intern_identifier(name), target, coerced_item))
4789 #target.release_target_temp(env) # was release_temp ?!?
4790 self.module.release_temp(env)
4791 self.item.release_temp(env)
4793 def generate_execution_code(self, code):
4794 self.module.generate_evaluation_code(code)
4795 if self.import_star:
4797 'if (%s(%s) < 0) %s;' % (
4799 self.module.py_result(),
4800 code.error_goto(self.pos)))
4801 for cname, target, coerced_item in self.interned_items:
4803 '%s = PyObject_GetAttr(%s, %s); %s' % (
4805 self.module.py_result(),
4807 code.error_goto_if_null(self.item.result(), self.pos)))
4808 code.put_gotref(self.item.py_result())
4809 if coerced_item is None:
4810 target.generate_assignment_code(self.item, code)
4812 coerced_item.allocate_temp_result(code)
4813 coerced_item.generate_result_code(code)
4814 target.generate_assignment_code(coerced_item, code)
4815 if self.item.result() != coerced_item.result():
4816 code.put_decref_clear(self.item.result(), self.item.type)
4817 self.module.generate_disposal_code(code)
4818 self.module.free_temps(code)
4822 #------------------------------------------------------------------------------------
4824 # Runtime support code
4826 #------------------------------------------------------------------------------------
4828 utility_function_predeclarations = \
4831 #define INLINE __inline__
4833 #define INLINE __inline
4838 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4842 static int %(skip_dispatch_cname)s = 0;
4844 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4846 if Options.gcc_branch_hints:
4847 branch_prediction_macros = \
4850 /* Test for GCC > 2.95 */
4851 #if __GNUC__ > 2 || \
4852 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4853 #define likely(x) __builtin_expect(!!(x), 1)
4854 #define unlikely(x) __builtin_expect(!!(x), 0)
4855 #else /* __GNUC__ > 2 ... */
4856 #define likely(x) (x)
4857 #define unlikely(x) (x)
4858 #endif /* __GNUC__ > 2 ... */
4859 #else /* __GNUC__ */
4860 #define likely(x) (x)
4861 #define unlikely(x) (x)
4862 #endif /* __GNUC__ */
4865 branch_prediction_macros = \
4867 #define likely(x) (x)
4868 #define unlikely(x) (x)
4871 #get_name_predeclaration = \
4872 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4874 #get_name_interned_predeclaration = \
4875 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4877 #------------------------------------------------------------------------------------
4879 printing_utility_code = UtilityCode(
4881 static int __Pyx_Print(PyObject *, int); /*proto*/
4882 #if PY_MAJOR_VERSION >= 3
4883 static PyObject* %s = 0;
4884 static PyObject* %s = 0;
4886 """ % (Naming.print_function, Naming.print_function_kwargs),
4888 #if PY_MAJOR_VERSION < 3
4889 static PyObject *__Pyx_GetStdout(void) {
4890 PyObject *f = PySys_GetObject((char *)"stdout");
4892 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4897 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4902 if (!(f = __Pyx_GetStdout()))
4904 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4905 if (PyFile_SoftSpace(f, 1)) {
4906 if (PyFile_WriteString(" ", f) < 0)
4909 v = PyTuple_GET_ITEM(arg_tuple, i);
4910 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4912 if (PyString_Check(v)) {
4913 char *s = PyString_AsString(v);
4914 Py_ssize_t len = PyString_Size(v);
4916 isspace(Py_CHARMASK(s[len-1])) &&
4918 PyFile_SoftSpace(f, 0);
4922 if (PyFile_WriteString("\n", f) < 0)
4924 PyFile_SoftSpace(f, 0);
4929 #else /* Python 3 has a print function */
4931 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4932 PyObject* kwargs = 0;
4933 PyObject* result = 0;
4934 PyObject* end_string;
4935 if (!%(PRINT_FUNCTION)s) {
4936 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4937 if (!%(PRINT_FUNCTION)s)
4941 if (!%(PRINT_KWARGS)s) {
4942 %(PRINT_KWARGS)s = PyDict_New();
4943 if (!%(PRINT_KWARGS)s)
4945 end_string = PyUnicode_FromStringAndSize(" ", 1);
4948 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4949 Py_DECREF(end_string);
4952 Py_DECREF(end_string);
4954 kwargs = %(PRINT_KWARGS)s;
4956 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4964 """ % {'BUILTINS' : Naming.builtins_cname,
4965 'PRINT_FUNCTION' : Naming.print_function,
4966 'PRINT_KWARGS' : Naming.print_function_kwargs}
4970 printing_one_utility_code = UtilityCode(
4972 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4975 #if PY_MAJOR_VERSION < 3
4977 static int __Pyx_PrintOne(PyObject *o) {
4979 if (!(f = __Pyx_GetStdout()))
4981 if (PyFile_SoftSpace(f, 0)) {
4982 if (PyFile_WriteString(" ", f) < 0)
4985 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4987 if (PyFile_WriteString("\n", f) < 0)
4990 /* the line below is just to avoid compiler
4991 * compiler warnings about unused functions */
4992 return __Pyx_Print(NULL, 0);
4995 #else /* Python 3 has a print function */
4997 static int __Pyx_PrintOne(PyObject *o) {
4999 PyObject* arg_tuple = PyTuple_New(1);
5000 if (unlikely(!arg_tuple))
5003 PyTuple_SET_ITEM(arg_tuple, 0, o);
5004 res = __Pyx_Print(arg_tuple, 1);
5005 Py_DECREF(arg_tuple);
5011 requires=[printing_utility_code])
5015 #------------------------------------------------------------------------------------
5017 # The following function is based on do_raise() from ceval.c.
5019 raise_utility_code = UtilityCode(
5021 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5024 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5028 /* First, check the traceback argument, replacing None with NULL. */
5029 if (tb == Py_None) {
5033 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5034 PyErr_SetString(PyExc_TypeError,
5035 "raise: arg 3 must be a traceback or None");
5038 /* Next, replace a missing value with None */
5039 if (value == NULL) {
5043 #if PY_VERSION_HEX < 0x02050000
5044 if (!PyClass_Check(type))
5046 if (!PyType_Check(type))
5049 /* Raising an instance. The value should be a dummy. */
5050 if (value != Py_None) {
5051 PyErr_SetString(PyExc_TypeError,
5052 "instance exception may not have a separate value");
5055 /* Normalize to raise <class>, <instance> */
5058 #if PY_VERSION_HEX < 0x02050000
5059 if (PyInstance_Check(type)) {
5060 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5065 PyErr_SetString(PyExc_TypeError,
5066 "raise: exception must be an old-style class or instance");
5070 type = (PyObject*) Py_TYPE(type);
5072 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5073 PyErr_SetString(PyExc_TypeError,
5074 "raise: exception class must be a subclass of BaseException");
5079 __Pyx_ErrRestore(type, value, tb);
5089 #------------------------------------------------------------------------------------
5091 reraise_utility_code = UtilityCode(
5093 static void __Pyx_ReRaise(void); /*proto*/
5096 static void __Pyx_ReRaise(void) {
5097 PyThreadState *tstate = PyThreadState_GET();
5098 PyObject* tmp_type = tstate->curexc_type;
5099 PyObject* tmp_value = tstate->curexc_value;
5100 PyObject* tmp_tb = tstate->curexc_traceback;
5101 tstate->curexc_type = tstate->exc_type;
5102 tstate->curexc_value = tstate->exc_value;
5103 tstate->curexc_traceback = tstate->exc_traceback;
5104 tstate->exc_type = 0;
5105 tstate->exc_value = 0;
5106 tstate->exc_traceback = 0;
5107 Py_XDECREF(tmp_type);
5108 Py_XDECREF(tmp_value);
5113 #------------------------------------------------------------------------------------
5115 arg_type_test_utility_code = UtilityCode(
5117 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5118 const char *name, int exact); /*proto*/
5121 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5122 const char *name, int exact)
5125 PyErr_Format(PyExc_SystemError, "Missing type object");
5128 if (none_allowed && obj == Py_None) return 1;
5130 if (Py_TYPE(obj) == type) return 1;
5133 if (PyObject_TypeCheck(obj, type)) return 1;
5135 PyErr_Format(PyExc_TypeError,
5136 "Argument '%s' has incorrect type (expected %s, got %s)",
5137 name, type->tp_name, Py_TYPE(obj)->tp_name);
5142 #------------------------------------------------------------------------------------
5144 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5145 # many or too few positional arguments were found. This handles
5146 # Py_ssize_t formatting correctly.
5148 raise_argtuple_invalid_utility_code = UtilityCode(
5150 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5151 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5154 static void __Pyx_RaiseArgtupleInvalid(
5155 const char* func_name,
5159 Py_ssize_t num_found)
5161 Py_ssize_t num_expected;
5162 const char *number, *more_or_less;
5164 if (num_found < num_min) {
5165 num_expected = num_min;
5166 more_or_less = "at least";
5168 num_expected = num_max;
5169 more_or_less = "at most";
5172 more_or_less = "exactly";
5174 number = (num_expected == 1) ? "" : "s";
5175 PyErr_Format(PyExc_TypeError,
5176 #if PY_VERSION_HEX < 0x02050000
5177 "%s() takes %s %d positional argument%s (%d given)",
5179 "%s() takes %s %zd positional argument%s (%zd given)",
5181 func_name, more_or_less, num_expected, number, num_found);
5185 raise_keyword_required_utility_code = UtilityCode(
5187 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5190 static INLINE void __Pyx_RaiseKeywordRequired(
5191 const char* func_name,
5194 PyErr_Format(PyExc_TypeError,
5195 #if PY_MAJOR_VERSION >= 3
5196 "%s() needs keyword-only argument %U", func_name, kw_name);
5198 "%s() needs keyword-only argument %s", func_name,
5199 PyString_AS_STRING(kw_name));
5204 raise_double_keywords_utility_code = UtilityCode(
5206 static void __Pyx_RaiseDoubleKeywordsError(
5207 const char* func_name, PyObject* kw_name); /*proto*/
5210 static void __Pyx_RaiseDoubleKeywordsError(
5211 const char* func_name,
5214 PyErr_Format(PyExc_TypeError,
5215 #if PY_MAJOR_VERSION >= 3
5216 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5218 "%s() got multiple values for keyword argument '%s'", func_name,
5219 PyString_AS_STRING(kw_name));
5224 #------------------------------------------------------------------------------------
5226 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5227 # were passed to a function, or if any keywords were passed to a
5228 # function that does not accept them.
5230 keyword_string_check_utility_code = UtilityCode(
5232 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5233 const char* function_name, int kw_allowed); /*proto*/
5236 static INLINE int __Pyx_CheckKeywordStrings(
5238 const char* function_name,
5243 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5244 #if PY_MAJOR_VERSION < 3
5245 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5247 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5249 goto invalid_keyword_type;
5251 if ((!kw_allowed) && unlikely(key))
5252 goto invalid_keyword;
5254 invalid_keyword_type:
5255 PyErr_Format(PyExc_TypeError,
5256 "%s() keywords must be strings", function_name);
5259 PyErr_Format(PyExc_TypeError,
5260 #if PY_MAJOR_VERSION < 3
5261 "%s() got an unexpected keyword argument '%s'",
5262 function_name, PyString_AsString(key));
5264 "%s() got an unexpected keyword argument '%U'",
5265 function_name, key);
5271 #------------------------------------------------------------------------------------
5273 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5274 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5275 # keywords will raise an invalid keyword error.
5277 # Three kinds of errors are checked: 1) non-string keywords, 2)
5278 # unexpected keywords and 3) overlap with positional arguments.
5280 # If num_posargs is greater 0, it denotes the number of positional
5281 # arguments that were passed and that must therefore not appear
5282 # amongst the keywords as well.
5284 # This method does not check for required keyword arguments.
5287 parse_keywords_utility_code = UtilityCode(
5289 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5290 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5291 const char* function_name); /*proto*/
5294 static int __Pyx_ParseOptionalKeywords(
5296 PyObject **argnames[],
5299 Py_ssize_t num_pos_args,
5300 const char* function_name)
5302 PyObject *key = 0, *value = 0;
5305 PyObject*** first_kw_arg = argnames + num_pos_args;
5307 while (PyDict_Next(kwds, &pos, &key, &value)) {
5308 name = first_kw_arg;
5309 while (*name && (**name != key)) name++;
5311 values[name-argnames] = value;
5313 #if PY_MAJOR_VERSION < 3
5314 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5316 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5318 goto invalid_keyword_type;
5320 for (name = first_kw_arg; *name; name++) {
5321 #if PY_MAJOR_VERSION >= 3
5322 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5323 PyUnicode_Compare(**name, key) == 0) break;
5325 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5326 _PyString_Eq(**name, key)) break;
5330 values[name-argnames] = value;
5332 /* unexpected keyword found */
5333 for (name=argnames; name != first_kw_arg; name++) {
5334 if (**name == key) goto arg_passed_twice;
5335 #if PY_MAJOR_VERSION >= 3
5336 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5337 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5339 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5340 _PyString_Eq(**name, key)) goto arg_passed_twice;
5344 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5346 goto invalid_keyword;
5354 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5356 invalid_keyword_type:
5357 PyErr_Format(PyExc_TypeError,
5358 "%s() keywords must be strings", function_name);
5361 PyErr_Format(PyExc_TypeError,
5362 #if PY_MAJOR_VERSION < 3
5363 "%s() got an unexpected keyword argument '%s'",
5364 function_name, PyString_AsString(key));
5366 "%s() got an unexpected keyword argument '%U'",
5367 function_name, key);
5374 #------------------------------------------------------------------------------------
5376 traceback_utility_code = UtilityCode(
5378 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5381 #include "compile.h"
5382 #include "frameobject.h"
5383 #include "traceback.h"
5385 static void __Pyx_AddTraceback(const char *funcname) {
5386 PyObject *py_srcfile = 0;
5387 PyObject *py_funcname = 0;
5388 PyObject *py_globals = 0;
5389 PyObject *empty_string = 0;
5390 PyCodeObject *py_code = 0;
5391 PyFrameObject *py_frame = 0;
5393 #if PY_MAJOR_VERSION < 3
5394 py_srcfile = PyString_FromString(%(FILENAME)s);
5396 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5398 if (!py_srcfile) goto bad;
5400 #if PY_MAJOR_VERSION < 3
5401 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5403 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5407 #if PY_MAJOR_VERSION < 3
5408 py_funcname = PyString_FromString(funcname);
5410 py_funcname = PyUnicode_FromString(funcname);
5413 if (!py_funcname) goto bad;
5414 py_globals = PyModule_GetDict(%(GLOBALS)s);
5415 if (!py_globals) goto bad;
5416 #if PY_MAJOR_VERSION < 3
5417 empty_string = PyString_FromStringAndSize("", 0);
5419 empty_string = PyBytes_FromStringAndSize("", 0);
5421 if (!empty_string) goto bad;
5422 py_code = PyCode_New(
5423 0, /*int argcount,*/
5424 #if PY_MAJOR_VERSION >= 3
5425 0, /*int kwonlyargcount,*/
5428 0, /*int stacksize,*/
5430 empty_string, /*PyObject *code,*/
5431 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5432 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5433 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5434 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5435 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5436 py_srcfile, /*PyObject *filename,*/
5437 py_funcname, /*PyObject *name,*/
5438 %(LINENO)s, /*int firstlineno,*/
5439 empty_string /*PyObject *lnotab*/
5441 if (!py_code) goto bad;
5442 py_frame = PyFrame_New(
5443 PyThreadState_GET(), /*PyThreadState *tstate,*/
5444 py_code, /*PyCodeObject *code,*/
5445 py_globals, /*PyObject *globals,*/
5446 0 /*PyObject *locals*/
5448 if (!py_frame) goto bad;
5449 py_frame->f_lineno = %(LINENO)s;
5450 PyTraceBack_Here(py_frame);
5452 Py_XDECREF(py_srcfile);
5453 Py_XDECREF(py_funcname);
5454 Py_XDECREF(empty_string);
5455 Py_XDECREF(py_code);
5456 Py_XDECREF(py_frame);
5459 'FILENAME': Naming.filename_cname,
5460 'LINENO': Naming.lineno_cname,
5461 'CFILENAME': Naming.cfilenm_cname,
5462 'CLINENO': Naming.clineno_cname,
5463 'GLOBALS': Naming.module_cname,
5464 'EMPTY_TUPLE' : Naming.empty_tuple,
5467 restore_exception_utility_code = UtilityCode(
5469 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5470 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5473 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5474 PyObject *tmp_type, *tmp_value, *tmp_tb;
5475 PyThreadState *tstate = PyThreadState_GET();
5477 #if PY_MAJOR_VERSION >= 3
5478 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5479 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5480 tmp_type = tstate->exc_type;
5481 tmp_value = tstate->exc_value;
5482 tmp_tb = tstate->exc_traceback;
5483 PyErr_NormalizeException(&type, &value, &tb);
5484 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5485 tstate->exc_type = 0;
5486 tstate->exc_value = 0;
5487 tstate->exc_traceback = 0;
5488 PyException_SetContext(value, tmp_value);
5489 Py_DECREF(tmp_type);
5494 tmp_type = tstate->curexc_type;
5495 tmp_value = tstate->curexc_value;
5496 tmp_tb = tstate->curexc_traceback;
5497 tstate->curexc_type = type;
5498 tstate->curexc_value = value;
5499 tstate->curexc_traceback = tb;
5500 Py_XDECREF(tmp_type);
5501 Py_XDECREF(tmp_value);
5505 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5506 PyThreadState *tstate = PyThreadState_GET();
5507 *type = tstate->curexc_type;
5508 *value = tstate->curexc_value;
5509 *tb = tstate->curexc_traceback;
5511 tstate->curexc_type = 0;
5512 tstate->curexc_value = 0;
5513 tstate->curexc_traceback = 0;
5518 #------------------------------------------------------------------------------------
5520 unraisable_exception_utility_code = UtilityCode(
5522 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5525 static void __Pyx_WriteUnraisable(const char *name) {
5526 PyObject *old_exc, *old_val, *old_tb;
5528 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5529 #if PY_MAJOR_VERSION < 3
5530 ctx = PyString_FromString(name);
5532 ctx = PyUnicode_FromString(name);
5534 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5536 PyErr_WriteUnraisable(Py_None);
5538 PyErr_WriteUnraisable(ctx);
5543 requires=[restore_exception_utility_code])
5545 #------------------------------------------------------------------------------------
5547 set_vtable_utility_code = UtilityCode(
5549 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5552 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5553 PyObject *pycobj = 0;
5556 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5559 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5572 #------------------------------------------------------------------------------------
5574 get_vtable_utility_code = UtilityCode(
5576 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5579 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5583 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5586 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5587 if (!*(void **)vtabptr)
5600 #------------------------------------------------------------------------------------
5602 init_string_tab_utility_code = UtilityCode(
5604 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5607 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5609 #if PY_MAJOR_VERSION < 3
5610 if (t->is_unicode && (!t->is_identifier)) {
5611 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5612 } else if (t->intern) {
5613 *t->p = PyString_InternFromString(t->s);
5615 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5617 #else /* Python 3+ has unicode identifiers */
5618 if (t->is_identifier || (t->is_unicode && t->intern)) {
5619 *t->p = PyUnicode_InternFromString(t->s);
5620 } else if (t->is_unicode) {
5621 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5623 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5634 #------------------------------------------------------------------------------------
5636 get_exception_utility_code = UtilityCode(
5638 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5641 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5642 PyObject *tmp_type, *tmp_value, *tmp_tb;
5643 PyThreadState *tstate = PyThreadState_GET();
5644 *type = tstate->curexc_type;
5645 *value = tstate->curexc_value;
5646 *tb = tstate->curexc_traceback;
5647 tstate->curexc_type = 0;
5648 tstate->curexc_value = 0;
5649 tstate->curexc_traceback = 0;
5650 PyErr_NormalizeException(type, value, tb);
5651 if (PyErr_Occurred())
5656 tmp_type = tstate->exc_type;
5657 tmp_value = tstate->exc_value;
5658 tmp_tb = tstate->exc_traceback;
5659 tstate->exc_type = *type;
5660 tstate->exc_value = *value;
5661 tstate->exc_traceback = *tb;
5662 /* Make sure tstate is in a consistent state when we XDECREF
5663 these objects (XDECREF may run arbitrary code). */
5664 Py_XDECREF(tmp_type);
5665 Py_XDECREF(tmp_value);
5677 #------------------------------------------------------------------------------------
5679 reset_exception_utility_code = UtilityCode(
5681 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5682 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5685 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5686 PyThreadState *tstate = PyThreadState_GET();
5687 *type = tstate->exc_type;
5688 *value = tstate->exc_value;
5689 *tb = tstate->exc_traceback;
5695 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5696 PyObject *tmp_type, *tmp_value, *tmp_tb;
5697 PyThreadState *tstate = PyThreadState_GET();
5698 tmp_type = tstate->exc_type;
5699 tmp_value = tstate->exc_value;
5700 tmp_tb = tstate->exc_traceback;
5701 tstate->exc_type = type;
5702 tstate->exc_value = value;
5703 tstate->exc_traceback = tb;
5704 Py_XDECREF(tmp_type);
5705 Py_XDECREF(tmp_value);
5710 #------------------------------------------------------------------------------------
5712 force_init_threads_utility_code = UtilityCode(
5714 #ifndef __PYX_FORCE_INIT_THREADS
5715 #if PY_VERSION_HEX < 0x02040200
5716 #define __PYX_FORCE_INIT_THREADS 1
5718 #define __PYX_FORCE_INIT_THREADS 0
5723 #------------------------------------------------------------------------------------