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
844 child_attrs = ["attributes"]
846 def analyse_declarations(self, env):
848 if self.attributes is not None:
849 scope = StructOrUnionScope(self.name)
850 self.entry = env.declare_struct_or_union(
851 self.name, self.kind, scope, self.typedef_flag, self.pos,
852 self.cname, visibility = self.visibility)
853 if self.attributes is not None:
854 if self.in_pxd and not env.in_cinclude:
855 self.entry.defined_in_pxd = 1
856 for attr in self.attributes:
857 attr.analyse_declarations(env, scope)
858 if self.visibility != 'extern':
859 need_typedef_indirection = False
860 for attr in scope.var_entries:
863 type = type.base_type
864 if type == self.entry.type:
865 error(attr.pos, "Struct cannot contain itself as a member.")
866 if self.typedef_flag:
868 type = type.base_type
869 if type == self.entry.type:
870 need_typedef_indirection = True
871 if need_typedef_indirection:
872 # C can't handle typedef structs that refer to themselves.
873 struct_entry = self.entry
874 cname = env.new_const_cname()
875 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
876 struct_entry.type.typedef_flag = False
877 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
879 def analyse_expressions(self, env):
882 def generate_execution_code(self, code):
886 class CEnumDefNode(StatNode):
887 # name string or None
888 # cname string or None
889 # items [CEnumDefItemNode]
890 # typedef_flag boolean
891 # visibility "public" or "private"
895 child_attrs = ["items"]
897 def analyse_declarations(self, env):
898 self.entry = env.declare_enum(self.name, self.pos,
899 cname = self.cname, typedef_flag = self.typedef_flag,
900 visibility = self.visibility)
901 if self.items is not None:
902 if self.in_pxd and not env.in_cinclude:
903 self.entry.defined_in_pxd = 1
904 for item in self.items:
905 item.analyse_declarations(env, self.entry)
907 def analyse_expressions(self, env):
908 if self.visibility == 'public':
909 self.temp = env.allocate_temp_pyobject()
910 env.release_temp(self.temp)
912 def generate_execution_code(self, code):
913 if self.visibility == 'public':
914 for item in self.entry.enum_values:
915 code.putln("%s = PyInt_FromLong(%s); %s" % (
918 code.error_goto_if_null(self.temp, item.pos)))
919 code.put_gotref(self.temp)
920 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
924 code.error_goto(item.pos)))
925 code.put_decref_clear(self.temp, PyrexTypes.py_object_type)
928 class CEnumDefItemNode(StatNode):
930 # cname string or None
931 # value ExprNode or None
933 child_attrs = ["value"]
935 def analyse_declarations(self, env, enum_entry):
937 self.value.analyse_const_expression(env)
938 if not self.value.type.is_int:
939 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
940 self.value.analyse_const_expression(env)
941 value = self.value.result()
944 entry = env.declare_const(self.name, enum_entry.type,
945 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
946 enum_entry.enum_values.append(entry)
949 class CTypeDefNode(StatNode):
950 # base_type CBaseTypeNode
951 # declarator CDeclaratorNode
952 # visibility "public" or "private"
955 child_attrs = ["base_type", "declarator"]
957 def analyse_declarations(self, env):
958 base = self.base_type.analyse(env)
959 name_declarator, type = self.declarator.analyse(base, env)
960 name = name_declarator.name
961 cname = name_declarator.cname
962 entry = env.declare_typedef(name, type, self.pos,
963 cname = cname, visibility = self.visibility)
964 if self.in_pxd and not env.in_cinclude:
965 entry.defined_in_pxd = 1
967 def analyse_expressions(self, env):
969 def generate_execution_code(self, code):
973 class FuncDefNode(StatNode, BlockNode):
974 # Base class for function definition nodes.
976 # return_type PyrexType
977 # #filename string C name of filename string const
979 # needs_closure boolean Whether or not this function has inner functions/classes/yield
980 # directive_locals { string : NameNode } locals defined by cython.locals(...)
984 needs_closure = False
986 def analyse_default_values(self, env):
987 genv = env.global_scope()
988 for arg in self.args:
991 if not hasattr(arg, 'default_entry'):
992 arg.default.analyse_types(env)
993 arg.default = arg.default.coerce_to(arg.type, genv)
994 if arg.default.is_literal:
995 arg.default_entry = arg.default
996 arg.default_result_code = arg.default.calculate_result_code()
997 if arg.default.type != arg.type and not arg.type.is_int:
998 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1000 arg.default.allocate_temps(genv)
1001 arg.default_entry = genv.add_default_value(arg.type)
1002 if arg.type.is_pyobject:
1003 arg.default_entry.init = 0
1004 arg.default_entry.used = 1
1005 arg.default_result_code = arg.default_entry.cname
1008 "This argument cannot have a default value")
1011 def need_gil_acquisition(self, lenv):
1014 def create_local_scope(self, env):
1016 while env.is_py_class_scope or env.is_c_class_scope:
1017 env = env.outer_scope
1018 if self.needs_closure:
1019 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1021 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1022 lenv.return_type = self.return_type
1023 type = self.entry.type
1024 if type.is_cfunction:
1025 lenv.nogil = type.nogil and not type.with_gil
1026 self.local_scope = lenv
1027 lenv.directives = env.directives
1030 def generate_function_definitions(self, env, code):
1033 lenv = self.local_scope
1035 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1036 self.entry.scope.is_c_class_scope)
1038 # Generate C code for header and body of function
1039 code.enter_cfunc_scope()
1040 code.return_from_error_cleanup_label = code.new_label()
1042 # ----- Top-level constants used by this function
1043 code.mark_pos(self.pos)
1044 self.generate_interned_num_decls(lenv, code)
1045 self.generate_interned_string_decls(lenv, code)
1046 self.generate_py_string_decls(lenv, code)
1047 self.generate_cached_builtins_decls(lenv, code)
1049 #code.put_var_declarations(lenv.const_entries, static = 1)
1050 self.generate_const_definitions(lenv, code)
1051 # ----- Function header
1054 self.py_func.generate_function_header(code,
1055 with_pymethdef = env.is_py_class_scope,
1057 self.generate_function_header(code,
1058 with_pymethdef = env.is_py_class_scope)
1059 # ----- Local variable declarations
1060 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1061 self.generate_argument_declarations(lenv, code)
1062 if self.needs_closure:
1063 code.putln("/* TODO: declare and create scope object */")
1064 code.put_var_declarations(lenv.var_entries)
1066 if not self.return_type.is_void:
1067 if self.return_type.is_pyobject:
1071 (self.return_type.declaration_code(
1072 Naming.retval_cname),
1074 tempvardecl_code = code.insertion_point()
1075 self.generate_keyword_list(code)
1076 # ----- Extern library function declarations
1077 lenv.generate_library_function_declarations(code)
1078 # ----- GIL acquisition
1079 acquire_gil = self.need_gil_acquisition(lenv)
1081 env.use_utility_code(force_init_threads_utility_code)
1082 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1083 # ----- Automatic lead-ins for certain special functions
1085 code.put_setup_refcount_context(self.entry.name)
1086 if is_getbuffer_slot:
1087 self.getbuffer_init(code)
1088 # ----- Fetch arguments
1089 self.generate_argument_parsing_code(env, code)
1090 # If an argument is assigned to in the body, we must
1091 # incref it to properly keep track of refcounts.
1092 for entry in lenv.arg_entries:
1093 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1094 code.put_var_incref(entry)
1095 # ----- Initialise local variables
1096 for entry in lenv.var_entries:
1097 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1098 code.put_init_var_to_py_none(entry)
1099 # ----- Initialise local buffer auxiliary variables
1100 for entry in lenv.var_entries + lenv.arg_entries:
1101 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1102 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1103 # ----- Check and convert arguments
1104 self.generate_argument_type_tests(code)
1105 # ----- Acquire buffer arguments
1106 for entry in lenv.arg_entries:
1107 if entry.type.is_buffer:
1108 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1109 # ----- Function body
1110 self.body.generate_execution_code(code)
1111 # ----- Default return value
1113 if self.return_type.is_pyobject:
1114 #if self.return_type.is_extension_type:
1115 # lhs = "(PyObject *)%s" % Naming.retval_cname
1117 lhs = Naming.retval_cname
1118 code.put_init_to_py_none(lhs, self.return_type)
1120 val = self.return_type.default_value
1122 code.putln("%s = %s;" % (Naming.retval_cname, val))
1123 # ----- Error cleanup
1124 if code.error_label in code.labels_used:
1125 code.put_goto(code.return_label)
1126 code.put_label(code.error_label)
1127 # cleanup temps the old way
1128 code.put_var_xdecrefs(lenv.temp_entries)
1129 # cleanup temps the new way
1130 for cname, type in code.funcstate.all_managed_temps():
1131 code.put_xdecref(cname, type)
1133 # Clean up buffers -- this calls a Python function
1134 # so need to save and restore error state
1135 buffers_present = len(lenv.buffer_entries) > 0
1137 code.globalstate.use_utility_code(restore_exception_utility_code)
1138 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1139 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1140 for entry in lenv.buffer_entries:
1141 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1142 #code.putln("%s = 0;" % entry.cname)
1143 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1145 err_val = self.error_value()
1146 exc_check = self.caller_will_check_exceptions()
1147 if err_val is not None or exc_check:
1148 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1150 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1151 % self.entry.qualified_name, 0)
1153 '__Pyx_WriteUnraisable("%s");' %
1154 self.entry.qualified_name)
1155 env.use_utility_code(unraisable_exception_utility_code)
1156 env.use_utility_code(restore_exception_utility_code)
1157 default_retval = self.return_type.default_value
1158 if err_val is None and default_retval:
1159 err_val = default_retval
1160 if err_val is not None:
1163 Naming.retval_cname,
1166 if is_getbuffer_slot:
1167 self.getbuffer_error_cleanup(code)
1169 # If we are using the non-error cleanup section we should
1170 # jump past it if we have an error. The if-test below determine
1171 # whether this section is used.
1172 if buffers_present or is_getbuffer_slot:
1173 code.put_goto(code.return_from_error_cleanup_label)
1176 # ----- Non-error return cleanup
1177 # If you add anything here, remember to add a condition to the
1178 # if-test above in the error block (so that it can jump past this
1180 code.put_label(code.return_label)
1181 for entry in lenv.buffer_entries:
1183 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1184 if is_getbuffer_slot:
1185 self.getbuffer_normal_cleanup(code)
1186 # ----- Return cleanup for both error and no-error return
1187 code.put_label(code.return_from_error_cleanup_label)
1188 if not Options.init_local_none:
1189 for entry in lenv.var_entries:
1190 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1191 entry.xdecref_cleanup = 1
1192 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1193 # Decref any increfed args
1194 for entry in lenv.arg_entries:
1195 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1196 code.put_var_decref(entry)
1198 # code.putln("/* TODO: decref scope object */")
1200 # This code is duplicated in ModuleNode.generate_module_init_func
1202 default_retval = self.return_type.default_value
1203 err_val = self.error_value()
1204 if err_val is None and default_retval:
1205 err_val = default_retval
1206 if self.return_type.is_pyobject:
1207 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1209 code.put_finish_refcount_context()
1212 code.putln("PyGILState_Release(_save);")
1214 if not self.return_type.is_void:
1215 code.putln("return %s;" % Naming.retval_cname)
1218 # ----- Go back and insert temp variable declarations
1219 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1220 tempvardecl_code.put_temp_declarations(code.funcstate)
1221 # ----- Python version
1222 code.exit_cfunc_scope()
1224 self.py_func.generate_function_definitions(env, code)
1225 self.generate_wrapper_functions(code)
1227 def declare_argument(self, env, arg):
1228 if arg.type.is_void:
1229 error(arg.pos, "Invalid use of 'void'")
1230 elif not arg.type.is_complete() and not arg.type.is_array:
1232 "Argument type '%s' is incomplete" % arg.type)
1233 return env.declare_arg(arg.name, arg.type, arg.pos)
1235 def generate_wrapper_functions(self, code):
1238 def generate_execution_code(self, code):
1239 # Evaluate and store argument default values
1240 for arg in self.args:
1241 default = arg.default
1243 if not default.is_literal:
1244 default.generate_evaluation_code(code)
1245 default.make_owned_reference(code)
1248 arg.default_entry.cname,
1249 default.result_as(arg.default_entry.type)))
1250 if default.is_temp and default.type.is_pyobject:
1251 code.putln("%s = 0;" % default.result())
1252 default.free_temps(code)
1253 code.put_var_giveref(arg.default_entry)
1254 # For Python class methods, create and store function object
1256 self.assmt.generate_execution_code(code)
1259 # Special code for the __getbuffer__ function
1261 def getbuffer_init(self, code):
1262 info = self.local_scope.arg_entries[1].cname
1263 # Python 3.0 betas have a bug in memoryview which makes it call
1264 # getbuffer with a NULL parameter. For now we work around this;
1265 # the following line should be removed when this bug is fixed.
1266 code.putln("if (%s == NULL) return 0;" % info)
1267 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1268 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1270 def getbuffer_error_cleanup(self, code):
1271 info = self.local_scope.arg_entries[1].cname
1272 code.put_gotref("%s->obj" % info)
1273 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1276 def getbuffer_normal_cleanup(self, code):
1277 info = self.local_scope.arg_entries[1].cname
1278 code.putln("if (%s->obj == Py_None) {" % info)
1279 code.put_gotref("Py_None")
1280 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1283 class CFuncDefNode(FuncDefNode):
1284 # C function definition.
1286 # modifiers ['inline']
1287 # visibility 'private' or 'public' or 'extern'
1288 # base_type CBaseTypeNode
1289 # declarator CDeclaratorNode
1292 # decorators [DecoratorNode] list of decorators
1294 # with_gil boolean Acquire GIL around body
1296 # py_func wrapper for calling from Python
1297 # overridable whether or not this is a cpdef function
1298 # inline_in_pxd whether this is an inline function in a pxd file
1300 child_attrs = ["base_type", "declarator", "body", "py_func"]
1302 inline_in_pxd = False
1304 directive_locals = {}
1306 def unqualified_name(self):
1307 return self.entry.name
1309 def analyse_declarations(self, env):
1310 directive_locals = self.directive_locals = env.directives['locals']
1311 base_type = self.base_type.analyse(env)
1312 # The 2 here is because we need both function and argument names.
1313 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1314 if not type.is_cfunction:
1316 "Suite attached to non-function declaration")
1317 # Remember the actual type according to the function header
1318 # written here, because the type in the symbol table entry
1319 # may be different if we're overriding a C method inherited
1320 # from the base type of an extension type.
1322 type.is_overridable = self.overridable
1323 declarator = self.declarator
1324 while not hasattr(declarator, 'args'):
1325 declarator = declarator.base
1326 self.args = declarator.args
1327 for formal_arg, type_arg in zip(self.args, type.args):
1328 formal_arg.type = type_arg.type
1329 formal_arg.name = type_arg.name
1330 formal_arg.cname = type_arg.cname
1331 name = name_declarator.name
1332 cname = name_declarator.cname
1333 self.entry = env.declare_cfunction(
1334 name, type, self.pos,
1335 cname = cname, visibility = self.visibility,
1336 defining = self.body is not None,
1337 api = self.api, modifiers = self.modifiers)
1338 self.entry.inline_func_in_pxd = self.inline_in_pxd
1339 self.return_type = type.return_type
1341 if self.overridable and not env.is_module_scope:
1342 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1343 # An error will be produced in the cdef function
1344 self.overridable = False
1346 if self.overridable:
1348 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1349 self.py_func = DefNode(pos = self.pos,
1350 name = self.entry.name,
1353 starstar_arg = None,
1355 body = py_func_body,
1357 self.py_func.is_module_scope = env.is_module_scope
1358 self.py_func.analyse_declarations(env)
1359 self.entry.as_variable = self.py_func.entry
1360 # Reset scope entry the above cfunction
1361 env.entries[name] = self.entry
1362 self.py_func.interned_attr_cname = env.intern_identifier(
1363 self.py_func.entry.name)
1364 if not env.is_module_scope or Options.lookup_module_cpdef:
1365 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1366 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1368 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1370 args = self.type.args
1371 if omit_optional_args:
1372 args = args[:len(args) - self.type.optional_arg_count]
1373 arg_names = [arg.name for arg in args]
1375 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1377 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1378 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1379 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1380 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)
1381 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1383 def declare_arguments(self, env):
1384 for arg in self.type.args:
1386 error(arg.pos, "Missing argument name")
1387 self.declare_argument(env, arg)
1389 def need_gil_acquisition(self, lenv):
1391 with_gil = self.type.with_gil
1392 if type.nogil and not with_gil:
1393 if type.return_type.is_pyobject:
1395 "Function with Python return type cannot be declared nogil")
1396 for entry in lenv.var_entries + lenv.temp_entries:
1397 if entry.type.is_pyobject:
1398 error(self.pos, "Function declared nogil has Python locals or temporaries")
1401 def analyse_expressions(self, env):
1402 self.local_scope.directives = env.directives
1403 self.analyse_default_values(env)
1404 if self.py_func is not None:
1405 self.py_func.analyse_expressions(env)
1407 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1410 visibility = self.entry.visibility
1411 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1412 arg_decls.append(arg.declaration_code())
1413 if with_dispatch and self.overridable:
1414 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1415 if type.optional_arg_count and with_opt_args:
1416 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1417 if type.has_varargs:
1418 arg_decls.append("...")
1420 arg_decls = ["void"]
1422 cname = self.entry.func_cname
1423 entity = type.function_header_code(cname, ', '.join(arg_decls))
1424 if visibility == 'public':
1425 dll_linkage = "DL_EXPORT"
1428 header = self.return_type.declaration_code(entity,
1429 dll_linkage = dll_linkage)
1430 if visibility == 'extern':
1431 storage_class = "%s " % Naming.extern_c_macro
1432 elif visibility == 'public':
1435 storage_class = "static "
1436 code.putln("%s%s %s {" % (
1438 ' '.join(self.modifiers).upper(), # macro forms
1441 def generate_argument_declarations(self, env, code):
1442 for arg in self.args:
1444 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1446 def generate_keyword_list(self, code):
1449 def generate_argument_parsing_code(self, env, code):
1451 if self.type.optional_arg_count:
1452 code.putln('if (%s) {' % Naming.optional_args_cname)
1453 for arg in self.args:
1455 # FIXME: simple name prefixing doesn't work when
1456 # argument name mangling is in place
1457 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1458 declarator = arg.declarator
1459 while not hasattr(declarator, 'name'):
1460 declarator = declarator.base
1461 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1463 for _ in range(self.type.optional_arg_count):
1467 def generate_argument_conversion_code(self, code):
1470 def generate_argument_type_tests(self, code):
1471 # Generate type tests for args whose type in a parent
1472 # class is a supertype of the declared type.
1473 for arg in self.type.args:
1474 if arg.needs_type_test:
1475 self.generate_arg_type_test(arg, code)
1477 def generate_arg_type_test(self, arg, code):
1478 # Generate type test for one argument.
1479 if arg.type.typeobj_is_available():
1480 typeptr_cname = arg.type.typeptr_cname
1481 arg_code = "((PyObject *)%s)" % arg.cname
1483 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1488 type.is_builtin_type,
1489 code.error_goto(arg.pos)))
1491 error(arg.pos, "Cannot test type of extern C class "
1492 "without type object name specification")
1494 def error_value(self):
1495 if self.return_type.is_pyobject:
1499 return self.entry.type.exception_value
1501 def caller_will_check_exceptions(self):
1502 return self.entry.type.exception_check
1504 def generate_wrapper_functions(self, code):
1505 # If the C signature of a function has changed, we need to generate
1506 # wrappers to put in the slots here.
1509 func_type = entry.type
1510 while entry.prev_entry is not None:
1512 entry = entry.prev_entry
1513 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1515 self.generate_function_header(code,
1517 with_dispatch = entry.type.is_overridable,
1518 with_opt_args = entry.type.optional_arg_count,
1519 cname = entry.func_cname)
1520 if not self.return_type.is_void:
1522 args = self.type.args
1523 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1524 if entry.type.is_overridable:
1525 arglist.append(Naming.skip_dispatch_cname)
1526 elif func_type.is_overridable:
1528 if entry.type.optional_arg_count:
1529 arglist.append(Naming.optional_args_cname)
1530 elif func_type.optional_arg_count:
1531 arglist.append('NULL')
1532 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1536 class PyArgDeclNode(Node):
1537 # Argument which must be a Python object (used
1538 # for * and ** arguments).
1541 # entry Symtab.Entry
1545 class DecoratorNode(Node):
1548 # decorator NameNode or CallNode
1549 child_attrs = ['decorator']
1552 class DefNode(FuncDefNode):
1553 # A Python function definition.
1555 # name string the Python name of the function
1556 # decorators [DecoratorNode] list of decorators
1557 # args [CArgDeclNode] formal arguments
1558 # star_arg PyArgDeclNode or None * argument
1559 # starstar_arg PyArgDeclNode or None ** argument
1560 # doc EncodedString or None
1563 # The following subnode is constructed internally
1564 # when the def statement is inside a Python class definition.
1566 # assmt AssignmentNode Function construction/assignment
1568 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1572 num_required_kw_args = 0
1573 reqd_kw_flags_cname = "0"
1579 def __init__(self, pos, **kwds):
1580 FuncDefNode.__init__(self, pos, **kwds)
1582 for arg in self.args:
1589 self.num_kwonly_args = k
1590 self.num_required_kw_args = rk
1591 self.num_required_args = r
1593 def as_cfunction(self, cfunc=None, scope=None):
1595 error(self.star_arg.pos, "cdef function cannot have star argument")
1596 if self.starstar_arg:
1597 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1600 for formal_arg in self.args:
1601 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1602 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1604 type = py_object_type,
1605 pos = formal_arg.pos))
1606 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1608 has_varargs = False,
1609 exception_value = None,
1610 exception_check = False,
1613 is_overridable = True)
1614 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1616 cfunc_type = cfunc.type
1617 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1618 error(self.pos, "wrong number of arguments")
1619 error(declarator.pos, "previous declaration here")
1620 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1621 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1622 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1623 formal_arg.type = type_arg.type
1624 formal_arg.name_declarator = name_declarator
1626 if cfunc_type.exception_value is None:
1627 exception_value = None
1629 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1630 declarator = CFuncDeclaratorNode(self.pos,
1631 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1633 has_varargs = False,
1634 exception_check = cfunc_type.exception_check,
1635 exception_value = exception_value,
1636 with_gil = cfunc_type.with_gil,
1637 nogil = cfunc_type.nogil)
1638 return CFuncDefNode(self.pos,
1640 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1641 declarator = declarator,
1644 overridable = cfunc_type.is_overridable,
1646 with_gil = cfunc_type.with_gil,
1647 nogil = cfunc_type.nogil,
1648 visibility = 'private',
1650 directive_locals = getattr(cfunc, 'directive_locals', {}))
1652 def analyse_declarations(self, env):
1653 directive_locals = self.directive_locals = env.directives['locals']
1654 for arg in self.args:
1655 if hasattr(arg, 'name'):
1657 name_declarator = None
1659 base_type = arg.base_type.analyse(env)
1660 name_declarator, type = \
1661 arg.declarator.analyse(base_type, env)
1662 arg.name = name_declarator.name
1663 if arg.name in directive_locals:
1664 type_node = directive_locals[arg.name]
1665 other_type = type_node.analyse_as_type(env)
1666 if other_type is None:
1667 error(type_node.pos, "Not a type")
1668 elif (type is not PyrexTypes.py_object_type
1669 and not type.same_as(other_type)):
1670 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1671 error(type_node.pos, "Previous declaration here")
1674 if name_declarator and name_declarator.cname:
1676 "Python function argument cannot have C name specification")
1677 arg.type = type.as_argument_type()
1679 arg.needs_conversion = 0
1680 arg.needs_type_test = 0
1682 if arg.not_none and not arg.type.is_extension_type:
1684 "Only extension type arguments can have 'not None'")
1685 self.declare_pyfunction(env)
1686 self.analyse_signature(env)
1687 self.return_type = self.entry.signature.return_type()
1689 def analyse_signature(self, env):
1690 any_type_tests_needed = 0
1691 # Use the simpler calling signature for zero- and one-argument functions.
1692 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1693 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1694 if len(self.args) == 0:
1695 self.entry.signature = TypeSlots.pyfunction_noargs
1696 elif len(self.args) == 1:
1697 if self.args[0].default is None and not self.args[0].kw_only:
1698 self.entry.signature = TypeSlots.pyfunction_onearg
1699 elif self.entry.signature is TypeSlots.pymethod_signature:
1700 if len(self.args) == 1:
1701 self.entry.signature = TypeSlots.unaryfunc
1702 elif len(self.args) == 2:
1703 if self.args[1].default is None and not self.args[1].kw_only:
1704 self.entry.signature = TypeSlots.ibinaryfunc
1705 elif self.entry.is_special:
1706 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1707 sig = self.entry.signature
1708 nfixed = sig.num_fixed_args()
1709 for i in range(nfixed):
1710 if i < len(self.args):
1713 if sig.is_self_arg(i):
1715 arg.hdr_type = arg.type = env.parent_type
1716 arg.needs_conversion = 0
1718 arg.hdr_type = sig.fixed_arg_type(i)
1719 if not arg.type.same_as(arg.hdr_type):
1720 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1721 arg.needs_type_test = 1
1722 any_type_tests_needed = 1
1724 arg.needs_conversion = 1
1725 if arg.needs_conversion:
1726 arg.hdr_cname = Naming.arg_prefix + arg.name
1728 arg.hdr_cname = Naming.var_prefix + arg.name
1730 self.bad_signature()
1732 if nfixed < len(self.args):
1733 if not sig.has_generic_args:
1734 self.bad_signature()
1735 for arg in self.args:
1736 if arg.is_generic and \
1737 (arg.type.is_extension_type or arg.type.is_builtin_type):
1738 arg.needs_type_test = 1
1739 any_type_tests_needed = 1
1740 if any_type_tests_needed:
1741 env.use_utility_code(arg_type_test_utility_code)
1743 def bad_signature(self):
1744 sig = self.entry.signature
1745 expected_str = "%d" % sig.num_fixed_args()
1746 if sig.has_generic_args:
1747 expected_str = expected_str + " or more"
1749 if name.startswith("__") and name.endswith("__"):
1750 desc = "Special method"
1754 "%s %s has wrong number of arguments "
1755 "(%d declared, %s expected)" % (
1756 desc, self.name, len(self.args), expected_str))
1758 def signature_has_nongeneric_args(self):
1759 argcount = len(self.args)
1760 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1764 def signature_has_generic_args(self):
1765 return self.entry.signature.has_generic_args
1767 def declare_pyfunction(self, env):
1768 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1770 entry = env.lookup_here(self.name)
1771 if entry and entry.type.is_cfunction and not self.is_wrapper:
1772 warning(self.pos, "Overriding cdef method with def method.", 5)
1773 entry = env.declare_pyfunction(self.name, self.pos)
1775 prefix = env.scope_prefix
1776 entry.func_cname = \
1777 Naming.pyfunc_prefix + prefix + name
1778 entry.pymethdef_cname = \
1779 Naming.pymethdef_prefix + prefix + name
1780 if Options.docstrings:
1781 entry.doc = embed_position(self.pos, self.doc)
1783 Naming.funcdoc_prefix + prefix + name
1787 def declare_arguments(self, env):
1788 for arg in self.args:
1790 error(arg.pos, "Missing argument name")
1791 if arg.needs_conversion:
1792 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1793 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1794 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1795 if arg.type.is_pyobject:
1796 arg.entry.init = "0"
1797 arg.entry.init_to_none = 0
1799 arg.entry = self.declare_argument(env, arg)
1801 arg.entry.is_self_arg = arg.is_self_arg
1802 if not arg.is_self_arg:
1803 arg.name_entry = env.get_string_const(
1804 arg.name, identifier = True)
1805 env.add_py_string(arg.name_entry, identifier = True)
1807 if arg.is_self_arg or \
1808 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1809 arg.entry.is_declared_generic = 1
1810 self.declare_python_arg(env, self.star_arg)
1811 self.declare_python_arg(env, self.starstar_arg)
1813 def declare_python_arg(self, env, arg):
1815 entry = env.declare_var(arg.name,
1816 PyrexTypes.py_object_type, arg.pos)
1819 entry.init_to_none = 0
1820 entry.xdecref_cleanup = 1
1822 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1824 def analyse_expressions(self, env):
1825 self.local_scope.directives = env.directives
1826 self.analyse_default_values(env)
1827 if env.is_py_class_scope:
1828 self.synthesize_assignment_node(env)
1830 def synthesize_assignment_node(self, env):
1832 self.assmt = SingleAssignmentNode(self.pos,
1833 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1834 rhs = ExprNodes.UnboundMethodNode(self.pos,
1835 class_cname = env.class_obj_cname,
1836 function = ExprNodes.PyCFunctionNode(self.pos,
1837 pymethdef_cname = self.entry.pymethdef_cname)))
1838 self.assmt.analyse_declarations(env)
1839 self.assmt.analyse_expressions(env)
1841 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1843 sig = self.entry.signature
1844 if sig.has_dummy_arg:
1845 arg_code_list.append(
1846 "PyObject *%s" % Naming.self_cname)
1847 for arg in self.args:
1848 if not arg.is_generic:
1850 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1852 arg_code_list.append(
1853 arg.hdr_type.declaration_code(arg.hdr_cname))
1854 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1855 arg_code_list.append("PyObject *unused")
1856 if sig.has_generic_args:
1857 arg_code_list.append(
1858 "PyObject *%s, PyObject *%s"
1859 % (Naming.args_cname, Naming.kwds_cname))
1860 arg_code = ", ".join(arg_code_list)
1861 dc = self.return_type.declaration_code(self.entry.func_cname)
1862 header = "static %s(%s)" % (dc, arg_code)
1863 code.putln("%s; /*proto*/" % header)
1866 if self.entry.doc and Options.docstrings:
1867 docstr = self.entry.doc
1868 if not isinstance(docstr, str):
1869 docstr = docstr.utf8encode()
1871 'static char %s[] = "%s";' % (
1872 self.entry.doc_cname,
1873 split_docstring(escape_byte_string(docstr))))
1876 "static PyMethodDef %s = " %
1877 self.entry.pymethdef_cname)
1878 code.put_pymethoddef(self.entry, ";")
1879 code.putln("%s {" % header)
1881 def generate_argument_declarations(self, env, code):
1882 for arg in self.args:
1883 if arg.is_generic: # or arg.needs_conversion:
1884 if arg.needs_conversion:
1885 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1887 code.put_var_declaration(arg.entry)
1889 def generate_keyword_list(self, code):
1890 if self.signature_has_generic_args() and \
1891 self.signature_has_nongeneric_args():
1893 "static PyObject **%s[] = {" %
1894 Naming.pykwdlist_cname)
1895 for arg in self.args:
1897 code.put('&%s,' % arg.name_entry.pystring_cname)
1900 def generate_argument_parsing_code(self, env, code):
1901 # Generate PyArg_ParseTuple call for generic
1902 # arguments, if any.
1903 if self.entry.signature.has_dummy_arg:
1904 # get rid of unused argument warning
1905 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1907 old_error_label = code.new_error_label()
1908 our_error_label = code.error_label
1909 end_label = code.new_label("argument_unpacking_done")
1911 has_kwonly_args = self.num_kwonly_args > 0
1912 has_star_or_kw_args = self.star_arg is not None \
1913 or self.starstar_arg is not None or has_kwonly_args
1915 if not self.signature_has_generic_args():
1916 if has_star_or_kw_args:
1917 error(self.pos, "This method cannot have * or keyword arguments")
1918 self.generate_argument_conversion_code(code)
1920 elif not self.signature_has_nongeneric_args():
1921 # func(*args) or func(**kw) or func(*args, **kw)
1922 self.generate_stararg_copy_code(code)
1925 positional_args = []
1928 for arg in self.args:
1929 arg_entry = arg.entry
1933 if not arg.is_self_arg:
1935 kw_only_args.append(arg)
1937 positional_args.append(arg)
1939 kw_only_args.append(arg)
1942 error(arg.pos, "Non-default argument following default argument")
1943 elif not arg.is_self_arg:
1944 positional_args.append(arg)
1946 self.generate_tuple_and_keyword_parsing_code(
1947 positional_args, kw_only_args, end_label, code)
1949 code.error_label = old_error_label
1950 if code.label_used(our_error_label):
1951 if not code.label_used(end_label):
1952 code.put_goto(end_label)
1953 code.put_label(our_error_label)
1954 if has_star_or_kw_args:
1955 self.generate_arg_decref(self.star_arg, code)
1956 if self.starstar_arg:
1957 if self.starstar_arg.entry.xdecref_cleanup:
1958 code.put_var_xdecref(self.starstar_arg.entry)
1960 code.put_var_decref(self.starstar_arg.entry)
1961 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1962 code.putln("return %s;" % self.error_value())
1963 if code.label_used(end_label):
1964 code.put_label(end_label)
1966 def generate_arg_assignment(self, arg, item, code):
1967 if arg.type.is_pyobject:
1969 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1970 code.putln("%s = %s;" % (arg.entry.cname, item))
1972 func = arg.type.from_py_function
1974 code.putln("%s = %s(%s); %s" % (
1978 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1980 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1982 def generate_arg_xdecref(self, arg, code):
1984 code.put_var_xdecref(arg.entry)
1986 def generate_arg_decref(self, arg, code):
1988 code.put_var_decref(arg.entry)
1990 def generate_stararg_copy_code(self, code):
1991 if not self.star_arg:
1992 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1993 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1995 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1996 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1999 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2001 if self.starstar_arg:
2003 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2005 kwarg_check = "%s" % Naming.kwds_cname
2007 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2008 Naming.kwds_cname, Naming.kwds_cname)
2010 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2011 kwarg_check, Naming.kwds_cname, self.name,
2012 bool(self.starstar_arg), self.error_value()))
2014 if self.starstar_arg:
2015 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2016 self.starstar_arg.entry.cname,
2019 code.putln("if (unlikely(!%s)) return %s;" % (
2020 self.starstar_arg.entry.cname, self.error_value()))
2021 self.starstar_arg.entry.xdecref_cleanup = 0
2022 code.put_gotref(self.starstar_arg.entry.cname)
2026 code.put_incref(Naming.args_cname, py_object_type)
2027 code.putln("%s = %s;" % (
2028 self.star_arg.entry.cname,
2030 self.star_arg.entry.xdecref_cleanup = 0
2032 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2033 kw_only_args, success_label, code):
2034 argtuple_error_label = code.new_label("argtuple_error")
2036 min_positional_args = self.num_required_args - self.num_required_kw_args
2037 if len(self.args) > 0 and self.args[0].is_self_arg:
2038 min_positional_args -= 1
2039 max_positional_args = len(positional_args)
2040 has_fixed_positional_count = not self.star_arg and \
2041 min_positional_args == max_positional_args
2043 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2044 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2045 if self.num_required_kw_args:
2046 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2048 if self.starstar_arg or self.star_arg:
2049 self.generate_stararg_init_code(max_positional_args, code)
2051 # --- optimised code when we receive keyword arguments
2052 if self.num_required_kw_args:
2053 likely_hint = "likely"
2055 likely_hint = "unlikely"
2056 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2057 self.generate_keyword_unpacking_code(
2058 min_positional_args, max_positional_args,
2059 has_fixed_positional_count,
2060 positional_args, kw_only_args, argtuple_error_label, code)
2062 # --- optimised code when we do not receive any keyword arguments
2063 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2064 # Python raises arg tuple related errors first, so we must
2065 # check the length here
2066 if min_positional_args == max_positional_args and not self.star_arg:
2070 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2071 Naming.args_cname, compare, min_positional_args))
2072 code.put_goto(argtuple_error_label)
2074 if self.num_required_kw_args:
2075 # pure error case: keywords required but not passed
2076 if max_positional_args > min_positional_args and not self.star_arg:
2077 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2078 Naming.args_cname, max_positional_args))
2079 code.put_goto(argtuple_error_label)
2080 code.putln('} else {')
2081 for i, arg in enumerate(kw_only_args):
2083 # required keyword-only argument missing
2084 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2085 self.name.utf8encode(),
2086 arg.name_entry.pystring_cname))
2087 code.putln(code.error_goto(self.pos))
2090 elif min_positional_args == max_positional_args:
2091 # parse the exact number of positional arguments from the
2093 code.putln('} else {')
2094 for i, arg in enumerate(positional_args):
2095 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2096 self.generate_arg_assignment(arg, item, code)
2097 self.generate_arg_default_assignments(code)
2100 # parse the positional arguments from the variable length
2102 code.putln('} else {')
2103 self.generate_arg_default_assignments(code)
2104 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2106 code.putln('default:')
2107 reversed_args = list(enumerate(positional_args))[::-1]
2108 for i, arg in reversed_args:
2109 if i >= min_positional_args-1:
2110 if min_positional_args > 1:
2111 code.putln('case %2d:' % (i+1)) # pure code beautification
2113 code.put('case %2d: ' % (i+1))
2114 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2115 self.generate_arg_assignment(arg, item, code)
2116 if min_positional_args == 0:
2117 code.put('case 0: ')
2118 code.putln('break;')
2120 if min_positional_args:
2121 for i in range(min_positional_args-1, -1, -1):
2122 code.putln('case %2d:' % i)
2123 code.put_goto(argtuple_error_label)
2125 code.put('default: ')
2126 code.put_goto(argtuple_error_label)
2131 if code.label_used(argtuple_error_label):
2132 code.put_goto(success_label)
2133 code.put_label(argtuple_error_label)
2134 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2135 self.name.utf8encode(), has_fixed_positional_count,
2136 min_positional_args, max_positional_args,
2138 code.putln(code.error_goto(self.pos))
2140 def generate_arg_default_assignments(self, code):
2141 for arg in self.args:
2142 if arg.is_generic and arg.default:
2146 arg.default_result_code))
2148 def generate_stararg_init_code(self, max_positional_args, code):
2149 if self.starstar_arg:
2150 self.starstar_arg.entry.xdecref_cleanup = 0
2151 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2152 self.starstar_arg.entry.cname,
2153 self.starstar_arg.entry.cname,
2154 self.error_value()))
2155 code.put_gotref(self.starstar_arg.entry.cname)
2157 self.star_arg.entry.xdecref_cleanup = 0
2158 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2160 max_positional_args))
2161 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2162 self.star_arg.entry.cname, Naming.args_cname,
2163 max_positional_args, Naming.args_cname))
2164 code.put_gotref(self.star_arg.entry.cname)
2165 if self.starstar_arg:
2167 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2168 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2169 code.putln('return %s;' % self.error_value())
2172 code.putln("if (unlikely(!%s)) return %s;" % (
2173 self.star_arg.entry.cname, self.error_value()))
2174 code.putln('} else {')
2175 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2176 code.put_incref(Naming.empty_tuple, py_object_type)
2179 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2180 has_fixed_positional_count, positional_args,
2181 kw_only_args, argtuple_error_label, code):
2182 all_args = tuple(positional_args) + tuple(kw_only_args)
2183 max_args = len(all_args)
2186 for i, arg in enumerate(all_args):
2187 if arg.default and arg.type.is_pyobject:
2188 default_value = arg.default_result_code
2189 if arg.type is not PyrexTypes.py_object_type:
2190 default_value = "(PyObject*)"+default_value
2191 default_args.append((i, default_value))
2193 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2195 # it looks funny to separate the init-to-0 from setting the
2196 # default value, but C89 needs this
2197 code.putln("PyObject* values[%d] = {%s};" % (
2198 max_args, ','.join(['0']*max_args)))
2199 for i, default_value in default_args:
2200 code.putln('values[%d] = %s;' % (i, default_value))
2202 # parse the tuple and check that it's not too long
2203 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2205 code.putln('default:')
2206 for i in range(max_positional_args-1, -1, -1):
2207 code.put('case %2d: ' % (i+1))
2208 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2209 i, Naming.args_cname, i))
2210 code.putln('case 0: break;')
2211 if not self.star_arg:
2212 code.put('default: ') # more arguments than allowed
2213 code.put_goto(argtuple_error_label)
2216 # now fill up the positional/required arguments with values
2218 if self.num_required_args or max_positional_args > 0:
2219 last_required_arg = -1
2220 for i, arg in enumerate(all_args):
2222 last_required_arg = i
2223 if last_required_arg < max_positional_args:
2224 last_required_arg = max_positional_args-1
2225 num_required_args = self.num_required_args
2226 if max_positional_args > 0:
2227 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2228 for i, arg in enumerate(all_args[:last_required_arg+1]):
2229 if max_positional_args > 0 and i <= max_positional_args:
2230 if self.star_arg and i == max_positional_args:
2231 code.putln('default:')
2233 code.putln('case %2d:' % i)
2236 # handled separately below
2238 code.putln('if (kw_args > %d) {' % num_required_args)
2239 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2240 Naming.kwds_cname, arg.name_entry.pystring_cname))
2241 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2244 num_required_args -= 1
2245 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2246 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2247 code.putln('if (likely(values[%d])) kw_args--;' % i);
2248 if i < min_positional_args:
2250 # special case: we know arg 0 is missing
2252 code.put_goto(argtuple_error_label)
2254 # print the correct number of values (args or
2255 # kwargs) that were passed into positional
2256 # arguments up to this point
2257 code.putln('else {')
2258 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2259 self.name.utf8encode(), has_fixed_positional_count,
2260 min_positional_args, max_positional_args, i))
2261 code.putln(code.error_goto(self.pos))
2264 code.putln('else {')
2265 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2266 self.name.utf8encode(), arg.name_entry.pystring_cname))
2267 code.putln(code.error_goto(self.pos))
2269 if max_positional_args > 0:
2272 if kw_only_args and not self.starstar_arg:
2273 # unpack optional keyword-only arguments
2274 # checking for interned strings in a dict is faster than iterating
2275 # but it's too likely that we must iterate if we expect **kwargs
2277 for i, arg in enumerate(all_args[max_positional_args:]):
2278 if not arg.kw_only or not arg.default:
2280 optional_args.append((i+max_positional_args, arg))
2282 # this mimics an unrolled loop so that we can "break" out of it
2283 code.putln('while (kw_args > 0) {')
2284 code.putln('PyObject* value;')
2285 for i, arg in optional_args:
2287 'value = PyDict_GetItem(%s, %s);' % (
2288 Naming.kwds_cname, arg.name_entry.pystring_cname))
2290 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2291 code.putln('break;')
2294 code.putln('if (unlikely(kw_args > 0)) {')
2295 # non-positional/-required kw args left in dict: default args,
2296 # kw-only args, **kwargs or error
2298 # This is sort of a catch-all: except for checking required
2299 # arguments, this will always do the right thing for unpacking
2300 # keyword arguments, so that we can concentrate on optimising
2301 # common cases above.
2302 if max_positional_args == 0:
2305 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2306 Naming.args_cname, max_positional_args,
2307 Naming.args_cname, max_positional_args))
2308 pos_arg_count = "used_pos_args"
2310 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2311 code.globalstate.use_utility_code(parse_keywords_utility_code)
2313 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2315 Naming.pykwdlist_cname,
2316 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2318 self.name.utf8encode()))
2319 code.putln(code.error_goto(self.pos))
2322 # convert arg values to their final type and assign them
2323 for i, arg in enumerate(all_args):
2324 if arg.default and not arg.type.is_pyobject:
2325 code.putln("if (values[%d]) {" % i)
2326 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2327 if arg.default and not arg.type.is_pyobject:
2328 code.putln('} else {')
2332 arg.default_result_code))
2335 def generate_argument_conversion_code(self, code):
2336 # Generate code to convert arguments from
2337 # signature type to declared type, if needed.
2338 for arg in self.args:
2339 if arg.needs_conversion:
2340 self.generate_arg_conversion(arg, code)
2342 def generate_arg_conversion(self, arg, code):
2343 # Generate conversion code for one argument.
2344 old_type = arg.hdr_type
2346 if old_type.is_pyobject:
2348 code.putln("if (%s) {" % arg.hdr_cname)
2350 code.putln("assert(%s); {" % arg.hdr_cname)
2351 self.generate_arg_conversion_from_pyobject(arg, code)
2353 elif new_type.is_pyobject:
2354 self.generate_arg_conversion_to_pyobject(arg, code)
2356 if new_type.assignable_from(old_type):
2358 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2361 "Cannot convert 1 argument from '%s' to '%s'" %
2362 (old_type, new_type))
2364 def generate_arg_conversion_from_pyobject(self, arg, code):
2366 func = new_type.from_py_function
2367 # copied from CoerceFromPyTypeNode
2369 code.putln("%s = %s(%s); %s" % (
2373 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2376 "Cannot convert Python object argument to type '%s'"
2379 def generate_arg_conversion_to_pyobject(self, arg, code):
2380 old_type = arg.hdr_type
2381 func = old_type.to_py_function
2383 code.putln("%s = %s(%s); %s" % (
2387 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2388 code.put_var_gotref(arg.entry)
2391 "Cannot convert argument of type '%s' to Python object"
2394 def generate_argument_type_tests(self, code):
2395 # Generate type tests for args whose signature
2396 # type is PyObject * and whose declared type is
2397 # a subtype thereof.
2398 for arg in self.args:
2399 if arg.needs_type_test:
2400 self.generate_arg_type_test(arg, code)
2402 def generate_arg_type_test(self, arg, code):
2403 # Generate type test for one argument.
2404 if arg.type.typeobj_is_available():
2405 typeptr_cname = arg.type.typeptr_cname
2406 arg_code = "((PyObject *)%s)" % arg.entry.cname
2408 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2413 arg.type.is_builtin_type,
2414 code.error_goto(arg.pos)))
2416 error(arg.pos, "Cannot test type of extern C class "
2417 "without type object name specification")
2419 def error_value(self):
2420 return self.entry.signature.error_value
2422 def caller_will_check_exceptions(self):
2425 class OverrideCheckNode(StatNode):
2426 # A Node for dispatching to the def method if it
2435 child_attrs = ['body']
2439 def analyse_expressions(self, env):
2440 self.args = env.arg_entries
2441 if self.py_func.is_module_scope:
2446 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2447 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2448 call_node = ExprNodes.SimpleCallNode(self.pos,
2449 function=self.func_node,
2450 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2451 self.body = ReturnStatNode(self.pos, value=call_node)
2452 self.body.analyse_expressions(env)
2454 def generate_execution_code(self, code):
2455 # Check to see if we are an extension type
2456 if self.py_func.is_module_scope:
2457 self_arg = "((PyObject *)%s)" % Naming.module_cname
2459 self_arg = "((PyObject *)%s)" % self.args[0].cname
2460 code.putln("/* Check if called by wrapper */")
2461 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2462 code.putln("/* Check if overriden in Python */")
2463 if self.py_func.is_module_scope:
2464 code.putln("else {")
2466 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2467 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2468 # need to get attribute manually--scope would return cdef method
2469 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2470 code.put_gotref(self.func_node.py_result())
2471 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2472 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2473 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2474 self.body.generate_execution_code(code)
2476 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2479 class ClassDefNode(StatNode, BlockNode):
2482 class PyClassDefNode(ClassDefNode):
2483 # A Python class definition.
2485 # name EncodedString Name of the class
2486 # doc string or None
2487 # body StatNode Attribute definition code
2488 # entry Symtab.Entry
2489 # scope PyClassScope
2491 # The following subnodes are constructed internally:
2493 # dict DictNode Class dictionary
2494 # classobj ClassNode Class object
2495 # target NameNode Variable to assign class object to
2497 child_attrs = ["body", "dict", "classobj", "target"]
2499 def __init__(self, pos, name, bases, doc, body):
2500 StatNode.__init__(self, pos)
2505 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2506 if self.doc and Options.docstrings:
2507 doc = embed_position(self.pos, self.doc)
2508 doc_node = ExprNodes.StringNode(pos, value = doc)
2511 self.classobj = ExprNodes.ClassNode(pos, name = name,
2512 bases = bases, dict = self.dict, doc = doc_node)
2513 self.target = ExprNodes.NameNode(pos, name = name)
2515 def as_cclass(self):
2517 Return this node as if it were declared as an extension class
2519 bases = self.classobj.bases.args
2521 base_class_name = None
2522 base_class_module = None
2523 elif len(bases) == 1:
2526 from ExprNodes import AttributeNode, NameNode
2527 while isinstance(base, AttributeNode):
2528 path.insert(0, base.attribute)
2530 if isinstance(base, NameNode):
2531 path.insert(0, base.name)
2532 base_class_name = path[-1]
2534 base_class_module = u'.'.join(path[:-1])
2536 base_class_module = None
2538 error(self.classobj.bases.args.pos, "Invalid base class")
2540 error(self.classobj.bases.args.pos, "C class may only have one base class")
2543 return CClassDefNode(self.pos,
2544 visibility = 'private',
2546 class_name = self.name,
2547 base_class_module = base_class_module,
2548 base_class_name = base_class_name,
2553 def create_scope(self, env):
2555 while env.is_py_class_scope or env.is_c_class_scope:
2556 env = env.outer_scope
2557 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2560 def analyse_declarations(self, env):
2561 self.target.analyse_target_declaration(env)
2562 cenv = self.create_scope(env)
2563 cenv.directives = env.directives
2564 cenv.class_obj_cname = self.target.entry.cname
2565 self.body.analyse_declarations(cenv)
2567 def analyse_expressions(self, env):
2568 self.dict.analyse_expressions(env)
2569 self.classobj.analyse_expressions(env)
2570 genv = env.global_scope()
2572 cenv.class_dict_cname = self.dict.result()
2573 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2574 self.body.analyse_expressions(cenv)
2575 self.target.analyse_target_expression(env, self.classobj)
2576 self.dict.release_temp(env)
2577 #self.classobj.release_temp(env)
2578 #self.target.release_target_temp(env)
2580 def generate_function_definitions(self, env, code):
2581 self.generate_py_string_decls(self.scope, code)
2582 self.body.generate_function_definitions(self.scope, code)
2584 def generate_execution_code(self, code):
2585 self.dict.generate_evaluation_code(code)
2586 self.classobj.generate_evaluation_code(code)
2587 self.body.generate_execution_code(code)
2588 self.target.generate_assignment_code(self.classobj, code)
2589 self.dict.generate_disposal_code(code)
2590 self.dict.free_temps(code)
2593 class CClassDefNode(ClassDefNode):
2594 # An extension type definition.
2596 # visibility 'private' or 'public' or 'extern'
2597 # typedef_flag boolean
2599 # module_name string or None For import of extern type objects
2600 # class_name string Unqualified name of class
2601 # as_name string or None Name to declare as in this scope
2602 # base_class_module string or None Module containing the base class
2603 # base_class_name string or None Name of the base class
2604 # objstruct_name string or None Specified C name of object struct
2605 # typeobj_name string or None Specified C name of type object
2606 # in_pxd boolean Is in a .pxd file
2607 # doc string or None
2608 # body StatNode or None
2609 # entry Symtab.Entry
2610 # base_type PyExtensionType or None
2611 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2612 # buffer_defaults_pos
2614 child_attrs = ["body"]
2615 buffer_defaults_node = None
2616 buffer_defaults_pos = None
2617 typedef_flag = False
2619 objstruct_name = None
2622 def analyse_declarations(self, env):
2623 #print "CClassDefNode.analyse_declarations:", self.class_name
2624 #print "...visibility =", self.visibility
2625 #print "...module_name =", self.module_name
2628 if self.buffer_defaults_node:
2629 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2630 env, [], self.buffer_defaults_node,
2631 need_complete=False)
2633 buffer_defaults = None
2635 if env.in_cinclude and not self.objstruct_name:
2636 error(self.pos, "Object struct name specification required for "
2637 "C class defined in 'extern from' block")
2638 self.base_type = None
2639 # Now that module imports are cached, we need to
2640 # import the modules for extern classes.
2641 if self.module_name:
2643 for module in env.cimported_modules:
2644 if module.name == self.module_name:
2645 self.module = module
2646 if self.module is None:
2647 self.module = ModuleScope(self.module_name, None, env.context)
2648 self.module.has_extern_class = 1
2649 env.add_imported_module(self.module)
2651 if self.base_class_name:
2652 if self.base_class_module:
2653 base_class_scope = env.find_module(self.base_class_module, self.pos)
2655 base_class_scope = env
2656 if self.base_class_name == 'object':
2657 # extension classes are special and don't need to inherit from object
2658 if base_class_scope is None or base_class_scope.lookup('object') is None:
2659 self.base_class_name = None
2660 self.base_class_module = None
2661 base_class_scope = None
2662 if base_class_scope:
2663 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2664 if base_class_entry:
2665 if not base_class_entry.is_type:
2666 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2667 elif not base_class_entry.type.is_extension_type:
2668 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2669 elif not base_class_entry.type.is_complete():
2670 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2672 self.base_type = base_class_entry.type
2673 has_body = self.body is not None
2674 if self.module_name and self.visibility != 'extern':
2675 module_path = self.module_name.split(".")
2676 home_scope = env.find_imported_module(module_path, self.pos)
2682 if self.visibility == 'extern':
2683 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2684 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2686 self.entry = home_scope.declare_c_class(
2687 name = self.class_name,
2689 defining = has_body and self.in_pxd,
2690 implementing = has_body and not self.in_pxd,
2691 module_name = self.module_name,
2692 base_type = self.base_type,
2693 objstruct_cname = self.objstruct_name,
2694 typeobj_cname = self.typeobj_name,
2695 visibility = self.visibility,
2696 typedef_flag = self.typedef_flag,
2698 buffer_defaults = buffer_defaults)
2699 if home_scope is not env and self.visibility == 'extern':
2700 env.add_imported_entry(self.class_name, self.entry, pos)
2701 scope = self.entry.type.scope
2702 if scope is not None:
2703 scope.directives = env.directives
2705 if self.doc and Options.docstrings:
2706 scope.doc = embed_position(self.pos, self.doc)
2709 self.body.analyse_declarations(scope)
2713 scope.implemented = 1
2714 env.allocate_vtable_names(self.entry)
2716 def analyse_expressions(self, env):
2718 scope = self.entry.type.scope
2719 self.body.analyse_expressions(scope)
2721 def generate_function_definitions(self, env, code):
2722 self.generate_py_string_decls(self.entry.type.scope, code)
2724 self.body.generate_function_definitions(
2725 self.entry.type.scope, code)
2727 def generate_execution_code(self, code):
2728 # This is needed to generate evaluation code for
2729 # default values of method arguments.
2731 self.body.generate_execution_code(code)
2733 def annotate(self, code):
2735 self.body.annotate(code)
2738 class PropertyNode(StatNode):
2739 # Definition of a property in an extension type.
2742 # doc EncodedString or None Doc string
2745 child_attrs = ["body"]
2747 def analyse_declarations(self, env):
2748 entry = env.declare_property(self.name, self.doc, self.pos)
2750 if self.doc and Options.docstrings:
2751 doc_entry = env.get_string_const(
2752 self.doc, identifier = False)
2753 entry.doc_cname = doc_entry.cname
2754 entry.scope.directives = env.directives
2755 self.body.analyse_declarations(entry.scope)
2757 def analyse_expressions(self, env):
2758 self.body.analyse_expressions(env)
2760 def generate_function_definitions(self, env, code):
2761 self.body.generate_function_definitions(env, code)
2763 def generate_execution_code(self, code):
2766 def annotate(self, code):
2767 self.body.annotate(code)
2770 class GlobalNode(StatNode):
2771 # Global variable declaration.
2777 def analyse_declarations(self, env):
2778 for name in self.names:
2779 env.declare_global(name, self.pos)
2781 def analyse_expressions(self, env):
2784 def generate_execution_code(self, code):
2788 class ExprStatNode(StatNode):
2789 # Expression used as a statement.
2793 child_attrs = ["expr"]
2795 def analyse_declarations(self, env):
2797 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2798 func = self.expr.function.as_cython_attribute()
2799 if func == u'declare':
2800 args, kwds = self.expr.explicit_args_kwds()
2802 error(self.expr.pos, "Variable names must be specified.")
2803 for var, type_node in kwds.key_value_pairs:
2804 type = type_node.analyse_as_type(env)
2806 error(type_node.pos, "Unknown type")
2808 env.declare_var(var.value, type, var.pos, is_cdef = True)
2809 self.__class__ = PassStatNode
2811 def analyse_expressions(self, env):
2812 self.expr.analyse_expressions(env)
2813 self.expr.release_temp(env)
2815 def generate_execution_code(self, code):
2816 self.expr.generate_evaluation_code(code)
2817 if not self.expr.is_temp and self.expr.result():
2818 code.putln("%s;" % self.expr.result())
2819 self.expr.generate_disposal_code(code)
2820 self.expr.free_temps(code)
2822 def annotate(self, code):
2823 self.expr.annotate(code)
2826 class AssignmentNode(StatNode):
2827 # Abstract base class for assignment nodes.
2829 # The analyse_expressions and generate_execution_code
2830 # phases of assignments are split into two sub-phases
2831 # each, to enable all the right hand sides of a
2832 # parallel assignment to be evaluated before assigning
2833 # to any of the left hand sides.
2835 def analyse_expressions(self, env):
2836 self.analyse_types(env)
2837 self.allocate_rhs_temps(env)
2838 self.allocate_lhs_temps(env)
2840 # def analyse_expressions(self, env):
2841 # self.analyse_expressions_1(env)
2842 # self.analyse_expressions_2(env)
2844 def generate_execution_code(self, code):
2845 self.generate_rhs_evaluation_code(code)
2846 self.generate_assignment_code(code)
2849 class SingleAssignmentNode(AssignmentNode):
2850 # The simplest case:
2854 # lhs ExprNode Left hand side
2855 # rhs ExprNode Right hand side
2856 # first bool Is this guaranteed the first assignment to lhs?
2858 child_attrs = ["lhs", "rhs"]
2860 declaration_only = False
2862 def analyse_declarations(self, env):
2865 # handle declarations of the form x = cython.foo()
2866 if isinstance(self.rhs, ExprNodes.CallNode):
2867 func_name = self.rhs.function.as_cython_attribute()
2869 args, kwds = self.rhs.explicit_args_kwds()
2871 if func_name in ['declare', 'typedef']:
2872 if len(args) > 2 or kwds is not None:
2873 error(rhs.pos, "Can only declare one type at a time.")
2875 type = args[0].analyse_as_type(env)
2877 error(args[0].pos, "Unknown type")
2880 if func_name == 'declare':
2881 if isinstance(lhs, ExprNodes.NameNode):
2882 vars = [(lhs.name, lhs.pos)]
2883 elif isinstance(lhs, ExprNodes.TupleNode):
2884 vars = [(var.name, var.pos) for var in lhs.args]
2886 error(lhs.pos, "Invalid declaration")
2888 for var, pos in vars:
2889 env.declare_var(var, type, pos, is_cdef = True)
2894 self.declaration_only = True
2896 self.declaration_only = True
2897 if not isinstance(lhs, ExprNodes.NameNode):
2898 error(lhs.pos, "Invalid declaration.")
2899 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2901 elif func_name in ['struct', 'union']:
2902 self.declaration_only = True
2903 if len(args) > 0 or kwds is None:
2904 error(rhs.pos, "Struct or union members must be given by name.")
2907 for member, type_node in kwds.key_value_pairs:
2908 type = type_node.analyse_as_type(env)
2910 error(type_node.pos, "Unknown type")
2912 members.append((member.value, type, member.pos))
2913 if len(members) < len(kwds.key_value_pairs):
2915 if not isinstance(self.lhs, ExprNodes.NameNode):
2916 error(self.lhs.pos, "Invalid declaration.")
2917 name = self.lhs.name
2918 scope = StructOrUnionScope(name)
2919 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2920 for member, type, pos in members:
2921 scope.declare_var(member, type, pos)
2923 if self.declaration_only:
2926 self.lhs.analyse_target_declaration(env)
2928 def analyse_types(self, env, use_temp = 0):
2929 self.rhs.analyse_types(env)
2930 self.lhs.analyse_target_types(env)
2931 self.lhs.gil_assignment_check(env)
2932 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2934 self.rhs = self.rhs.coerce_to_temp(env)
2936 def allocate_rhs_temps(self, env):
2937 self.rhs.allocate_temps(env)
2939 def allocate_lhs_temps(self, env):
2940 self.lhs.allocate_target_temps(env, self.rhs)
2941 #self.lhs.release_target_temp(env)
2942 #self.rhs.release_temp(env)
2944 def generate_rhs_evaluation_code(self, code):
2945 self.rhs.generate_evaluation_code(code)
2947 def generate_assignment_code(self, code):
2948 self.lhs.generate_assignment_code(self.rhs, code)
2950 def annotate(self, code):
2951 self.lhs.annotate(code)
2952 self.rhs.annotate(code)
2955 class CascadedAssignmentNode(AssignmentNode):
2956 # An assignment with multiple left hand sides:
2960 # lhs_list [ExprNode] Left hand sides
2961 # rhs ExprNode Right hand sides
2965 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2967 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2968 coerced_rhs_list = None
2970 def analyse_declarations(self, env):
2971 for lhs in self.lhs_list:
2972 lhs.analyse_target_declaration(env)
2974 def analyse_types(self, env, use_temp = 0):
2975 self.rhs.analyse_types(env)
2977 self.rhs = self.rhs.coerce_to_temp(env)
2979 self.rhs = self.rhs.coerce_to_simple(env)
2980 from ExprNodes import CloneNode
2981 self.coerced_rhs_list = []
2982 for lhs in self.lhs_list:
2983 lhs.analyse_target_types(env)
2984 lhs.gil_assignment_check(env)
2985 rhs = CloneNode(self.rhs)
2986 rhs = rhs.coerce_to(lhs.type, env)
2987 self.coerced_rhs_list.append(rhs)
2989 def allocate_rhs_temps(self, env):
2990 self.rhs.allocate_temps(env)
2992 def allocate_lhs_temps(self, env):
2993 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2994 rhs.allocate_temps(env)
2995 lhs.allocate_target_temps(env, rhs)
2996 #lhs.release_target_temp(env)
2997 #rhs.release_temp(env)
2998 self.rhs.release_temp(env)
3000 def generate_rhs_evaluation_code(self, code):
3001 self.rhs.generate_evaluation_code(code)
3003 def generate_assignment_code(self, code):
3004 for i in range(len(self.lhs_list)):
3005 lhs = self.lhs_list[i]
3006 rhs = self.coerced_rhs_list[i]
3007 rhs.generate_evaluation_code(code)
3008 lhs.generate_assignment_code(rhs, code)
3009 # Assignment has disposed of the cloned RHS
3010 self.rhs.generate_disposal_code(code)
3011 self.rhs.free_temps(code)
3013 def annotate(self, code):
3014 for i in range(len(self.lhs_list)):
3015 lhs = self.lhs_list[i].annotate(code)
3016 rhs = self.coerced_rhs_list[i].annotate(code)
3017 self.rhs.annotate(code)
3020 class ParallelAssignmentNode(AssignmentNode):
3021 # A combined packing/unpacking assignment:
3025 # This has been rearranged by the parser into
3027 # a = d ; b = e ; c = f
3029 # but we must evaluate all the right hand sides
3030 # before assigning to any of the left hand sides.
3032 # stats [AssignmentNode] The constituent assignments
3034 child_attrs = ["stats"]
3036 def analyse_declarations(self, env):
3037 for stat in self.stats:
3038 stat.analyse_declarations(env)
3040 def analyse_expressions(self, env):
3041 for stat in self.stats:
3042 stat.analyse_types(env, use_temp = 1)
3043 stat.allocate_rhs_temps(env)
3044 for stat in self.stats:
3045 stat.allocate_lhs_temps(env)
3047 # def analyse_expressions(self, env):
3048 # for stat in self.stats:
3049 # stat.analyse_expressions_1(env, use_temp = 1)
3050 # for stat in self.stats:
3051 # stat.analyse_expressions_2(env)
3053 def generate_execution_code(self, code):
3054 for stat in self.stats:
3055 stat.generate_rhs_evaluation_code(code)
3056 for stat in self.stats:
3057 stat.generate_assignment_code(code)
3059 def annotate(self, code):
3060 for stat in self.stats:
3064 class InPlaceAssignmentNode(AssignmentNode):
3065 # An in place arithmatic operand:
3071 # lhs ExprNode Left hand side
3072 # rhs ExprNode Right hand side
3073 # op char one of "+-*/%^&|"
3074 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3076 # This code is a bit tricky because in order to obey Python
3077 # semantics the sub-expressions (e.g. indices) of the lhs must
3078 # not be evaluated twice. So we must re-use the values calculated
3079 # in evaluation phase for the assignment phase as well.
3080 # Fortunately, the type of the lhs node is fairly constrained
3081 # (it must be a NameNode, AttributeNode, or IndexNode).
3083 child_attrs = ["lhs", "rhs"]
3086 def analyse_declarations(self, env):
3087 self.lhs.analyse_target_declaration(env)
3089 def analyse_types(self, env):
3090 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3091 self.rhs.analyse_types(env)
3092 self.lhs.analyse_target_types(env)
3093 if Options.incref_local_binop and self.dup.type.is_pyobject:
3094 self.dup = self.dup.coerce_to_temp(env)
3096 def allocate_rhs_temps(self, env):
3098 if self.lhs.type.is_pyobject:
3099 self.rhs = self.rhs.coerce_to_pyobject(env)
3100 elif self.rhs.type.is_pyobject:
3101 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3102 if self.lhs.type.is_pyobject:
3103 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3104 self.result_value.allocate_temps(env)
3106 # self.rhs = self.rhs.coerce_to_temp(env)
3107 self.rhs.allocate_temps(env)
3108 self.dup.allocate_subexpr_temps(env)
3109 self.dup.allocate_temp(env)
3111 def allocate_lhs_temps(self, env):
3112 self.lhs.allocate_target_temps(env, self.rhs)
3113 # self.lhs.release_target_temp(env)
3114 self.dup.release_temp(env)
3115 if self.dup.is_temp:
3116 self.dup.release_subexpr_temps(env)
3117 # self.rhs.release_temp(env)
3118 if self.lhs.type.is_pyobject:
3119 self.result_value.release_temp(env)
3121 def generate_execution_code(self, code):
3123 self.rhs.generate_evaluation_code(code)
3124 self.dup.generate_subexpr_evaluation_code(code)
3125 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3126 # This is because we're manually messing with subexpr nodes
3127 if self.dup.is_temp:
3128 self.dup.allocate_temp_result(code)
3129 # self.dup.generate_result_code is run only if it is not buffer access
3130 if self.operator == "**":
3134 if self.lhs.type.is_pyobject:
3135 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3136 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3137 self.dup.generate_result_code(code)
3139 "%s = %s(%s, %s%s); %s" % (
3140 self.result_value.result(),
3141 self.py_operation_function(),
3142 self.dup.py_result(),
3143 self.rhs.py_result(),
3145 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3146 code.put_gotref(self.result_value.py_result())
3147 self.result_value.generate_evaluation_code(code) # May be a type check...
3148 self.rhs.generate_disposal_code(code)
3149 self.rhs.free_temps(code)
3150 self.dup.generate_disposal_code(code)
3151 self.dup.free_temps(code)
3152 self.lhs.generate_assignment_code(self.result_value, code)
3154 c_op = self.operator
3158 if self.lhs.type.is_int and self.rhs.type.is_int:
3159 error(self.pos, "** with two C int types is ambiguous")
3161 error(self.pos, "No C inplace power operator")
3162 # have to do assignment directly to avoid side-effects
3163 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3164 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3166 self.dup.generate_result_code(code)
3167 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3168 self.rhs.generate_disposal_code(code)
3169 self.rhs.free_temps(code)
3170 if self.dup.is_temp:
3171 self.dup.generate_subexpr_disposal_code(code)
3172 self.dup.free_subexpr_temps(code)
3174 def create_dup_node(self, env):
3177 self.dup.analyse_types(env)
3178 if isinstance(self.lhs, ExprNodes.NameNode):
3179 target_lhs = ExprNodes.NameNode(self.dup.pos,
3180 name = self.dup.name,
3181 is_temp = self.dup.is_temp,
3182 entry = self.dup.entry)
3183 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3184 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3185 obj = ExprNodes.CloneNode(self.lhs.obj),
3186 attribute = self.dup.attribute,
3187 is_temp = self.dup.is_temp)
3188 elif isinstance(self.lhs, ExprNodes.IndexNode):
3190 index = ExprNodes.CloneNode(self.lhs.index)
3193 if self.lhs.indices:
3194 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3197 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3198 base = ExprNodes.CloneNode(self.dup.base),
3201 is_temp = self.dup.is_temp)
3204 self.lhs = target_lhs
3207 def py_operation_function(self):
3208 return self.py_functions[self.operator]
3211 "|": "PyNumber_InPlaceOr",
3212 "^": "PyNumber_InPlaceXor",
3213 "&": "PyNumber_InPlaceAnd",
3214 "+": "PyNumber_InPlaceAdd",
3215 "-": "PyNumber_InPlaceSubtract",
3216 "*": "PyNumber_InPlaceMultiply",
3217 "/": "PyNumber_InPlaceDivide",
3218 "%": "PyNumber_InPlaceRemainder",
3219 "<<": "PyNumber_InPlaceLshift",
3220 ">>": "PyNumber_InPlaceRshift",
3221 "**": "PyNumber_InPlacePower",
3222 "//": "PyNumber_InPlaceFloorDivide",
3225 def annotate(self, code):
3226 self.lhs.annotate(code)
3227 self.rhs.annotate(code)
3228 self.dup.annotate(code)
3231 class PrintStatNode(StatNode):
3234 # arg_tuple TupleNode
3235 # append_newline boolean
3237 child_attrs = ["arg_tuple"]
3239 def analyse_expressions(self, env):
3240 self.arg_tuple.analyse_expressions(env)
3241 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3242 self.arg_tuple.release_temp(env)
3243 env.use_utility_code(printing_utility_code)
3244 if len(self.arg_tuple.args) == 1 and self.append_newline:
3245 env.use_utility_code(printing_one_utility_code)
3248 gil_message = "Python print statement"
3250 def generate_execution_code(self, code):
3251 if len(self.arg_tuple.args) == 1 and self.append_newline:
3252 arg = self.arg_tuple.args[0]
3253 arg.generate_evaluation_code(code)
3256 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3258 code.error_goto(self.pos)))
3259 arg.generate_disposal_code(code)
3260 arg.free_temps(code)
3262 self.arg_tuple.generate_evaluation_code(code)
3264 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3265 self.arg_tuple.py_result(),
3266 self.append_newline,
3267 code.error_goto(self.pos)))
3268 self.arg_tuple.generate_disposal_code(code)
3269 self.arg_tuple.free_temps(code)
3271 def annotate(self, code):
3272 self.arg_tuple.annotate(code)
3275 class ExecStatNode(StatNode):
3280 child_attrs = ["args"]
3282 def analyse_expressions(self, env):
3283 for i, arg in enumerate(self.args):
3284 arg.analyse_expressions(env)
3285 arg = arg.coerce_to_pyobject(env)
3286 arg.release_temp(env)
3288 self.temp_result = env.allocate_temp_pyobject()
3289 env.release_temp(self.temp_result)
3290 env.use_utility_code(Builtin.pyexec_utility_code)
3293 gil_message = "Python exec statement"
3295 def generate_execution_code(self, code):
3297 for arg in self.args:
3298 arg.generate_evaluation_code(code)
3299 args.append( arg.py_result() )
3300 args = tuple(args + ['0', '0'][:3-len(args)])
3301 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3302 (self.temp_result,) + args))
3303 for arg in self.args:
3304 arg.generate_disposal_code(code)
3305 arg.free_temps(code)
3307 code.error_goto_if_null(self.temp_result, self.pos))
3308 code.put_gotref(self.temp_result)
3309 code.put_decref_clear(self.temp_result, py_object_type)
3311 def annotate(self, code):
3312 for arg in self.args:
3316 class DelStatNode(StatNode):
3321 child_attrs = ["args"]
3323 def analyse_declarations(self, env):
3324 for arg in self.args:
3325 arg.analyse_target_declaration(env)
3327 def analyse_expressions(self, env):
3328 for arg in self.args:
3329 arg.analyse_target_expression(env, None)
3330 if arg.type.is_pyobject:
3333 error(arg.pos, "Deletion of non-Python object")
3334 #arg.release_target_temp(env)
3336 gil_message = "Deleting Python object"
3338 def generate_execution_code(self, code):
3339 for arg in self.args:
3340 if arg.type.is_pyobject:
3341 arg.generate_deletion_code(code)
3342 # else error reported earlier
3344 def annotate(self, code):
3345 for arg in self.args:
3349 class PassStatNode(StatNode):
3354 def analyse_expressions(self, env):
3357 def generate_execution_code(self, code):
3361 class BreakStatNode(StatNode):
3365 def analyse_expressions(self, env):
3368 def generate_execution_code(self, code):
3369 if not code.break_label:
3370 error(self.pos, "break statement not inside loop")
3372 code.put_goto(code.break_label)
3375 class ContinueStatNode(StatNode):
3379 def analyse_expressions(self, env):
3382 def generate_execution_code(self, code):
3383 if code.funcstate.in_try_finally:
3384 error(self.pos, "continue statement inside try of try...finally")
3385 elif not code.continue_label:
3386 error(self.pos, "continue statement not inside loop")
3388 code.put_goto(code.continue_label)
3391 class ReturnStatNode(StatNode):
3394 # value ExprNode or None
3395 # return_type PyrexType
3396 # temps_in_use [Entry] Temps in use at time of return
3398 child_attrs = ["value"]
3400 def analyse_expressions(self, env):
3401 return_type = env.return_type
3402 self.return_type = return_type
3403 self.temps_in_use = env.temps_in_use()
3405 error(self.pos, "Return not inside a function body")
3408 self.value.analyse_types(env)
3409 if return_type.is_void or return_type.is_returncode:
3410 error(self.value.pos,
3411 "Return with value in void function")
3413 self.value = self.value.coerce_to(env.return_type, env)
3414 self.value.allocate_temps(env)
3415 self.value.release_temp(env)
3417 if (not return_type.is_void
3418 and not return_type.is_pyobject
3419 and not return_type.is_returncode):
3420 error(self.pos, "Return value required")
3421 if return_type.is_pyobject:
3424 gil_message = "Returning Python object"
3426 def generate_execution_code(self, code):
3427 code.mark_pos(self.pos)
3428 if not self.return_type:
3429 # error reported earlier
3431 if self.return_type.is_pyobject:
3432 code.put_xdecref(Naming.retval_cname,
3435 self.value.generate_evaluation_code(code)
3436 self.value.make_owned_reference(code)
3439 Naming.retval_cname,
3440 self.value.result_as(self.return_type)))
3441 self.value.generate_post_assignment_code(code)
3442 self.value.free_temps(code)
3444 if self.return_type.is_pyobject:
3445 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3446 elif self.return_type.is_returncode:
3449 Naming.retval_cname,
3450 self.return_type.default_value))
3451 # free temps the old way
3452 for entry in self.temps_in_use:
3453 code.put_var_decref_clear(entry)
3454 # free temps the new way
3455 for cname, type in code.funcstate.temps_holding_reference():
3456 code.put_decref_clear(cname, type)
3459 # code.return_label)
3460 code.put_goto(code.return_label)
3462 def annotate(self, code):
3464 self.value.annotate(code)
3467 class RaiseStatNode(StatNode):
3470 # exc_type ExprNode or None
3471 # exc_value ExprNode or None
3472 # exc_tb ExprNode or None
3474 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3476 def analyse_expressions(self, env):
3478 self.exc_type.analyse_types(env)
3479 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3480 self.exc_type.allocate_temps(env)
3482 self.exc_value.analyse_types(env)
3483 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3484 self.exc_value.allocate_temps(env)
3486 self.exc_tb.analyse_types(env)
3487 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3488 self.exc_tb.allocate_temps(env)
3490 self.exc_type.release_temp(env)
3492 self.exc_value.release_temp(env)
3494 self.exc_tb.release_temp(env)
3495 env.use_utility_code(raise_utility_code)
3496 env.use_utility_code(restore_exception_utility_code)
3499 gil_message = "Raising exception"
3501 def generate_execution_code(self, code):
3503 self.exc_type.generate_evaluation_code(code)
3504 type_code = self.exc_type.py_result()
3508 self.exc_value.generate_evaluation_code(code)
3509 value_code = self.exc_value.py_result()
3513 self.exc_tb.generate_evaluation_code(code)
3514 tb_code = self.exc_tb.py_result()
3517 if self.exc_type or self.exc_value or self.exc_tb:
3519 "__Pyx_Raise(%s, %s, %s);" % (
3526 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3528 obj.generate_disposal_code(code)
3529 obj.free_temps(code)
3531 code.error_goto(self.pos))
3533 def annotate(self, code):
3535 self.exc_type.annotate(code)
3537 self.exc_value.annotate(code)
3539 self.exc_tb.annotate(code)
3542 class ReraiseStatNode(StatNode):
3546 def analyse_expressions(self, env):
3548 env.use_utility_code(raise_utility_code)
3549 env.use_utility_code(restore_exception_utility_code)
3551 gil_message = "Raising exception"
3553 def generate_execution_code(self, code):
3554 vars = code.funcstate.exc_vars
3556 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3557 code.putln(code.error_goto(self.pos))
3559 error(self.pos, "Reraise not inside except clause")
3562 class AssertStatNode(StatNode):
3566 # value ExprNode or None
3568 child_attrs = ["cond", "value"]
3570 def analyse_expressions(self, env):
3571 self.cond = self.cond.analyse_boolean_expression(env)
3573 self.value.analyse_types(env)
3574 self.value = self.value.coerce_to_pyobject(env)
3575 self.value.allocate_temps(env)
3576 self.cond.release_temp(env)
3578 self.value.release_temp(env)
3580 #env.recycle_pending_temps() # TEMPORARY
3582 gil_message = "Raising exception"
3584 def generate_execution_code(self, code):
3585 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3586 self.cond.generate_evaluation_code(code)
3588 "if (unlikely(!%s)) {" %
3591 self.value.generate_evaluation_code(code)
3593 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3594 self.value.py_result())
3595 self.value.generate_disposal_code(code)
3596 self.value.free_temps(code)
3599 "PyErr_SetNone(PyExc_AssertionError);")
3601 code.error_goto(self.pos))
3604 self.cond.generate_disposal_code(code)
3605 self.cond.free_temps(code)
3606 code.putln("#endif")
3608 def annotate(self, code):
3609 self.cond.annotate(code)
3611 self.value.annotate(code)
3614 class IfStatNode(StatNode):
3617 # if_clauses [IfClauseNode]
3618 # else_clause StatNode or None
3620 child_attrs = ["if_clauses", "else_clause"]
3622 def analyse_control_flow(self, env):
3623 env.start_branching(self.pos)
3624 for if_clause in self.if_clauses:
3625 if_clause.analyse_control_flow(env)
3626 env.next_branch(if_clause.end_pos())
3627 if self.else_clause:
3628 self.else_clause.analyse_control_flow(env)
3629 env.finish_branching(self.end_pos())
3631 def analyse_declarations(self, env):
3632 for if_clause in self.if_clauses:
3633 if_clause.analyse_declarations(env)
3634 if self.else_clause:
3635 self.else_clause.analyse_declarations(env)
3637 def analyse_expressions(self, env):
3638 for if_clause in self.if_clauses:
3639 if_clause.analyse_expressions(env)
3640 if self.else_clause:
3641 self.else_clause.analyse_expressions(env)
3643 def generate_execution_code(self, code):
3644 code.mark_pos(self.pos)
3645 end_label = code.new_label()
3646 for if_clause in self.if_clauses:
3647 if_clause.generate_execution_code(code, end_label)
3648 if self.else_clause:
3649 code.putln("/*else*/ {")
3650 self.else_clause.generate_execution_code(code)
3652 code.put_label(end_label)
3654 def annotate(self, code):
3655 for if_clause in self.if_clauses:
3656 if_clause.annotate(code)
3657 if self.else_clause:
3658 self.else_clause.annotate(code)
3661 class IfClauseNode(Node):
3662 # if or elif clause in an if statement
3664 # condition ExprNode
3667 child_attrs = ["condition", "body"]
3669 def analyse_control_flow(self, env):
3670 self.body.analyse_control_flow(env)
3672 def analyse_declarations(self, env):
3673 self.condition.analyse_declarations(env)
3674 self.body.analyse_declarations(env)
3676 def analyse_expressions(self, env):
3678 self.condition.analyse_temp_boolean_expression(env)
3679 self.condition.release_temp(env)
3680 self.body.analyse_expressions(env)
3682 def generate_execution_code(self, code, end_label):
3683 self.condition.generate_evaluation_code(code)
3686 self.condition.result())
3687 self.condition.generate_disposal_code(code)
3688 self.condition.free_temps(code)
3689 self.body.generate_execution_code(code)
3693 code.put_goto(end_label)
3696 def annotate(self, code):
3697 self.condition.annotate(code)
3698 self.body.annotate(code)
3701 class SwitchCaseNode(StatNode):
3702 # Generated in the optimization of an if-elif-else node
3704 # conditions [ExprNode]
3707 child_attrs = ['conditions', 'body']
3709 def generate_execution_code(self, code):
3710 for cond in self.conditions:
3711 code.mark_pos(cond.pos)
3712 code.putln("case %s:" % cond.calculate_result_code())
3713 self.body.generate_execution_code(code)
3714 code.putln("break;")
3716 def annotate(self, code):
3717 for cond in self.conditions:
3719 self.body.annotate(code)
3721 class SwitchStatNode(StatNode):
3722 # Generated in the optimization of an if-elif-else node
3725 # cases [SwitchCaseNode]
3726 # else_clause StatNode or None
3728 child_attrs = ['test', 'cases', 'else_clause']
3730 def generate_execution_code(self, code):
3731 code.putln("switch (%s) {" % self.test.calculate_result_code())
3732 for case in self.cases:
3733 case.generate_execution_code(code)
3734 if self.else_clause is not None:
3735 code.putln("default:")
3736 self.else_clause.generate_execution_code(code)
3737 code.putln("break;")
3740 def annotate(self, code):
3741 self.test.annotate(code)
3742 for case in self.cases:
3744 if self.else_clause is not None:
3745 self.else_clause.annotate(code)
3747 class LoopNode(object):
3749 def analyse_control_flow(self, env):
3750 env.start_branching(self.pos)
3751 self.body.analyse_control_flow(env)
3752 env.next_branch(self.body.end_pos())
3753 if self.else_clause:
3754 self.else_clause.analyse_control_flow(env)
3755 env.finish_branching(self.end_pos())
3758 class WhileStatNode(LoopNode, StatNode):
3761 # condition ExprNode
3763 # else_clause StatNode
3765 child_attrs = ["condition", "body", "else_clause"]
3767 def analyse_declarations(self, env):
3768 self.body.analyse_declarations(env)
3769 if self.else_clause:
3770 self.else_clause.analyse_declarations(env)
3772 def analyse_expressions(self, env):
3774 self.condition.analyse_temp_boolean_expression(env)
3775 self.condition.release_temp(env)
3776 #env.recycle_pending_temps() # TEMPORARY
3777 self.body.analyse_expressions(env)
3778 if self.else_clause:
3779 self.else_clause.analyse_expressions(env)
3781 def generate_execution_code(self, code):
3782 old_loop_labels = code.new_loop_labels()
3785 self.condition.generate_evaluation_code(code)
3786 self.condition.generate_disposal_code(code)
3789 self.condition.result())
3790 self.condition.free_temps(code)
3791 self.body.generate_execution_code(code)
3792 code.put_label(code.continue_label)
3794 break_label = code.break_label
3795 code.set_loop_labels(old_loop_labels)
3796 if self.else_clause:
3797 code.putln("/*else*/ {")
3798 self.else_clause.generate_execution_code(code)
3800 code.put_label(break_label)
3802 def annotate(self, code):
3803 self.condition.annotate(code)
3804 self.body.annotate(code)
3805 if self.else_clause:
3806 self.else_clause.annotate(code)
3809 def ForStatNode(pos, **kw):
3810 if 'iterator' in kw:
3811 return ForInStatNode(pos, **kw)
3813 return ForFromStatNode(pos, **kw)
3815 class ForInStatNode(LoopNode, StatNode):
3819 # iterator IteratorNode
3821 # else_clause StatNode
3822 # item NextNode used internally
3824 child_attrs = ["target", "iterator", "body", "else_clause"]
3827 def analyse_declarations(self, env):
3828 self.target.analyse_target_declaration(env)
3829 self.body.analyse_declarations(env)
3830 if self.else_clause:
3831 self.else_clause.analyse_declarations(env)
3833 def analyse_expressions(self, env):
3835 self.target.analyse_target_types(env)
3836 self.iterator.analyse_expressions(env)
3837 self.item = ExprNodes.NextNode(self.iterator, env)
3838 self.item = self.item.coerce_to(self.target.type, env)
3839 self.item.allocate_temps(env)
3840 self.target.allocate_target_temps(env, self.item)
3841 #self.item.release_temp(env)
3842 #self.target.release_target_temp(env)
3843 self.body.analyse_expressions(env)
3844 if self.else_clause:
3845 self.else_clause.analyse_expressions(env)
3846 self.iterator.release_temp(env)
3848 def generate_execution_code(self, code):
3849 old_loop_labels = code.new_loop_labels()
3850 self.iterator.allocate_counter_temp(code)
3851 self.iterator.generate_evaluation_code(code)
3854 self.item.generate_evaluation_code(code)
3855 self.target.generate_assignment_code(self.item, code)
3856 self.body.generate_execution_code(code)
3857 code.put_label(code.continue_label)
3860 break_label = code.break_label
3861 code.set_loop_labels(old_loop_labels)
3862 if self.else_clause:
3863 code.putln("/*else*/ {")
3864 self.else_clause.generate_execution_code(code)
3866 code.put_label(break_label)
3867 self.iterator.release_counter_temp(code)
3868 self.iterator.generate_disposal_code(code)
3869 self.iterator.free_temps(code)
3871 def annotate(self, code):
3872 self.target.annotate(code)
3873 self.iterator.annotate(code)
3874 self.body.annotate(code)
3875 if self.else_clause:
3876 self.else_clause.annotate(code)
3877 self.item.annotate(code)
3880 class ForFromStatNode(LoopNode, StatNode):
3881 # for name from expr rel name rel expr
3888 # step ExprNode or None
3890 # else_clause StatNode or None
3896 # loopvar_node ExprNode (usually a NameNode or temp node)
3897 # py_loopvar_node PyTempNode or None
3898 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3900 is_py_target = False
3902 py_loopvar_node = None
3905 def analyse_declarations(self, env):
3906 self.target.analyse_target_declaration(env)
3907 self.body.analyse_declarations(env)
3908 if self.else_clause:
3909 self.else_clause.analyse_declarations(env)
3911 def analyse_expressions(self, env):
3913 self.target.analyse_target_types(env)
3914 self.bound1.analyse_types(env)
3915 self.bound2.analyse_types(env)
3916 if self.step is not None:
3917 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3918 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3919 self.step.analyse_types(env)
3921 target_type = self.target.type
3922 if self.target.type.is_numeric:
3923 loop_type = self.target.type
3925 loop_type = PyrexTypes.c_int_type
3926 if not self.bound1.type.is_pyobject:
3927 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3928 if not self.bound2.type.is_pyobject:
3929 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3930 if self.step is not None and not self.step.type.is_pyobject:
3931 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3932 self.bound1 = self.bound1.coerce_to(loop_type, env)
3933 self.bound2 = self.bound2.coerce_to(loop_type, env)
3934 if not self.bound2.is_literal:
3935 self.bound2 = self.bound2.coerce_to_temp(env)
3936 if self.step is not None:
3937 self.step = self.step.coerce_to(loop_type, env)
3938 if not self.step.is_literal:
3939 self.step = self.step.coerce_to_temp(env)
3941 target_type = self.target.type
3942 if not (target_type.is_pyobject or target_type.is_numeric):
3943 error(self.target.pos,
3944 "for-from loop variable must be c numeric type or Python object")
3945 if target_type.is_numeric:
3946 self.is_py_target = False
3947 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3948 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3949 self.loopvar_node = self.target
3950 self.py_loopvar_node = None
3952 self.is_py_target = True
3953 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3954 c_loopvar_node.allocate_temps(env)
3955 self.loopvar_node = c_loopvar_node
3956 self.py_loopvar_node = \
3957 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3958 self.bound1.allocate_temps(env)
3959 self.bound2.allocate_temps(env)
3960 if self.step is not None:
3961 self.step.allocate_temps(env)
3962 if self.is_py_target:
3963 self.py_loopvar_node.allocate_temps(env)
3964 self.target.allocate_target_temps(env, self.py_loopvar_node)
3965 #self.target.release_target_temp(env)
3966 #self.py_loopvar_node.release_temp(env)
3967 self.body.analyse_expressions(env)
3968 if self.is_py_target:
3969 c_loopvar_node.release_temp(env)
3970 if self.else_clause:
3971 self.else_clause.analyse_expressions(env)
3972 self.bound1.release_temp(env)
3973 self.bound2.release_temp(env)
3974 if self.step is not None:
3975 self.step.release_temp(env)
3977 def generate_execution_code(self, code):
3978 old_loop_labels = code.new_loop_labels()
3979 from_range = self.from_range
3980 self.bound1.generate_evaluation_code(code)
3981 self.bound2.generate_evaluation_code(code)
3982 offset, incop = self.relation_table[self.relation1]
3983 if self.step is not None:
3984 self.step.generate_evaluation_code(code)
3985 step = self.step.result()
3986 incop = "%s=%s" % (incop[0], step)
3988 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3990 loopvar_name = self.loopvar_node.result()
3992 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3994 self.bound1.result(), offset,
3995 loopvar_name, self.relation2, self.bound2.result(),
3996 loopvar_name, incop))
3997 if self.py_loopvar_node:
3998 self.py_loopvar_node.generate_evaluation_code(code)
3999 self.target.generate_assignment_code(self.py_loopvar_node, code)
4001 code.putln("%s = %s;" % (
4002 self.target.result(), loopvar_name))
4003 self.body.generate_execution_code(code)
4004 code.put_label(code.continue_label)
4005 if self.py_loopvar_node:
4006 # This mess is to make for..from loops with python targets behave
4007 # exactly like those with C targets with regards to re-assignment
4008 # of the loop variable.
4010 if self.target.entry.is_pyglobal:
4011 # We know target is a NameNode, this is the only ugly case.
4012 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4013 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4014 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4015 target_node.result_code,
4016 Naming.module_cname,
4017 self.target.entry.interned_cname,
4018 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4019 code.put_gotref(target_node.result_code)
4021 target_node = self.target
4022 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4023 from_py_node.temp_code = loopvar_name
4024 from_py_node.generate_result_code(code)
4025 if self.target.entry.is_pyglobal:
4026 code.put_decref_clear(target_node.result_code, py_object_type)
4027 code.funcstate.release_temp(target_node.result_code)
4029 if self.py_loopvar_node:
4030 # This is potentially wasteful, but we don't want the semantics to
4031 # depend on whether or not the loop is a python type.
4032 self.py_loopvar_node.generate_evaluation_code(code)
4033 self.target.generate_assignment_code(self.py_loopvar_node, code)
4034 break_label = code.break_label
4035 code.set_loop_labels(old_loop_labels)
4036 if self.else_clause:
4037 code.putln("/*else*/ {")
4038 self.else_clause.generate_execution_code(code)
4040 code.put_label(break_label)
4041 self.bound1.generate_disposal_code(code)
4042 self.bound1.free_temps(code)
4043 self.bound2.generate_disposal_code(code)
4044 self.bound2.free_temps(code)
4045 if self.step is not None:
4046 self.step.generate_disposal_code(code)
4047 self.step.free_temps(code)
4049 code.funcstate.release_temp(loopvar_name)
4052 # {relop : (initial offset, increment op)}
4059 def annotate(self, code):
4060 self.target.annotate(code)
4061 self.bound1.annotate(code)
4062 self.bound2.annotate(code)
4064 self.bound2.annotate(code)
4065 self.body.annotate(code)
4066 if self.else_clause:
4067 self.else_clause.annotate(code)
4070 class WithStatNode(StatNode):
4072 Represents a Python with statement.
4074 This is only used at parse tree level; and is not present in
4075 analysis or generation phases.
4077 # manager The with statement manager object
4078 # target Node (lhs expression)
4080 child_attrs = ["manager", "target", "body"]
4082 class TryExceptStatNode(StatNode):
4083 # try .. except statement
4086 # except_clauses [ExceptClauseNode]
4087 # else_clause StatNode or None
4088 # cleanup_list [Entry] old style temps to clean up on error
4090 child_attrs = ["body", "except_clauses", "else_clause"]
4092 def analyse_control_flow(self, env):
4093 env.start_branching(self.pos)
4094 self.body.analyse_control_flow(env)
4095 successful_try = env.control_flow # grab this for later
4096 env.next_branch(self.body.end_pos())
4097 env.finish_branching(self.body.end_pos())
4099 env.start_branching(self.except_clauses[0].pos)
4100 for except_clause in self.except_clauses:
4101 except_clause.analyse_control_flow(env)
4102 env.next_branch(except_clause.end_pos())
4104 # the else cause it executed only when the try clause finishes
4105 env.control_flow.incoming = successful_try
4106 if self.else_clause:
4107 self.else_clause.analyse_control_flow(env)
4108 env.finish_branching(self.end_pos())
4110 def analyse_declarations(self, env):
4111 self.body.analyse_declarations(env)
4112 for except_clause in self.except_clauses:
4113 except_clause.analyse_declarations(env)
4114 if self.else_clause:
4115 self.else_clause.analyse_declarations(env)
4117 env.use_utility_code(reset_exception_utility_code)
4119 def analyse_expressions(self, env):
4120 self.body.analyse_expressions(env)
4121 self.cleanup_list = env.free_temp_entries[:]
4122 default_clause_seen = 0
4123 for except_clause in self.except_clauses:
4124 except_clause.analyse_expressions(env)
4125 if default_clause_seen:
4126 error(except_clause.pos, "default 'except:' must be last")
4127 if not except_clause.pattern:
4128 default_clause_seen = 1
4129 self.has_default_clause = default_clause_seen
4130 if self.else_clause:
4131 self.else_clause.analyse_expressions(env)
4134 gil_message = "Try-except statement"
4136 def generate_execution_code(self, code):
4137 old_return_label = code.return_label
4138 old_break_label = code.break_label
4139 old_continue_label = code.continue_label
4140 old_error_label = code.new_error_label()
4141 our_error_label = code.error_label
4142 except_end_label = code.new_label('exception_handled')
4143 except_error_label = code.new_label('except_error')
4144 except_return_label = code.new_label('except_return')
4145 try_return_label = code.new_label('try_return')
4146 try_break_label = code.new_label('try_break')
4147 try_continue_label = code.new_label('try_continue')
4148 try_end_label = code.new_label('try_end')
4151 code.putln("PyObject %s;" %
4152 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4153 code.putln("__Pyx_ExceptionSave(%s);" %
4154 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4155 for var in Naming.exc_save_vars:
4156 code.put_xgotref(var)
4159 code.return_label = try_return_label
4160 code.break_label = try_break_label
4161 code.continue_label = try_continue_label
4162 self.body.generate_execution_code(code)
4165 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4166 code.error_label = except_error_label
4167 code.return_label = except_return_label
4168 if self.else_clause:
4171 self.else_clause.generate_execution_code(code)
4174 for var in Naming.exc_save_vars:
4175 code.put_xdecref_clear(var, py_object_type)
4176 code.put_goto(try_end_label)
4177 if code.label_used(try_return_label):
4178 code.put_label(try_return_label)
4179 for var in Naming.exc_save_vars:
4180 code.put_xdecref_clear(var, py_object_type)
4181 code.put_goto(old_return_label)
4182 code.put_label(our_error_label)
4183 code.put_var_xdecrefs_clear(self.cleanup_list)
4184 for temp_name, type in temps_to_clean_up:
4185 code.put_xdecref_clear(temp_name, type)
4186 for except_clause in self.except_clauses:
4187 except_clause.generate_handling_code(code, except_end_label)
4189 error_label_used = code.label_used(except_error_label)
4190 if error_label_used or not self.has_default_clause:
4191 if error_label_used:
4192 code.put_label(except_error_label)
4193 for var in Naming.exc_save_vars:
4194 code.put_xdecref(var, py_object_type)
4195 code.put_goto(old_error_label)
4197 if code.label_used(try_break_label):
4198 code.put_label(try_break_label)
4199 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4200 code.putln("__Pyx_ExceptionReset(%s);" %
4201 ', '.join(Naming.exc_save_vars))
4202 code.put_goto(old_break_label)
4204 if code.label_used(try_continue_label):
4205 code.put_label(try_continue_label)
4206 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4207 code.putln("__Pyx_ExceptionReset(%s);" %
4208 ', '.join(Naming.exc_save_vars))
4209 code.put_goto(old_continue_label)
4211 if code.label_used(except_return_label):
4212 code.put_label(except_return_label)
4213 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4214 code.putln("__Pyx_ExceptionReset(%s);" %
4215 ', '.join(Naming.exc_save_vars))
4216 code.put_goto(old_return_label)
4218 if code.label_used(except_end_label):
4219 code.put_label(except_end_label)
4220 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4221 code.putln("__Pyx_ExceptionReset(%s);" %
4222 ', '.join(Naming.exc_save_vars))
4223 code.put_label(try_end_label)
4226 code.return_label = old_return_label
4227 code.break_label = old_break_label
4228 code.continue_label = old_continue_label
4229 code.error_label = old_error_label
4231 def annotate(self, code):
4232 self.body.annotate(code)
4233 for except_node in self.except_clauses:
4234 except_node.annotate(code)
4235 if self.else_clause:
4236 self.else_clause.annotate(code)
4239 class ExceptClauseNode(Node):
4240 # Part of try ... except statement.
4243 # target ExprNode or None
4245 # excinfo_target NameNode or None optional target for exception info
4246 # match_flag string result of exception match
4247 # exc_value ExcValueNode used internally
4248 # function_name string qualified name of enclosing function
4249 # exc_vars (string * 3) local exception variables
4251 # excinfo_target is never set by the parser, but can be set by a transform
4252 # in order to extract more extensive information about the exception as a
4253 # sys.exc_info()-style tuple into a target variable
4255 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4258 excinfo_target = None
4260 def analyse_declarations(self, env):
4262 self.target.analyse_target_declaration(env)
4263 if self.excinfo_target is not None:
4264 self.excinfo_target.analyse_target_declaration(env)
4265 self.body.analyse_declarations(env)
4267 def analyse_expressions(self, env):
4269 genv = env.global_scope()
4270 self.function_name = env.qualified_name
4272 self.pattern.analyse_expressions(env)
4273 self.pattern = self.pattern.coerce_to_pyobject(env)
4274 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4275 self.pattern.release_temp(env)
4276 env.release_temp(self.match_flag)
4278 if self.target or self.excinfo_target:
4279 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4281 self.exc_vars = None
4284 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4285 self.exc_value.allocate_temps(env)
4286 self.target.analyse_target_expression(env, self.exc_value)
4287 if self.excinfo_target is not None:
4289 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4290 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4291 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4292 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4294 self.excinfo_tuple.analyse_expressions(env)
4295 self.excinfo_tuple.allocate_temps(env)
4296 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4298 self.body.analyse_expressions(env)
4301 for var in self.exc_vars:
4302 env.release_temp(var)
4304 def generate_handling_code(self, code, end_label):
4305 code.mark_pos(self.pos)
4307 self.pattern.generate_evaluation_code(code)
4309 "%s = PyErr_ExceptionMatches(%s);" % (
4311 self.pattern.py_result()))
4312 self.pattern.generate_disposal_code(code)
4313 self.pattern.free_temps(code)
4318 code.putln("/*except:*/ {")
4321 exc_vars = self.exc_vars
4322 elif not getattr(self.body, 'stats', True):
4323 # most simple case: no exception variable, empty body (pass)
4324 # => reset the exception state, done
4325 code.putln("PyErr_Restore(0,0,0);")
4326 code.put_goto(end_label)
4330 # during type analysis, we didn't know if we need the
4331 # exception value, but apparently, we do
4332 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4336 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4337 # We always have to fetch the exception value even if
4338 # there is no target, because this also normalises the
4339 # exception and stores it in the thread state.
4340 code.globalstate.use_utility_code(get_exception_utility_code)
4341 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4342 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4343 code.error_goto(self.pos)))
4347 self.exc_value.generate_evaluation_code(code)
4348 self.target.generate_assignment_code(self.exc_value, code)
4349 if self.excinfo_target is not None:
4350 self.excinfo_tuple.generate_evaluation_code(code)
4351 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4354 old_break_label, old_continue_label = code.break_label, code.continue_label
4355 code.break_label = code.new_label('except_break')
4356 code.continue_label = code.new_label('except_continue')
4358 old_exc_vars = code.funcstate.exc_vars
4359 code.funcstate.exc_vars = exc_vars
4360 self.body.generate_execution_code(code)
4361 code.funcstate.exc_vars = old_exc_vars
4362 for var in exc_vars:
4363 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4364 code.put_goto(end_label)
4366 if code.label_used(code.break_label):
4367 code.put_label(code.break_label)
4368 for var in exc_vars:
4369 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4370 code.put_goto(old_break_label)
4371 code.break_label = old_break_label
4373 if code.label_used(code.continue_label):
4374 code.put_label(code.continue_label)
4375 for var in exc_vars:
4376 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4377 code.put_goto(old_continue_label)
4378 code.continue_label = old_continue_label
4380 if not self.exc_vars:
4381 # clean up locally allocated temps
4382 for temp in exc_vars:
4383 code.funcstate.release_temp(temp)
4388 def annotate(self, code):
4390 self.pattern.annotate(code)
4392 self.target.annotate(code)
4393 self.body.annotate(code)
4396 class TryFinallyStatNode(StatNode):
4397 # try ... finally statement
4400 # finally_clause StatNode
4402 # cleanup_list [Entry] old_style temps to clean up on error
4404 # The plan is that we funnel all continue, break
4405 # return and error gotos into the beginning of the
4406 # finally block, setting a variable to remember which
4407 # one we're doing. At the end of the finally block, we
4408 # switch on the variable to figure out where to go.
4409 # In addition, if we're doing an error, we save the
4410 # exception on entry to the finally block and restore
4413 child_attrs = ["body", "finally_clause"]
4415 preserve_exception = 1
4417 disallow_continue_in_try_finally = 0
4418 # There doesn't seem to be any point in disallowing
4419 # continue in the try block, since we have no problem
4422 def create_analysed(pos, env, body, finally_clause):
4423 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4424 node.cleanup_list = []
4426 create_analysed = staticmethod(create_analysed)
4428 def analyse_control_flow(self, env):
4429 env.start_branching(self.pos)
4430 self.body.analyse_control_flow(env)
4431 env.next_branch(self.body.end_pos())
4432 env.finish_branching(self.body.end_pos())
4433 self.finally_clause.analyse_control_flow(env)
4435 def analyse_declarations(self, env):
4436 self.body.analyse_declarations(env)
4437 self.finally_clause.analyse_declarations(env)
4439 def analyse_expressions(self, env):
4440 self.body.analyse_expressions(env)
4441 self.cleanup_list = env.free_temp_entries[:]
4442 self.finally_clause.analyse_expressions(env)
4445 gil_message = "Try-finally statement"
4447 def generate_execution_code(self, code):
4448 old_error_label = code.error_label
4449 old_labels = code.all_new_labels()
4450 new_labels = code.get_all_labels()
4451 new_error_label = code.error_label
4452 catch_label = code.new_label()
4455 if self.disallow_continue_in_try_finally:
4456 was_in_try_finally = code.funcstate.in_try_finally
4457 code.funcstate.in_try_finally = 1
4458 self.body.generate_execution_code(code)
4459 if self.disallow_continue_in_try_finally:
4460 code.funcstate.in_try_finally = was_in_try_finally
4463 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4467 error_label_used = 0
4468 for i, new_label in enumerate(new_labels):
4469 if new_label in code.labels_used:
4470 cases_used.append(i)
4471 if new_label == new_error_label:
4472 error_label_used = 1
4473 error_label_case = i
4477 if error_label_used and self.preserve_exception:
4479 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4481 "int %s;" % Naming.exc_lineno_name)
4482 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4483 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4484 code.putln(exc_var_init_zero)
4486 exc_var_init_zero = None
4487 code.use_label(catch_label)
4489 "__pyx_why = 0; goto %s;" % catch_label)
4490 for i in cases_used:
4491 new_label = new_labels[i]
4492 #if new_label and new_label != "<try>":
4493 if new_label == new_error_label and self.preserve_exception:
4494 self.put_error_catcher(code,
4495 new_error_label, i+1, catch_label, temps_to_clean_up)
4497 code.put('%s: ' % new_label)
4498 if exc_var_init_zero:
4499 code.putln(exc_var_init_zero)
4500 code.putln("__pyx_why = %s; goto %s;" % (
4503 code.put_label(catch_label)
4504 code.set_all_labels(old_labels)
4505 if error_label_used:
4506 code.new_error_label()
4507 finally_error_label = code.error_label
4508 self.finally_clause.generate_execution_code(code)
4509 if error_label_used:
4510 if finally_error_label in code.labels_used and self.preserve_exception:
4511 over_label = code.new_label()
4512 code.put_goto(over_label);
4513 code.put_label(finally_error_label)
4514 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4515 for var in Naming.exc_vars:
4516 code.putln("Py_XDECREF(%s);" % var)
4518 code.put_goto(old_error_label)
4519 code.put_label(over_label)
4520 code.error_label = old_error_label
4523 "switch (__pyx_why) {")
4524 for i in cases_used:
4525 old_label = old_labels[i]
4526 if old_label == old_error_label and self.preserve_exception:
4527 self.put_error_uncatcher(code, i+1, old_error_label)
4529 code.use_label(old_label)
4531 "case %s: goto %s;" % (
4539 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4540 code.globalstate.use_utility_code(restore_exception_utility_code)
4547 code.put_var_xdecrefs_clear(self.cleanup_list)
4548 for temp_name, type in temps_to_clean_up:
4549 code.put_xdecref_clear(temp_name, type)
4551 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4555 Naming.exc_lineno_name, Naming.lineno_cname))
4559 code.put_goto(catch_label)
4563 def put_error_uncatcher(self, code, i, error_label):
4564 code.globalstate.use_utility_code(restore_exception_utility_code)
4569 "__Pyx_ErrRestore(%s, %s, %s);" %
4573 Naming.lineno_cname, Naming.exc_lineno_name))
4574 for var in Naming.exc_vars:
4578 code.put_goto(error_label)
4582 def annotate(self, code):
4583 self.body.annotate(code)
4584 self.finally_clause.annotate(code)
4587 class GILStatNode(TryFinallyStatNode):
4588 # 'with gil' or 'with nogil' statement
4590 # state string 'gil' or 'nogil'
4594 preserve_exception = 0
4596 def __init__(self, pos, state, body):
4598 TryFinallyStatNode.__init__(self, pos,
4600 finally_clause = GILExitNode(pos, state = state))
4602 def analyse_expressions(self, env):
4603 env.use_utility_code(force_init_threads_utility_code)
4604 was_nogil = env.nogil
4606 TryFinallyStatNode.analyse_expressions(self, env)
4607 env.nogil = was_nogil
4609 def gil_check(self, env):
4612 def generate_execution_code(self, code):
4613 code.mark_pos(self.pos)
4614 if self.state == 'gil':
4615 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4617 code.putln("{ PyThreadState *_save;")
4618 code.putln("Py_UNBLOCK_THREADS")
4619 TryFinallyStatNode.generate_execution_code(self, code)
4623 class GILExitNode(StatNode):
4624 # Used as the 'finally' block in a GILStatNode
4626 # state string 'gil' or 'nogil'
4630 def analyse_expressions(self, env):
4633 def generate_execution_code(self, code):
4634 if self.state == 'gil':
4635 code.putln("PyGILState_Release();")
4637 code.putln("Py_BLOCK_THREADS")
4640 class CImportStatNode(StatNode):
4643 # module_name string Qualified name of module being imported
4644 # as_name string or None Name specified in "as" clause, if any
4648 def analyse_declarations(self, env):
4649 if not env.is_module_scope:
4650 error(self.pos, "cimport only allowed at module level")
4652 module_scope = env.find_module(self.module_name, self.pos)
4653 if "." in self.module_name:
4654 names = [EncodedString(name) for name in self.module_name.split(".")]
4656 top_module_scope = env.context.find_submodule(top_name)
4657 module_scope = top_module_scope
4658 for name in names[1:]:
4659 submodule_scope = module_scope.find_submodule(name)
4660 module_scope.declare_module(name, submodule_scope, self.pos)
4661 module_scope = submodule_scope
4663 env.declare_module(self.as_name, module_scope, self.pos)
4665 env.declare_module(top_name, top_module_scope, self.pos)
4667 name = self.as_name or self.module_name
4668 env.declare_module(name, module_scope, self.pos)
4670 def analyse_expressions(self, env):
4673 def generate_execution_code(self, code):
4677 class FromCImportStatNode(StatNode):
4678 # from ... cimport statement
4680 # module_name string Qualified name of module
4681 # imported_names [(pos, name, as_name, kind)] Names to be imported
4685 def analyse_declarations(self, env):
4686 if not env.is_module_scope:
4687 error(self.pos, "cimport only allowed at module level")
4689 module_scope = env.find_module(self.module_name, self.pos)
4690 env.add_imported_module(module_scope)
4691 for pos, name, as_name, kind in self.imported_names:
4693 for local_name, entry in module_scope.entries.items():
4694 env.add_imported_entry(local_name, entry, pos)
4696 entry = module_scope.lookup(name)
4698 if kind and not self.declaration_matches(entry, kind):
4699 entry.redeclared(pos)
4701 if kind == 'struct' or kind == 'union':
4702 entry = module_scope.declare_struct_or_union(name,
4703 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4704 elif kind == 'class':
4705 entry = module_scope.declare_c_class(name, pos = pos,
4706 module_name = self.module_name)
4708 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4709 if submodule_scope.parent_module is module_scope:
4710 env.declare_module(as_name or name, submodule_scope, self.pos)
4712 error(pos, "Name '%s' not declared in module '%s'"
4713 % (name, self.module_name))
4716 local_name = as_name or name
4717 env.add_imported_entry(local_name, entry, pos)
4719 def declaration_matches(self, entry, kind):
4720 if not entry.is_type:
4724 if not type.is_extension_type:
4727 if not type.is_struct_or_union:
4729 if kind != type.kind:
4733 def analyse_expressions(self, env):
4736 def generate_execution_code(self, code):
4740 class FromImportStatNode(StatNode):
4741 # from ... import statement
4744 # items [(string, NameNode)]
4745 # interned_items [(string, NameNode, ExprNode)]
4746 # item PyTempNode used internally
4747 # import_star boolean used internally
4749 child_attrs = ["module"]
4752 def analyse_declarations(self, env):
4753 for name, target in self.items:
4755 if not env.is_module_scope:
4756 error(self.pos, "import * only allowed at module level")
4758 env.has_import_star = 1
4759 self.import_star = 1
4761 target.analyse_target_declaration(env)
4763 def analyse_expressions(self, env):
4765 self.module.analyse_expressions(env)
4766 self.item = ExprNodes.PyTempNode(self.pos, env)
4767 self.item.allocate_temp(env)
4768 self.interned_items = []
4769 for name, target in self.items:
4771 for _, entry in env.entries.items():
4772 if not entry.is_type and entry.type.is_extension_type:
4773 env.use_utility_code(ExprNodes.type_test_utility_code)
4776 entry = env.lookup(target.name)
4777 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4778 continue # already cimported
4779 target.analyse_target_expression(env, None)
4780 if target.type is py_object_type:
4783 coerced_item = self.item.coerce_to(target.type, env)
4784 self.interned_items.append(
4785 (env.intern_identifier(name), target, coerced_item))
4786 #target.release_target_temp(env) # was release_temp ?!?
4787 self.module.release_temp(env)
4788 self.item.release_temp(env)
4790 def generate_execution_code(self, code):
4791 self.module.generate_evaluation_code(code)
4792 if self.import_star:
4794 'if (%s(%s) < 0) %s;' % (
4796 self.module.py_result(),
4797 code.error_goto(self.pos)))
4798 for cname, target, coerced_item in self.interned_items:
4800 '%s = PyObject_GetAttr(%s, %s); %s' % (
4802 self.module.py_result(),
4804 code.error_goto_if_null(self.item.result(), self.pos)))
4805 code.put_gotref(self.item.py_result())
4806 if coerced_item is None:
4807 target.generate_assignment_code(self.item, code)
4809 coerced_item.allocate_temp_result(code)
4810 coerced_item.generate_result_code(code)
4811 target.generate_assignment_code(coerced_item, code)
4812 if self.item.result() != coerced_item.result():
4813 code.put_decref_clear(self.item.result(), self.item.type)
4814 self.module.generate_disposal_code(code)
4815 self.module.free_temps(code)
4819 #------------------------------------------------------------------------------------
4821 # Runtime support code
4823 #------------------------------------------------------------------------------------
4825 utility_function_predeclarations = \
4828 #define INLINE __inline__
4830 #define INLINE __inline
4835 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4839 static int %(skip_dispatch_cname)s = 0;
4841 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4843 if Options.gcc_branch_hints:
4844 branch_prediction_macros = \
4847 /* Test for GCC > 2.95 */
4848 #if __GNUC__ > 2 || \
4849 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4850 #define likely(x) __builtin_expect(!!(x), 1)
4851 #define unlikely(x) __builtin_expect(!!(x), 0)
4852 #else /* __GNUC__ > 2 ... */
4853 #define likely(x) (x)
4854 #define unlikely(x) (x)
4855 #endif /* __GNUC__ > 2 ... */
4856 #else /* __GNUC__ */
4857 #define likely(x) (x)
4858 #define unlikely(x) (x)
4859 #endif /* __GNUC__ */
4862 branch_prediction_macros = \
4864 #define likely(x) (x)
4865 #define unlikely(x) (x)
4868 #get_name_predeclaration = \
4869 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4871 #get_name_interned_predeclaration = \
4872 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4874 #------------------------------------------------------------------------------------
4876 printing_utility_code = UtilityCode(
4878 static int __Pyx_Print(PyObject *, int); /*proto*/
4879 #if PY_MAJOR_VERSION >= 3
4880 static PyObject* %s = 0;
4881 static PyObject* %s = 0;
4883 """ % (Naming.print_function, Naming.print_function_kwargs),
4885 #if PY_MAJOR_VERSION < 3
4886 static PyObject *__Pyx_GetStdout(void) {
4887 PyObject *f = PySys_GetObject((char *)"stdout");
4889 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4894 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4899 if (!(f = __Pyx_GetStdout()))
4901 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4902 if (PyFile_SoftSpace(f, 1)) {
4903 if (PyFile_WriteString(" ", f) < 0)
4906 v = PyTuple_GET_ITEM(arg_tuple, i);
4907 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4909 if (PyString_Check(v)) {
4910 char *s = PyString_AsString(v);
4911 Py_ssize_t len = PyString_Size(v);
4913 isspace(Py_CHARMASK(s[len-1])) &&
4915 PyFile_SoftSpace(f, 0);
4919 if (PyFile_WriteString("\n", f) < 0)
4921 PyFile_SoftSpace(f, 0);
4926 #else /* Python 3 has a print function */
4928 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4929 PyObject* kwargs = 0;
4930 PyObject* result = 0;
4931 PyObject* end_string;
4932 if (!%(PRINT_FUNCTION)s) {
4933 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4934 if (!%(PRINT_FUNCTION)s)
4938 if (!%(PRINT_KWARGS)s) {
4939 %(PRINT_KWARGS)s = PyDict_New();
4940 if (!%(PRINT_KWARGS)s)
4942 end_string = PyUnicode_FromStringAndSize(" ", 1);
4945 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4946 Py_DECREF(end_string);
4949 Py_DECREF(end_string);
4951 kwargs = %(PRINT_KWARGS)s;
4953 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4961 """ % {'BUILTINS' : Naming.builtins_cname,
4962 'PRINT_FUNCTION' : Naming.print_function,
4963 'PRINT_KWARGS' : Naming.print_function_kwargs}
4967 printing_one_utility_code = UtilityCode(
4969 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4972 #if PY_MAJOR_VERSION < 3
4974 static int __Pyx_PrintOne(PyObject *o) {
4976 if (!(f = __Pyx_GetStdout()))
4978 if (PyFile_SoftSpace(f, 0)) {
4979 if (PyFile_WriteString(" ", f) < 0)
4982 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4984 if (PyFile_WriteString("\n", f) < 0)
4987 /* the line below is just to avoid compiler
4988 * compiler warnings about unused functions */
4989 return __Pyx_Print(NULL, 0);
4992 #else /* Python 3 has a print function */
4994 static int __Pyx_PrintOne(PyObject *o) {
4996 PyObject* arg_tuple = PyTuple_New(1);
4997 if (unlikely(!arg_tuple))
5000 PyTuple_SET_ITEM(arg_tuple, 0, o);
5001 res = __Pyx_Print(arg_tuple, 1);
5002 Py_DECREF(arg_tuple);
5008 requires=[printing_utility_code])
5012 #------------------------------------------------------------------------------------
5014 # The following function is based on do_raise() from ceval.c.
5016 raise_utility_code = UtilityCode(
5018 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5021 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5025 /* First, check the traceback argument, replacing None with NULL. */
5026 if (tb == Py_None) {
5030 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5031 PyErr_SetString(PyExc_TypeError,
5032 "raise: arg 3 must be a traceback or None");
5035 /* Next, replace a missing value with None */
5036 if (value == NULL) {
5040 #if PY_VERSION_HEX < 0x02050000
5041 if (!PyClass_Check(type))
5043 if (!PyType_Check(type))
5046 /* Raising an instance. The value should be a dummy. */
5047 if (value != Py_None) {
5048 PyErr_SetString(PyExc_TypeError,
5049 "instance exception may not have a separate value");
5052 /* Normalize to raise <class>, <instance> */
5055 #if PY_VERSION_HEX < 0x02050000
5056 if (PyInstance_Check(type)) {
5057 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5062 PyErr_SetString(PyExc_TypeError,
5063 "raise: exception must be an old-style class or instance");
5067 type = (PyObject*) Py_TYPE(type);
5069 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5070 PyErr_SetString(PyExc_TypeError,
5071 "raise: exception class must be a subclass of BaseException");
5076 __Pyx_ErrRestore(type, value, tb);
5086 #------------------------------------------------------------------------------------
5088 reraise_utility_code = UtilityCode(
5090 static void __Pyx_ReRaise(void); /*proto*/
5093 static void __Pyx_ReRaise(void) {
5094 PyThreadState *tstate = PyThreadState_GET();
5095 PyObject* tmp_type = tstate->curexc_type;
5096 PyObject* tmp_value = tstate->curexc_value;
5097 PyObject* tmp_tb = tstate->curexc_traceback;
5098 tstate->curexc_type = tstate->exc_type;
5099 tstate->curexc_value = tstate->exc_value;
5100 tstate->curexc_traceback = tstate->exc_traceback;
5101 tstate->exc_type = 0;
5102 tstate->exc_value = 0;
5103 tstate->exc_traceback = 0;
5104 Py_XDECREF(tmp_type);
5105 Py_XDECREF(tmp_value);
5110 #------------------------------------------------------------------------------------
5112 arg_type_test_utility_code = UtilityCode(
5114 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5115 const char *name, int exact); /*proto*/
5118 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5119 const char *name, int exact)
5122 PyErr_Format(PyExc_SystemError, "Missing type object");
5125 if (none_allowed && obj == Py_None) return 1;
5127 if (Py_TYPE(obj) == type) return 1;
5130 if (PyObject_TypeCheck(obj, type)) return 1;
5132 PyErr_Format(PyExc_TypeError,
5133 "Argument '%s' has incorrect type (expected %s, got %s)",
5134 name, type->tp_name, Py_TYPE(obj)->tp_name);
5139 #------------------------------------------------------------------------------------
5141 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5142 # many or too few positional arguments were found. This handles
5143 # Py_ssize_t formatting correctly.
5145 raise_argtuple_invalid_utility_code = UtilityCode(
5147 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5148 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5151 static void __Pyx_RaiseArgtupleInvalid(
5152 const char* func_name,
5156 Py_ssize_t num_found)
5158 Py_ssize_t num_expected;
5159 const char *number, *more_or_less;
5161 if (num_found < num_min) {
5162 num_expected = num_min;
5163 more_or_less = "at least";
5165 num_expected = num_max;
5166 more_or_less = "at most";
5169 more_or_less = "exactly";
5171 number = (num_expected == 1) ? "" : "s";
5172 PyErr_Format(PyExc_TypeError,
5173 #if PY_VERSION_HEX < 0x02050000
5174 "%s() takes %s %d positional argument%s (%d given)",
5176 "%s() takes %s %zd positional argument%s (%zd given)",
5178 func_name, more_or_less, num_expected, number, num_found);
5182 raise_keyword_required_utility_code = UtilityCode(
5184 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5187 static INLINE void __Pyx_RaiseKeywordRequired(
5188 const char* func_name,
5191 PyErr_Format(PyExc_TypeError,
5192 #if PY_MAJOR_VERSION >= 3
5193 "%s() needs keyword-only argument %U", func_name, kw_name);
5195 "%s() needs keyword-only argument %s", func_name,
5196 PyString_AS_STRING(kw_name));
5201 raise_double_keywords_utility_code = UtilityCode(
5203 static void __Pyx_RaiseDoubleKeywordsError(
5204 const char* func_name, PyObject* kw_name); /*proto*/
5207 static void __Pyx_RaiseDoubleKeywordsError(
5208 const char* func_name,
5211 PyErr_Format(PyExc_TypeError,
5212 #if PY_MAJOR_VERSION >= 3
5213 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5215 "%s() got multiple values for keyword argument '%s'", func_name,
5216 PyString_AS_STRING(kw_name));
5221 #------------------------------------------------------------------------------------
5223 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5224 # were passed to a function, or if any keywords were passed to a
5225 # function that does not accept them.
5227 keyword_string_check_utility_code = UtilityCode(
5229 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5230 const char* function_name, int kw_allowed); /*proto*/
5233 static INLINE int __Pyx_CheckKeywordStrings(
5235 const char* function_name,
5240 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5241 #if PY_MAJOR_VERSION < 3
5242 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5244 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5246 goto invalid_keyword_type;
5248 if ((!kw_allowed) && unlikely(key))
5249 goto invalid_keyword;
5251 invalid_keyword_type:
5252 PyErr_Format(PyExc_TypeError,
5253 "%s() keywords must be strings", function_name);
5256 PyErr_Format(PyExc_TypeError,
5257 #if PY_MAJOR_VERSION < 3
5258 "%s() got an unexpected keyword argument '%s'",
5259 function_name, PyString_AsString(key));
5261 "%s() got an unexpected keyword argument '%U'",
5262 function_name, key);
5268 #------------------------------------------------------------------------------------
5270 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5271 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5272 # keywords will raise an invalid keyword error.
5274 # Three kinds of errors are checked: 1) non-string keywords, 2)
5275 # unexpected keywords and 3) overlap with positional arguments.
5277 # If num_posargs is greater 0, it denotes the number of positional
5278 # arguments that were passed and that must therefore not appear
5279 # amongst the keywords as well.
5281 # This method does not check for required keyword arguments.
5284 parse_keywords_utility_code = UtilityCode(
5286 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5287 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5288 const char* function_name); /*proto*/
5291 static int __Pyx_ParseOptionalKeywords(
5293 PyObject **argnames[],
5296 Py_ssize_t num_pos_args,
5297 const char* function_name)
5299 PyObject *key = 0, *value = 0;
5302 PyObject*** first_kw_arg = argnames + num_pos_args;
5304 while (PyDict_Next(kwds, &pos, &key, &value)) {
5305 name = first_kw_arg;
5306 while (*name && (**name != key)) name++;
5308 values[name-argnames] = value;
5310 #if PY_MAJOR_VERSION < 3
5311 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5313 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5315 goto invalid_keyword_type;
5317 for (name = first_kw_arg; *name; name++) {
5318 #if PY_MAJOR_VERSION >= 3
5319 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5320 PyUnicode_Compare(**name, key) == 0) break;
5322 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5323 _PyString_Eq(**name, key)) break;
5327 values[name-argnames] = value;
5329 /* unexpected keyword found */
5330 for (name=argnames; name != first_kw_arg; name++) {
5331 if (**name == key) goto arg_passed_twice;
5332 #if PY_MAJOR_VERSION >= 3
5333 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5334 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5336 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5337 _PyString_Eq(**name, key)) goto arg_passed_twice;
5341 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5343 goto invalid_keyword;
5351 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5353 invalid_keyword_type:
5354 PyErr_Format(PyExc_TypeError,
5355 "%s() keywords must be strings", function_name);
5358 PyErr_Format(PyExc_TypeError,
5359 #if PY_MAJOR_VERSION < 3
5360 "%s() got an unexpected keyword argument '%s'",
5361 function_name, PyString_AsString(key));
5363 "%s() got an unexpected keyword argument '%U'",
5364 function_name, key);
5371 #------------------------------------------------------------------------------------
5373 traceback_utility_code = UtilityCode(
5375 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5378 #include "compile.h"
5379 #include "frameobject.h"
5380 #include "traceback.h"
5382 static void __Pyx_AddTraceback(const char *funcname) {
5383 PyObject *py_srcfile = 0;
5384 PyObject *py_funcname = 0;
5385 PyObject *py_globals = 0;
5386 PyObject *empty_string = 0;
5387 PyCodeObject *py_code = 0;
5388 PyFrameObject *py_frame = 0;
5390 #if PY_MAJOR_VERSION < 3
5391 py_srcfile = PyString_FromString(%(FILENAME)s);
5393 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5395 if (!py_srcfile) goto bad;
5397 #if PY_MAJOR_VERSION < 3
5398 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5400 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5404 #if PY_MAJOR_VERSION < 3
5405 py_funcname = PyString_FromString(funcname);
5407 py_funcname = PyUnicode_FromString(funcname);
5410 if (!py_funcname) goto bad;
5411 py_globals = PyModule_GetDict(%(GLOBALS)s);
5412 if (!py_globals) goto bad;
5413 #if PY_MAJOR_VERSION < 3
5414 empty_string = PyString_FromStringAndSize("", 0);
5416 empty_string = PyBytes_FromStringAndSize("", 0);
5418 if (!empty_string) goto bad;
5419 py_code = PyCode_New(
5420 0, /*int argcount,*/
5421 #if PY_MAJOR_VERSION >= 3
5422 0, /*int kwonlyargcount,*/
5425 0, /*int stacksize,*/
5427 empty_string, /*PyObject *code,*/
5428 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5429 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5430 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5431 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5432 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5433 py_srcfile, /*PyObject *filename,*/
5434 py_funcname, /*PyObject *name,*/
5435 %(LINENO)s, /*int firstlineno,*/
5436 empty_string /*PyObject *lnotab*/
5438 if (!py_code) goto bad;
5439 py_frame = PyFrame_New(
5440 PyThreadState_GET(), /*PyThreadState *tstate,*/
5441 py_code, /*PyCodeObject *code,*/
5442 py_globals, /*PyObject *globals,*/
5443 0 /*PyObject *locals*/
5445 if (!py_frame) goto bad;
5446 py_frame->f_lineno = %(LINENO)s;
5447 PyTraceBack_Here(py_frame);
5449 Py_XDECREF(py_srcfile);
5450 Py_XDECREF(py_funcname);
5451 Py_XDECREF(empty_string);
5452 Py_XDECREF(py_code);
5453 Py_XDECREF(py_frame);
5456 'FILENAME': Naming.filename_cname,
5457 'LINENO': Naming.lineno_cname,
5458 'CFILENAME': Naming.cfilenm_cname,
5459 'CLINENO': Naming.clineno_cname,
5460 'GLOBALS': Naming.module_cname,
5461 'EMPTY_TUPLE' : Naming.empty_tuple,
5464 restore_exception_utility_code = UtilityCode(
5466 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5467 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5470 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5471 PyObject *tmp_type, *tmp_value, *tmp_tb;
5472 PyThreadState *tstate = PyThreadState_GET();
5474 #if PY_MAJOR_VERSION >= 3
5475 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5476 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5477 tmp_type = tstate->exc_type;
5478 tmp_value = tstate->exc_value;
5479 tmp_tb = tstate->exc_traceback;
5480 PyErr_NormalizeException(&type, &value, &tb);
5481 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5482 tstate->exc_type = 0;
5483 tstate->exc_value = 0;
5484 tstate->exc_traceback = 0;
5485 PyException_SetContext(value, tmp_value);
5486 Py_DECREF(tmp_type);
5491 tmp_type = tstate->curexc_type;
5492 tmp_value = tstate->curexc_value;
5493 tmp_tb = tstate->curexc_traceback;
5494 tstate->curexc_type = type;
5495 tstate->curexc_value = value;
5496 tstate->curexc_traceback = tb;
5497 Py_XDECREF(tmp_type);
5498 Py_XDECREF(tmp_value);
5502 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5503 PyThreadState *tstate = PyThreadState_GET();
5504 *type = tstate->curexc_type;
5505 *value = tstate->curexc_value;
5506 *tb = tstate->curexc_traceback;
5508 tstate->curexc_type = 0;
5509 tstate->curexc_value = 0;
5510 tstate->curexc_traceback = 0;
5515 #------------------------------------------------------------------------------------
5517 unraisable_exception_utility_code = UtilityCode(
5519 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5522 static void __Pyx_WriteUnraisable(const char *name) {
5523 PyObject *old_exc, *old_val, *old_tb;
5525 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5526 #if PY_MAJOR_VERSION < 3
5527 ctx = PyString_FromString(name);
5529 ctx = PyUnicode_FromString(name);
5531 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5533 PyErr_WriteUnraisable(Py_None);
5535 PyErr_WriteUnraisable(ctx);
5540 requires=[restore_exception_utility_code])
5542 #------------------------------------------------------------------------------------
5544 set_vtable_utility_code = UtilityCode(
5546 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5549 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5550 PyObject *pycobj = 0;
5553 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5556 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5569 #------------------------------------------------------------------------------------
5571 get_vtable_utility_code = UtilityCode(
5573 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5576 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5580 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5583 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5584 if (!*(void **)vtabptr)
5597 #------------------------------------------------------------------------------------
5599 init_string_tab_utility_code = UtilityCode(
5601 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5604 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5606 #if PY_MAJOR_VERSION < 3
5607 if (t->is_unicode && (!t->is_identifier)) {
5608 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5609 } else if (t->intern) {
5610 *t->p = PyString_InternFromString(t->s);
5612 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5614 #else /* Python 3+ has unicode identifiers */
5615 if (t->is_identifier || (t->is_unicode && t->intern)) {
5616 *t->p = PyUnicode_InternFromString(t->s);
5617 } else if (t->is_unicode) {
5618 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5620 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5631 #------------------------------------------------------------------------------------
5633 get_exception_utility_code = UtilityCode(
5635 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5638 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5639 PyObject *tmp_type, *tmp_value, *tmp_tb;
5640 PyThreadState *tstate = PyThreadState_GET();
5641 *type = tstate->curexc_type;
5642 *value = tstate->curexc_value;
5643 *tb = tstate->curexc_traceback;
5644 tstate->curexc_type = 0;
5645 tstate->curexc_value = 0;
5646 tstate->curexc_traceback = 0;
5647 PyErr_NormalizeException(type, value, tb);
5648 if (PyErr_Occurred())
5653 tmp_type = tstate->exc_type;
5654 tmp_value = tstate->exc_value;
5655 tmp_tb = tstate->exc_traceback;
5656 tstate->exc_type = *type;
5657 tstate->exc_value = *value;
5658 tstate->exc_traceback = *tb;
5659 /* Make sure tstate is in a consistent state when we XDECREF
5660 these objects (XDECREF may run arbitrary code). */
5661 Py_XDECREF(tmp_type);
5662 Py_XDECREF(tmp_value);
5674 #------------------------------------------------------------------------------------
5676 reset_exception_utility_code = UtilityCode(
5678 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5679 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5682 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5683 PyThreadState *tstate = PyThreadState_GET();
5684 *type = tstate->exc_type;
5685 *value = tstate->exc_value;
5686 *tb = tstate->exc_traceback;
5692 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5693 PyObject *tmp_type, *tmp_value, *tmp_tb;
5694 PyThreadState *tstate = PyThreadState_GET();
5695 tmp_type = tstate->exc_type;
5696 tmp_value = tstate->exc_value;
5697 tmp_tb = tstate->exc_traceback;
5698 tstate->exc_type = type;
5699 tstate->exc_value = value;
5700 tstate->exc_traceback = tb;
5701 Py_XDECREF(tmp_type);
5702 Py_XDECREF(tmp_value);
5707 #------------------------------------------------------------------------------------
5709 force_init_threads_utility_code = UtilityCode(
5711 #ifndef __PYX_FORCE_INIT_THREADS
5712 #if PY_VERSION_HEX < 0x02040200
5713 #define __PYX_FORCE_INIT_THREADS 1
5715 #define __PYX_FORCE_INIT_THREADS 0
5720 #------------------------------------------------------------------------------------