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 return_type.is_pyobject \
569 and (self.exception_value or self.exception_check) \
570 and self.exception_check != '+':
572 "Exception clause not allowed for function returning Python object")
574 if self.exception_value:
575 self.exception_value.analyse_const_expression(env)
576 if self.exception_check == '+':
577 exc_val_type = self.exception_value.type
578 env.add_include_file('stdexcept')
579 if not exc_val_type.is_error and \
580 not exc_val_type.is_pyobject and \
581 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
582 error(self.exception_value.pos,
583 "Exception value must be a Python exception or cdef function with no arguments.")
584 exc_val = self.exception_value
586 exc_val = self.exception_value.result()
587 if not return_type.assignable_from(self.exception_value.type):
588 error(self.exception_value.pos,
589 "Exception value incompatible with function return type")
590 exc_check = self.exception_check
591 if return_type.is_array:
593 "Function cannot return an array")
594 if return_type.is_cfunction:
596 "Function cannot return a function")
597 func_type = PyrexTypes.CFuncType(
598 return_type, func_type_args, self.has_varargs,
599 optional_arg_count = self.optional_arg_count,
600 exception_value = exc_val, exception_check = exc_check,
601 calling_convention = self.base.calling_convention,
602 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
603 if self.optional_arg_count:
604 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
605 return self.base.analyse(func_type, env)
608 class CArgDeclNode(Node):
609 # Item in a function declaration argument list.
611 # base_type CBaseTypeNode
612 # declarator CDeclaratorNode
613 # not_none boolean Tagged with 'not None'
614 # default ExprNode or None
615 # default_entry Symtab.Entry Entry for the variable holding the default value
616 # default_result_code string cname or code fragment for default value
617 # is_self_arg boolean Is the "self" arg of an extension type method
618 # is_kw_only boolean Is a keyword-only argument
620 child_attrs = ["base_type", "declarator", "default"]
625 name_declarator = None
627 def analyse(self, env, nonempty = 0):
628 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
629 if self.type is None:
630 # The parser may missinterpret names as types...
632 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
634 self.declarator.name = self.base_type.name
635 self.base_type.name = None
636 self.base_type.is_basic_c_type = False
639 could_be_name = False
640 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
641 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
642 self.declarator.name = self.base_type.arg_name
643 return self.declarator.analyse(base_type, env, nonempty = nonempty)
645 return self.name_declarator, self.type
647 def annotate(self, code):
649 self.default.annotate(code)
652 class CBaseTypeNode(Node):
653 # Abstract base class for C base type nodes.
655 # Processing during analyse_declarations phase:
662 class CAnalysedBaseTypeNode(Node):
667 def analyse(self, env, could_be_name = False):
670 class CSimpleBaseTypeNode(CBaseTypeNode):
672 # module_path [string] Qualifying name components
673 # is_basic_c_type boolean
676 # is_self_arg boolean Is self argument of C method
679 arg_name = None # in case the argument name was interpreted as a type
681 def analyse(self, env, could_be_name = False):
682 # Return type descriptor.
683 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
685 if self.is_basic_c_type:
686 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
688 error(self.pos, "Unrecognised type modifier combination")
689 elif self.name == "object" and not self.module_path:
690 type = py_object_type
691 elif self.name is None:
692 if self.is_self_arg and env.is_c_class_scope:
693 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
694 type = env.parent_type
696 type = py_object_type
699 scope = env.find_imported_module(self.module_path, self.pos)
703 if scope.is_c_class_scope:
704 scope = scope.global_scope()
705 entry = scope.lookup(self.name)
706 if entry and entry.is_type:
709 if self.is_self_arg and env.is_c_class_scope:
710 type = env.parent_type
712 type = py_object_type
713 self.arg_name = self.name
715 error(self.pos, "'%s' is not a type identifier" % self.name)
719 return PyrexTypes.error_type
721 class CBufferAccessTypeNode(CBaseTypeNode):
723 # positional_args [ExprNode] List of positional arguments
724 # keyword_args DictNode Keyword arguments
725 # base_type_node CBaseTypeNode
728 # type PyrexType.BufferType ...containing the right options
731 child_attrs = ["base_type_node", "positional_args",
732 "keyword_args", "dtype_node"]
738 def analyse(self, env, could_be_name = False):
739 base_type = self.base_type_node.analyse(env)
740 if base_type.is_error: return base_type
743 options = Buffer.analyse_buffer_options(
746 self.positional_args,
748 base_type.buffer_defaults)
750 self.type = PyrexTypes.BufferType(base_type, **options)
753 class CComplexBaseTypeNode(CBaseTypeNode):
754 # base_type CBaseTypeNode
755 # declarator CDeclaratorNode
757 child_attrs = ["base_type", "declarator"]
759 def analyse(self, env, could_be_name = False):
760 base = self.base_type.analyse(env, could_be_name)
761 _, type = self.declarator.analyse(base, env)
765 class CVarDefNode(StatNode):
766 # C variable definition or forward/extern function declaration.
768 # visibility 'private' or 'public' or 'extern'
769 # base_type CBaseTypeNode
770 # declarators [CDeclaratorNode]
773 # need_properties [entry]
775 # decorators [cython.locals(...)] or None
776 # directive_locals { string : NameNode } locals defined by cython.locals(...)
778 child_attrs = ["base_type", "declarators"]
782 directive_locals = {}
784 def analyse_declarations(self, env, dest_scope = None):
787 self.dest_scope = dest_scope
788 base_type = self.base_type.analyse(env)
789 if (dest_scope.is_c_class_scope
790 and self.visibility == 'public'
791 and base_type.is_pyobject
792 and (base_type.is_builtin_type or base_type.is_extension_type)):
793 self.need_properties = []
795 visibility = 'private'
797 need_property = False
798 visibility = self.visibility
800 for declarator in self.declarators:
801 name_declarator, type = declarator.analyse(base_type, env)
802 if not type.is_complete():
803 if not (self.visibility == 'extern' and type.is_array):
804 error(declarator.pos,
805 "Variable type '%s' is incomplete" % type)
806 if self.visibility == 'extern' and type.is_pyobject:
807 error(declarator.pos,
808 "Python object cannot be declared extern")
809 name = name_declarator.name
810 cname = name_declarator.cname
812 error(declarator.pos, "Missing name in declaration.")
814 if type.is_cfunction:
815 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
816 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
818 if entry is not None:
819 entry.directive_locals = self.directive_locals
821 if self.directive_locals:
822 s.error("Decorators can only be followed by functions")
823 if self.in_pxd and self.visibility != 'extern':
825 "Only 'extern' C variable declaration allowed in .pxd file")
826 entry = dest_scope.declare_var(name, type, declarator.pos,
827 cname = cname, visibility = visibility, is_cdef = 1)
829 self.need_properties.append(entry)
830 entry.needs_property = 1
833 class CStructOrUnionDefNode(StatNode):
835 # cname string or None
836 # kind "struct" or "union"
837 # typedef_flag boolean
838 # visibility "public" or "private"
840 # attributes [CVarDefNode] or None
843 child_attrs = ["attributes"]
845 def analyse_declarations(self, env):
847 if self.attributes is not None:
848 scope = StructOrUnionScope(self.name)
849 self.entry = env.declare_struct_or_union(
850 self.name, self.kind, scope, self.typedef_flag, self.pos,
851 self.cname, visibility = self.visibility)
852 if self.attributes is not None:
853 if self.in_pxd and not env.in_cinclude:
854 self.entry.defined_in_pxd = 1
855 for attr in self.attributes:
856 attr.analyse_declarations(env, scope)
857 if self.visibility != 'extern':
858 need_typedef_indirection = False
859 for attr in scope.var_entries:
862 type = type.base_type
863 if type == self.entry.type:
864 error(attr.pos, "Struct cannot contain itself as a member.")
865 if self.typedef_flag:
867 type = type.base_type
868 if type == self.entry.type:
869 need_typedef_indirection = True
870 if need_typedef_indirection:
871 # C can't handle typedef structs that refer to themselves.
872 struct_entry = self.entry
873 cname = env.new_const_cname()
874 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
875 struct_entry.type.typedef_flag = False
876 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
878 def analyse_expressions(self, env):
881 def generate_execution_code(self, code):
885 class CEnumDefNode(StatNode):
886 # name string or None
887 # cname string or None
888 # items [CEnumDefItemNode]
889 # typedef_flag boolean
890 # visibility "public" or "private"
894 child_attrs = ["items"]
896 def analyse_declarations(self, env):
897 self.entry = env.declare_enum(self.name, self.pos,
898 cname = self.cname, typedef_flag = self.typedef_flag,
899 visibility = self.visibility)
900 if self.items is not None:
901 if self.in_pxd and not env.in_cinclude:
902 self.entry.defined_in_pxd = 1
903 for item in self.items:
904 item.analyse_declarations(env, self.entry)
906 def analyse_expressions(self, env):
907 if self.visibility == 'public':
908 self.temp = env.allocate_temp_pyobject()
909 env.release_temp(self.temp)
911 def generate_execution_code(self, code):
912 if self.visibility == 'public':
913 for item in self.entry.enum_values:
914 code.putln("%s = PyInt_FromLong(%s); %s" % (
917 code.error_goto_if_null(self.temp, item.pos)))
918 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
922 code.error_goto(item.pos)))
923 code.putln("%s = 0;" % self.temp)
926 class CEnumDefItemNode(StatNode):
928 # cname string or None
929 # value ExprNode or None
931 child_attrs = ["value"]
933 def analyse_declarations(self, env, enum_entry):
935 self.value.analyse_const_expression(env)
936 if not self.value.type.is_int:
937 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
938 self.value.analyse_const_expression(env)
939 value = self.value.result()
942 entry = env.declare_const(self.name, enum_entry.type,
943 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
944 enum_entry.enum_values.append(entry)
947 class CTypeDefNode(StatNode):
948 # base_type CBaseTypeNode
949 # declarator CDeclaratorNode
950 # visibility "public" or "private"
953 child_attrs = ["base_type", "declarator"]
955 def analyse_declarations(self, env):
956 base = self.base_type.analyse(env)
957 name_declarator, type = self.declarator.analyse(base, env)
958 name = name_declarator.name
959 cname = name_declarator.cname
960 entry = env.declare_typedef(name, type, self.pos,
961 cname = cname, visibility = self.visibility)
962 if self.in_pxd and not env.in_cinclude:
963 entry.defined_in_pxd = 1
965 def analyse_expressions(self, env):
967 def generate_execution_code(self, code):
971 class FuncDefNode(StatNode, BlockNode):
972 # Base class for function definition nodes.
974 # return_type PyrexType
975 # #filename string C name of filename string const
977 # needs_closure boolean Whether or not this function has inner functions/classes/yield
978 # directive_locals { string : NameNode } locals defined by cython.locals(...)
982 needs_closure = False
984 def analyse_default_values(self, env):
985 genv = env.global_scope()
986 for arg in self.args:
989 if not hasattr(arg, 'default_entry'):
990 arg.default.analyse_types(env)
991 arg.default = arg.default.coerce_to(arg.type, genv)
992 if arg.default.is_literal:
993 arg.default_entry = arg.default
994 arg.default_result_code = arg.default.calculate_result_code()
995 if arg.default.type != arg.type and not arg.type.is_int:
996 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
998 arg.default.allocate_temps(genv)
999 arg.default_entry = genv.add_default_value(arg.type)
1000 if arg.type.is_pyobject:
1001 arg.default_entry.init = 0
1002 arg.default_entry.used = 1
1003 arg.default_result_code = arg.default_entry.cname
1006 "This argument cannot have a default value")
1009 def need_gil_acquisition(self, lenv):
1012 def create_local_scope(self, env):
1014 while env.is_py_class_scope or env.is_c_class_scope:
1015 env = env.outer_scope
1016 if self.needs_closure:
1017 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1019 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1020 lenv.return_type = self.return_type
1021 type = self.entry.type
1022 if type.is_cfunction:
1023 lenv.nogil = type.nogil and not type.with_gil
1024 self.local_scope = lenv
1027 def generate_function_definitions(self, env, code):
1030 lenv = self.local_scope
1032 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1033 self.entry.scope.is_c_class_scope)
1035 # Generate C code for header and body of function
1036 code.enter_cfunc_scope()
1037 code.return_from_error_cleanup_label = code.new_label()
1039 # ----- Top-level constants used by this function
1040 code.mark_pos(self.pos)
1041 self.generate_interned_num_decls(lenv, code)
1042 self.generate_interned_string_decls(lenv, code)
1043 self.generate_py_string_decls(lenv, code)
1044 self.generate_cached_builtins_decls(lenv, code)
1046 #code.put_var_declarations(lenv.const_entries, static = 1)
1047 self.generate_const_definitions(lenv, code)
1048 # ----- Function header
1051 self.py_func.generate_function_header(code,
1052 with_pymethdef = env.is_py_class_scope,
1054 self.generate_function_header(code,
1055 with_pymethdef = env.is_py_class_scope)
1056 # ----- Local variable declarations
1057 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1058 self.generate_argument_declarations(lenv, code)
1059 if self.needs_closure:
1060 code.putln("/* TODO: declare and create scope object */")
1061 code.put_var_declarations(lenv.var_entries)
1063 if not self.return_type.is_void:
1064 if self.return_type.is_pyobject:
1068 (self.return_type.declaration_code(
1069 Naming.retval_cname),
1071 tempvardecl_code = code.insertion_point()
1072 self.generate_keyword_list(code)
1073 # ----- Extern library function declarations
1074 lenv.generate_library_function_declarations(code)
1075 # ----- GIL acquisition
1076 acquire_gil = self.need_gil_acquisition(lenv)
1078 env.use_utility_code(force_init_threads_utility_code)
1079 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1080 # ----- Automatic lead-ins for certain special functions
1082 code.put_setup_refcount_context(self.entry.name)
1083 if is_getbuffer_slot:
1084 self.getbuffer_init(code)
1085 # ----- Fetch arguments
1086 self.generate_argument_parsing_code(env, code)
1087 # If an argument is assigned to in the body, we must
1088 # incref it to properly keep track of refcounts.
1089 for entry in lenv.arg_entries:
1090 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1091 code.put_var_incref(entry)
1092 # ----- Initialise local variables
1093 for entry in lenv.var_entries:
1094 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1095 code.put_init_var_to_py_none(entry)
1096 # ----- Initialise local buffer auxiliary variables
1097 for entry in lenv.var_entries + lenv.arg_entries:
1098 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1099 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1100 # ----- Check and convert arguments
1101 self.generate_argument_type_tests(code)
1102 # ----- Acquire buffer arguments
1103 for entry in lenv.arg_entries:
1104 if entry.type.is_buffer:
1105 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1106 # ----- Function body
1107 self.body.generate_execution_code(code)
1108 # ----- Default return value
1110 if self.return_type.is_pyobject:
1111 #if self.return_type.is_extension_type:
1112 # lhs = "(PyObject *)%s" % Naming.retval_cname
1114 lhs = Naming.retval_cname
1115 code.put_init_to_py_none(lhs, self.return_type)
1117 val = self.return_type.default_value
1119 code.putln("%s = %s;" % (Naming.retval_cname, val))
1120 # ----- Error cleanup
1121 if code.error_label in code.labels_used:
1122 code.put_goto(code.return_label)
1123 code.put_label(code.error_label)
1124 # cleanup temps the old way
1125 code.put_var_xdecrefs(lenv.temp_entries)
1126 # cleanup temps the new way
1127 for cname, type in code.funcstate.all_managed_temps():
1128 code.put_xdecref(cname, type)
1130 # Clean up buffers -- this calls a Python function
1131 # so need to save and restore error state
1132 buffers_present = len(lenv.buffer_entries) > 0
1134 code.globalstate.use_utility_code(restore_exception_utility_code)
1135 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1136 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1137 for entry in lenv.buffer_entries:
1138 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1139 #code.putln("%s = 0;" % entry.cname)
1140 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1142 err_val = self.error_value()
1143 exc_check = self.caller_will_check_exceptions()
1144 if err_val is not None or exc_check:
1145 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1147 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1148 % self.entry.qualified_name, 0)
1150 '__Pyx_WriteUnraisable("%s");' %
1151 self.entry.qualified_name)
1152 env.use_utility_code(unraisable_exception_utility_code)
1153 env.use_utility_code(restore_exception_utility_code)
1154 default_retval = self.return_type.default_value
1155 if err_val is None and default_retval:
1156 err_val = default_retval
1157 if err_val is not None:
1160 Naming.retval_cname,
1163 if is_getbuffer_slot:
1164 self.getbuffer_error_cleanup(code)
1166 # If we are using the non-error cleanup section we should
1167 # jump past it if we have an error. The if-test below determine
1168 # whether this section is used.
1169 if buffers_present or is_getbuffer_slot:
1170 code.put_goto(code.return_from_error_cleanup_label)
1173 # ----- Non-error return cleanup
1174 # If you add anything here, remember to add a condition to the
1175 # if-test above in the error block (so that it can jump past this
1177 code.put_label(code.return_label)
1178 for entry in lenv.buffer_entries:
1180 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1181 if is_getbuffer_slot:
1182 self.getbuffer_normal_cleanup(code)
1183 # ----- Return cleanup for both error and no-error return
1184 code.put_label(code.return_from_error_cleanup_label)
1185 if not Options.init_local_none:
1186 for entry in lenv.var_entries:
1187 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1188 entry.xdecref_cleanup = 1
1189 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1190 # Decref any increfed args
1191 for entry in lenv.arg_entries:
1192 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1193 code.put_var_decref(entry)
1195 # code.putln("/* TODO: decref scope object */")
1197 # This code is duplicated in ModuleNode.generate_module_init_func
1199 default_retval = self.return_type.default_value
1200 err_val = self.error_value()
1201 if err_val is None and default_retval:
1202 err_val = default_retval
1203 if self.return_type.is_pyobject:
1204 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1206 code.put_finish_refcount_context()
1209 code.putln("PyGILState_Release(_save);")
1211 if not self.return_type.is_void:
1212 code.putln("return %s;" % Naming.retval_cname)
1215 # ----- Go back and insert temp variable declarations
1216 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1217 tempvardecl_code.put_temp_declarations(code.funcstate)
1218 # ----- Python version
1219 code.exit_cfunc_scope()
1221 self.py_func.generate_function_definitions(env, code)
1222 self.generate_wrapper_functions(code)
1224 def declare_argument(self, env, arg):
1225 if arg.type.is_void:
1226 error(arg.pos, "Invalid use of 'void'")
1227 elif not arg.type.is_complete() and not arg.type.is_array:
1229 "Argument type '%s' is incomplete" % arg.type)
1230 return env.declare_arg(arg.name, arg.type, arg.pos)
1232 def generate_wrapper_functions(self, code):
1235 def generate_execution_code(self, code):
1236 # Evaluate and store argument default values
1237 for arg in self.args:
1238 default = arg.default
1240 if not default.is_literal:
1241 default.generate_evaluation_code(code)
1242 default.make_owned_reference(code)
1245 arg.default_entry.cname,
1246 default.result_as(arg.default_entry.type)))
1247 if default.is_temp and default.type.is_pyobject:
1248 code.putln("%s = 0;" % default.result())
1249 default.free_temps(code)
1250 code.put_var_giveref(arg.default_entry)
1251 # For Python class methods, create and store function object
1253 self.assmt.generate_execution_code(code)
1256 # Special code for the __getbuffer__ function
1258 def getbuffer_init(self, code):
1259 info = self.local_scope.arg_entries[1].cname
1260 # Python 3.0 betas have a bug in memoryview which makes it call
1261 # getbuffer with a NULL parameter. For now we work around this;
1262 # the following line should be removed when this bug is fixed.
1263 code.putln("if (%s == NULL) return 0;" % info)
1264 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1265 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1267 def getbuffer_error_cleanup(self, code):
1268 info = self.local_scope.arg_entries[1].cname
1269 code.put_gotref("%s->obj" % info)
1270 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1273 def getbuffer_normal_cleanup(self, code):
1274 info = self.local_scope.arg_entries[1].cname
1275 code.putln("if (%s->obj == Py_None) {" % info)
1276 code.put_gotref("Py_None")
1277 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1280 class CFuncDefNode(FuncDefNode):
1281 # C function definition.
1283 # modifiers ['inline']
1284 # visibility 'private' or 'public' or 'extern'
1285 # base_type CBaseTypeNode
1286 # declarator CDeclaratorNode
1289 # decorators [DecoratorNode] list of decorators
1291 # with_gil boolean Acquire GIL around body
1293 # py_func wrapper for calling from Python
1294 # overridable whether or not this is a cpdef function
1295 # inline_in_pxd whether this is an inline function in a pxd file
1297 child_attrs = ["base_type", "declarator", "body", "py_func"]
1299 inline_in_pxd = False
1301 directive_locals = {}
1303 def unqualified_name(self):
1304 return self.entry.name
1306 def analyse_declarations(self, env):
1307 if 'locals' in env.directives and env.directives['locals']:
1308 self.directive_locals = env.directives['locals']
1309 directive_locals = self.directive_locals
1310 base_type = self.base_type.analyse(env)
1311 # The 2 here is because we need both function and argument names.
1312 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1313 if not type.is_cfunction:
1315 "Suite attached to non-function declaration")
1316 # Remember the actual type according to the function header
1317 # written here, because the type in the symbol table entry
1318 # may be different if we're overriding a C method inherited
1319 # from the base type of an extension type.
1321 type.is_overridable = self.overridable
1322 declarator = self.declarator
1323 while not hasattr(declarator, 'args'):
1324 declarator = declarator.base
1325 self.args = declarator.args
1326 for formal_arg, type_arg in zip(self.args, type.args):
1327 formal_arg.type = type_arg.type
1328 formal_arg.name = type_arg.name
1329 formal_arg.cname = type_arg.cname
1330 name = name_declarator.name
1331 cname = name_declarator.cname
1332 self.entry = env.declare_cfunction(
1333 name, type, self.pos,
1334 cname = cname, visibility = self.visibility,
1335 defining = self.body is not None,
1336 api = self.api, modifiers = self.modifiers)
1337 self.entry.inline_func_in_pxd = self.inline_in_pxd
1338 self.return_type = type.return_type
1340 if self.overridable and not env.is_module_scope:
1341 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1342 # An error will be produced in the cdef function
1343 self.overridable = False
1345 if self.overridable:
1347 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1348 self.py_func = DefNode(pos = self.pos,
1349 name = self.entry.name,
1352 starstar_arg = None,
1354 body = py_func_body,
1356 self.py_func.is_module_scope = env.is_module_scope
1357 self.py_func.analyse_declarations(env)
1358 self.entry.as_variable = self.py_func.entry
1359 # Reset scope entry the above cfunction
1360 env.entries[name] = self.entry
1361 self.py_func.interned_attr_cname = env.intern_identifier(
1362 self.py_func.entry.name)
1363 if not env.is_module_scope or Options.lookup_module_cpdef:
1364 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1365 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1367 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1369 args = self.type.args
1370 if omit_optional_args:
1371 args = args[:len(args) - self.type.optional_arg_count]
1372 arg_names = [arg.name for arg in args]
1374 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1376 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1377 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1378 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1379 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)
1380 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1382 def declare_arguments(self, env):
1383 for arg in self.type.args:
1385 error(arg.pos, "Missing argument name")
1386 self.declare_argument(env, arg)
1388 def need_gil_acquisition(self, lenv):
1390 with_gil = self.type.with_gil
1391 if type.nogil and not with_gil:
1392 if type.return_type.is_pyobject:
1394 "Function with Python return type cannot be declared nogil")
1395 for entry in lenv.var_entries + lenv.temp_entries:
1396 if entry.type.is_pyobject:
1397 error(self.pos, "Function declared nogil has Python locals or temporaries")
1400 def analyse_expressions(self, env):
1401 self.local_scope.directives = env.directives
1402 self.analyse_default_values(env)
1403 if self.py_func is not None:
1404 self.py_func.analyse_expressions(env)
1406 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1409 visibility = self.entry.visibility
1410 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1411 arg_decls.append(arg.declaration_code())
1412 if with_dispatch and self.overridable:
1413 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1414 if type.optional_arg_count and with_opt_args:
1415 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1416 if type.has_varargs:
1417 arg_decls.append("...")
1419 arg_decls = ["void"]
1421 cname = self.entry.func_cname
1422 entity = type.function_header_code(cname, ', '.join(arg_decls))
1423 if visibility == 'public':
1424 dll_linkage = "DL_EXPORT"
1427 header = self.return_type.declaration_code(entity,
1428 dll_linkage = dll_linkage)
1429 if visibility == 'extern':
1430 storage_class = "%s " % Naming.extern_c_macro
1431 elif visibility == 'public':
1434 storage_class = "static "
1435 code.putln("%s%s %s {" % (
1437 ' '.join(self.modifiers).upper(), # macro forms
1440 def generate_argument_declarations(self, env, code):
1441 for arg in self.args:
1443 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1445 def generate_keyword_list(self, code):
1448 def generate_argument_parsing_code(self, env, code):
1450 if self.type.optional_arg_count:
1451 code.putln('if (%s) {' % Naming.optional_args_cname)
1452 for arg in self.args:
1454 # FIXME: simple name prefixing doesn't work when
1455 # argument name mangling is in place
1456 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1457 declarator = arg.declarator
1458 while not hasattr(declarator, 'name'):
1459 declarator = declarator.base
1460 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1462 for _ in range(self.type.optional_arg_count):
1466 def generate_argument_conversion_code(self, code):
1469 def generate_argument_type_tests(self, code):
1470 # Generate type tests for args whose type in a parent
1471 # class is a supertype of the declared type.
1472 for arg in self.type.args:
1473 if arg.needs_type_test:
1474 self.generate_arg_type_test(arg, code)
1476 def generate_arg_type_test(self, arg, code):
1477 # Generate type test for one argument.
1478 if arg.type.typeobj_is_available():
1479 typeptr_cname = arg.type.typeptr_cname
1480 arg_code = "((PyObject *)%s)" % arg.cname
1482 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1487 type.is_builtin_type,
1488 code.error_goto(arg.pos)))
1490 error(arg.pos, "Cannot test type of extern C class "
1491 "without type object name specification")
1493 def error_value(self):
1494 if self.return_type.is_pyobject:
1498 return self.entry.type.exception_value
1500 def caller_will_check_exceptions(self):
1501 return self.entry.type.exception_check
1503 def generate_wrapper_functions(self, code):
1504 # If the C signature of a function has changed, we need to generate
1505 # wrappers to put in the slots here.
1508 func_type = entry.type
1509 while entry.prev_entry is not None:
1511 entry = entry.prev_entry
1512 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1514 self.generate_function_header(code,
1516 with_dispatch = entry.type.is_overridable,
1517 with_opt_args = entry.type.optional_arg_count,
1518 cname = entry.func_cname)
1519 if not self.return_type.is_void:
1521 args = self.type.args
1522 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1523 if entry.type.is_overridable:
1524 arglist.append(Naming.skip_dispatch_cname)
1525 elif func_type.is_overridable:
1527 if entry.type.optional_arg_count:
1528 arglist.append(Naming.optional_args_cname)
1529 elif func_type.optional_arg_count:
1530 arglist.append('NULL')
1531 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1535 class PyArgDeclNode(Node):
1536 # Argument which must be a Python object (used
1537 # for * and ** arguments).
1540 # entry Symtab.Entry
1544 class DecoratorNode(Node):
1547 # decorator NameNode or CallNode
1548 child_attrs = ['decorator']
1551 class DefNode(FuncDefNode):
1552 # A Python function definition.
1554 # name string the Python name of the function
1555 # decorators [DecoratorNode] list of decorators
1556 # args [CArgDeclNode] formal arguments
1557 # star_arg PyArgDeclNode or None * argument
1558 # starstar_arg PyArgDeclNode or None ** argument
1559 # doc EncodedString or None
1562 # The following subnode is constructed internally
1563 # when the def statement is inside a Python class definition.
1565 # assmt AssignmentNode Function construction/assignment
1567 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1571 num_required_kw_args = 0
1572 reqd_kw_flags_cname = "0"
1578 def __init__(self, pos, **kwds):
1579 FuncDefNode.__init__(self, pos, **kwds)
1581 for arg in self.args:
1588 self.num_kwonly_args = k
1589 self.num_required_kw_args = rk
1590 self.num_required_args = r
1592 def as_cfunction(self, cfunc=None, scope=None):
1594 error(self.star_arg.pos, "cdef function cannot have star argument")
1595 if self.starstar_arg:
1596 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1599 for formal_arg in self.args:
1600 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1601 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1603 type = py_object_type,
1604 pos = formal_arg.pos))
1605 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1607 has_varargs = False,
1608 exception_value = None,
1609 exception_check = False,
1612 is_overridable = True)
1613 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1615 cfunc_type = cfunc.type
1616 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1617 error(self.pos, "wrong number of arguments")
1618 error(declarator.pos, "previous declaration here")
1619 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1620 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1621 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1622 formal_arg.type = type_arg.type
1623 formal_arg.name_declarator = name_declarator
1625 if cfunc_type.exception_value is None:
1626 exception_value = None
1628 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1629 declarator = CFuncDeclaratorNode(self.pos,
1630 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1632 has_varargs = False,
1633 exception_check = cfunc_type.exception_check,
1634 exception_value = exception_value,
1635 with_gil = cfunc_type.with_gil,
1636 nogil = cfunc_type.nogil)
1637 return CFuncDefNode(self.pos,
1639 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1640 declarator = declarator,
1643 overridable = cfunc_type.is_overridable,
1645 with_gil = cfunc_type.with_gil,
1646 nogil = cfunc_type.nogil,
1647 visibility = 'private',
1649 directive_locals = cfunc.directive_locals)
1651 def analyse_declarations(self, env):
1652 if 'locals' in env.directives:
1653 directive_locals = env.directives['locals']
1655 directive_locals = {}
1656 self.directive_locals = directive_locals
1657 for arg in self.args:
1658 if hasattr(arg, 'name'):
1660 name_declarator = None
1662 base_type = arg.base_type.analyse(env)
1663 name_declarator, type = \
1664 arg.declarator.analyse(base_type, env)
1665 arg.name = name_declarator.name
1666 if arg.name in directive_locals:
1667 type_node = directive_locals[arg.name]
1668 other_type = type_node.analyse_as_type(env)
1669 if other_type is None:
1670 error(type_node.pos, "Not a type")
1671 elif (type is not PyrexTypes.py_object_type
1672 and not type.same_as(other_type)):
1673 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1674 error(type_node.pos, "Previous declaration here")
1677 if name_declarator and name_declarator.cname:
1679 "Python function argument cannot have C name specification")
1680 arg.type = type.as_argument_type()
1682 arg.needs_conversion = 0
1683 arg.needs_type_test = 0
1685 if arg.not_none and not arg.type.is_extension_type:
1687 "Only extension type arguments can have 'not None'")
1688 self.declare_pyfunction(env)
1689 self.analyse_signature(env)
1690 self.return_type = self.entry.signature.return_type()
1692 def analyse_signature(self, env):
1693 any_type_tests_needed = 0
1694 # Use the simpler calling signature for zero- and one-argument functions.
1695 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1696 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1697 if len(self.args) == 0:
1698 self.entry.signature = TypeSlots.pyfunction_noargs
1699 elif len(self.args) == 1:
1700 if self.args[0].default is None and not self.args[0].kw_only:
1701 self.entry.signature = TypeSlots.pyfunction_onearg
1702 elif self.entry.signature is TypeSlots.pymethod_signature:
1703 if len(self.args) == 1:
1704 self.entry.signature = TypeSlots.unaryfunc
1705 elif len(self.args) == 2:
1706 if self.args[1].default is None and not self.args[1].kw_only:
1707 self.entry.signature = TypeSlots.ibinaryfunc
1708 elif self.entry.is_special:
1709 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1710 sig = self.entry.signature
1711 nfixed = sig.num_fixed_args()
1712 for i in range(nfixed):
1713 if i < len(self.args):
1716 if sig.is_self_arg(i):
1718 arg.hdr_type = arg.type = env.parent_type
1719 arg.needs_conversion = 0
1721 arg.hdr_type = sig.fixed_arg_type(i)
1722 if not arg.type.same_as(arg.hdr_type):
1723 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1724 arg.needs_type_test = 1
1725 any_type_tests_needed = 1
1727 arg.needs_conversion = 1
1728 if arg.needs_conversion:
1729 arg.hdr_cname = Naming.arg_prefix + arg.name
1731 arg.hdr_cname = Naming.var_prefix + arg.name
1733 self.bad_signature()
1735 if nfixed < len(self.args):
1736 if not sig.has_generic_args:
1737 self.bad_signature()
1738 for arg in self.args:
1739 if arg.is_generic and \
1740 (arg.type.is_extension_type or arg.type.is_builtin_type):
1741 arg.needs_type_test = 1
1742 any_type_tests_needed = 1
1743 if any_type_tests_needed:
1744 env.use_utility_code(arg_type_test_utility_code)
1746 def bad_signature(self):
1747 sig = self.entry.signature
1748 expected_str = "%d" % sig.num_fixed_args()
1749 if sig.has_generic_args:
1750 expected_str = expected_str + " or more"
1752 if name.startswith("__") and name.endswith("__"):
1753 desc = "Special method"
1757 "%s %s has wrong number of arguments "
1758 "(%d declared, %s expected)" % (
1759 desc, self.name, len(self.args), expected_str))
1761 def signature_has_nongeneric_args(self):
1762 argcount = len(self.args)
1763 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1767 def signature_has_generic_args(self):
1768 return self.entry.signature.has_generic_args
1770 def declare_pyfunction(self, env):
1771 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1773 entry = env.lookup_here(self.name)
1774 if entry and entry.type.is_cfunction and not self.is_wrapper:
1775 warning(self.pos, "Overriding cdef method with def method.", 5)
1776 entry = env.declare_pyfunction(self.name, self.pos)
1778 prefix = env.scope_prefix
1779 entry.func_cname = \
1780 Naming.pyfunc_prefix + prefix + name
1781 entry.pymethdef_cname = \
1782 Naming.pymethdef_prefix + prefix + name
1783 if Options.docstrings:
1784 entry.doc = embed_position(self.pos, self.doc)
1786 Naming.funcdoc_prefix + prefix + name
1790 def declare_arguments(self, env):
1791 for arg in self.args:
1793 error(arg.pos, "Missing argument name")
1794 if arg.needs_conversion:
1795 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1796 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1797 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1798 if arg.type.is_pyobject:
1799 arg.entry.init = "0"
1800 arg.entry.init_to_none = 0
1802 arg.entry = self.declare_argument(env, arg)
1804 arg.entry.is_self_arg = arg.is_self_arg
1805 if not arg.is_self_arg:
1806 arg.name_entry = env.get_string_const(
1807 arg.name, identifier = True)
1808 env.add_py_string(arg.name_entry, identifier = True)
1810 if arg.is_self_arg or \
1811 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1812 arg.entry.is_declared_generic = 1
1813 self.declare_python_arg(env, self.star_arg)
1814 self.declare_python_arg(env, self.starstar_arg)
1816 def declare_python_arg(self, env, arg):
1818 entry = env.declare_var(arg.name,
1819 PyrexTypes.py_object_type, arg.pos)
1822 entry.init_to_none = 0
1823 entry.xdecref_cleanup = 1
1825 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1827 def analyse_expressions(self, env):
1828 self.local_scope.directives = env.directives
1829 self.analyse_default_values(env)
1830 if env.is_py_class_scope:
1831 self.synthesize_assignment_node(env)
1833 def synthesize_assignment_node(self, env):
1835 self.assmt = SingleAssignmentNode(self.pos,
1836 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1837 rhs = ExprNodes.UnboundMethodNode(self.pos,
1838 class_cname = env.class_obj_cname,
1839 function = ExprNodes.PyCFunctionNode(self.pos,
1840 pymethdef_cname = self.entry.pymethdef_cname)))
1841 self.assmt.analyse_declarations(env)
1842 self.assmt.analyse_expressions(env)
1844 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1846 sig = self.entry.signature
1847 if sig.has_dummy_arg:
1848 arg_code_list.append(
1849 "PyObject *%s" % Naming.self_cname)
1850 for arg in self.args:
1851 if not arg.is_generic:
1853 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1855 arg_code_list.append(
1856 arg.hdr_type.declaration_code(arg.hdr_cname))
1857 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1858 arg_code_list.append("PyObject *unused")
1859 if sig.has_generic_args:
1860 arg_code_list.append(
1861 "PyObject *%s, PyObject *%s"
1862 % (Naming.args_cname, Naming.kwds_cname))
1863 arg_code = ", ".join(arg_code_list)
1864 dc = self.return_type.declaration_code(self.entry.func_cname)
1865 header = "static %s(%s)" % (dc, arg_code)
1866 code.putln("%s; /*proto*/" % header)
1869 if self.entry.doc and Options.docstrings:
1870 docstr = self.entry.doc
1871 if not isinstance(docstr, str):
1872 docstr = docstr.utf8encode()
1874 'static char %s[] = "%s";' % (
1875 self.entry.doc_cname,
1876 split_docstring(escape_byte_string(docstr))))
1879 "static PyMethodDef %s = " %
1880 self.entry.pymethdef_cname)
1881 code.put_pymethoddef(self.entry, ";")
1882 code.putln("%s {" % header)
1884 def generate_argument_declarations(self, env, code):
1885 for arg in self.args:
1886 if arg.is_generic: # or arg.needs_conversion:
1887 if arg.needs_conversion:
1888 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1890 code.put_var_declaration(arg.entry)
1892 def generate_keyword_list(self, code):
1893 if self.signature_has_generic_args() and \
1894 self.signature_has_nongeneric_args():
1896 "static PyObject **%s[] = {" %
1897 Naming.pykwdlist_cname)
1898 for arg in self.args:
1900 code.put('&%s,' % arg.name_entry.pystring_cname)
1903 def generate_argument_parsing_code(self, env, code):
1904 # Generate PyArg_ParseTuple call for generic
1905 # arguments, if any.
1906 if self.entry.signature.has_dummy_arg:
1907 # get rid of unused argument warning
1908 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1910 old_error_label = code.new_error_label()
1911 our_error_label = code.error_label
1912 end_label = code.new_label("argument_unpacking_done")
1914 has_kwonly_args = self.num_kwonly_args > 0
1915 has_star_or_kw_args = self.star_arg is not None \
1916 or self.starstar_arg is not None or has_kwonly_args
1918 if not self.signature_has_generic_args():
1919 if has_star_or_kw_args:
1920 error(self.pos, "This method cannot have * or keyword arguments")
1921 self.generate_argument_conversion_code(code)
1923 elif not self.signature_has_nongeneric_args():
1924 # func(*args) or func(**kw) or func(*args, **kw)
1925 self.generate_stararg_copy_code(code)
1928 positional_args = []
1931 for arg in self.args:
1932 arg_entry = arg.entry
1936 if not arg.is_self_arg:
1938 kw_only_args.append(arg)
1940 positional_args.append(arg)
1942 kw_only_args.append(arg)
1945 error(arg.pos, "Non-default argument following default argument")
1946 elif not arg.is_self_arg:
1947 positional_args.append(arg)
1949 self.generate_tuple_and_keyword_parsing_code(
1950 positional_args, kw_only_args, end_label, code)
1952 code.error_label = old_error_label
1953 if code.label_used(our_error_label):
1954 if not code.label_used(end_label):
1955 code.put_goto(end_label)
1956 code.put_label(our_error_label)
1957 if has_star_or_kw_args:
1958 self.generate_arg_decref(self.star_arg, code)
1959 if self.starstar_arg:
1960 if self.starstar_arg.entry.xdecref_cleanup:
1961 code.put_var_xdecref(self.starstar_arg.entry)
1963 code.put_var_decref(self.starstar_arg.entry)
1964 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1965 code.putln("return %s;" % self.error_value())
1966 if code.label_used(end_label):
1967 code.put_label(end_label)
1969 def generate_arg_assignment(self, arg, item, code):
1970 if arg.type.is_pyobject:
1972 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1973 code.putln("%s = %s;" % (arg.entry.cname, item))
1975 func = arg.type.from_py_function
1977 code.putln("%s = %s(%s); %s" % (
1981 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1983 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1985 def generate_arg_xdecref(self, arg, code):
1987 code.put_var_xdecref(arg.entry)
1989 def generate_arg_decref(self, arg, code):
1991 code.put_var_decref(arg.entry)
1993 def generate_stararg_copy_code(self, code):
1994 if not self.star_arg:
1995 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1996 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1998 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1999 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2002 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2004 if self.starstar_arg:
2006 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2008 kwarg_check = "%s" % Naming.kwds_cname
2010 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2011 Naming.kwds_cname, Naming.kwds_cname)
2013 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2014 kwarg_check, Naming.kwds_cname, self.name,
2015 bool(self.starstar_arg), self.error_value()))
2017 if self.starstar_arg:
2018 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2019 self.starstar_arg.entry.cname,
2022 code.putln("if (unlikely(!%s)) return %s;" % (
2023 self.starstar_arg.entry.cname, self.error_value()))
2024 self.starstar_arg.entry.xdecref_cleanup = 0
2025 code.put_gotref(self.starstar_arg.entry.cname)
2029 code.put_incref(Naming.args_cname, py_object_type)
2030 code.putln("%s = %s;" % (
2031 self.star_arg.entry.cname,
2033 self.star_arg.entry.xdecref_cleanup = 0
2035 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2036 kw_only_args, success_label, code):
2037 argtuple_error_label = code.new_label("argtuple_error")
2039 min_positional_args = self.num_required_args - self.num_required_kw_args
2040 if len(self.args) > 0 and self.args[0].is_self_arg:
2041 min_positional_args -= 1
2042 max_positional_args = len(positional_args)
2043 has_fixed_positional_count = not self.star_arg and \
2044 min_positional_args == max_positional_args
2046 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2047 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2048 if self.num_required_kw_args:
2049 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2051 if self.starstar_arg or self.star_arg:
2052 self.generate_stararg_init_code(max_positional_args, code)
2054 # --- optimised code when we receive keyword arguments
2055 if self.num_required_kw_args:
2056 likely_hint = "likely"
2058 likely_hint = "unlikely"
2059 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2060 self.generate_keyword_unpacking_code(
2061 min_positional_args, max_positional_args,
2062 has_fixed_positional_count,
2063 positional_args, kw_only_args, argtuple_error_label, code)
2065 # --- optimised code when we do not receive any keyword arguments
2066 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2067 # Python raises arg tuple related errors first, so we must
2068 # check the length here
2069 if min_positional_args == max_positional_args and not self.star_arg:
2073 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2074 Naming.args_cname, compare, min_positional_args))
2075 code.put_goto(argtuple_error_label)
2077 if self.num_required_kw_args:
2078 # pure error case: keywords required but not passed
2079 if max_positional_args > min_positional_args and not self.star_arg:
2080 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2081 Naming.args_cname, max_positional_args))
2082 code.put_goto(argtuple_error_label)
2083 code.putln('} else {')
2084 for i, arg in enumerate(kw_only_args):
2086 # required keyword-only argument missing
2087 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2088 self.name.utf8encode(),
2089 arg.name_entry.pystring_cname))
2090 code.putln(code.error_goto(self.pos))
2093 elif min_positional_args == max_positional_args:
2094 # parse the exact number of positional arguments from the
2096 code.putln('} else {')
2097 for i, arg in enumerate(positional_args):
2098 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2099 self.generate_arg_assignment(arg, item, code)
2100 self.generate_arg_default_assignments(code)
2103 # parse the positional arguments from the variable length
2105 code.putln('} else {')
2106 self.generate_arg_default_assignments(code)
2107 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2109 code.putln('default:')
2110 reversed_args = list(enumerate(positional_args))[::-1]
2111 for i, arg in reversed_args:
2112 if i >= min_positional_args-1:
2113 if min_positional_args > 1:
2114 code.putln('case %2d:' % (i+1)) # pure code beautification
2116 code.put('case %2d: ' % (i+1))
2117 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2118 self.generate_arg_assignment(arg, item, code)
2119 if min_positional_args == 0:
2120 code.put('case 0: ')
2121 code.putln('break;')
2123 if min_positional_args:
2124 for i in range(min_positional_args-1, -1, -1):
2125 code.putln('case %2d:' % i)
2126 code.put_goto(argtuple_error_label)
2128 code.put('default: ')
2129 code.put_goto(argtuple_error_label)
2134 if code.label_used(argtuple_error_label):
2135 code.put_goto(success_label)
2136 code.put_label(argtuple_error_label)
2137 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2138 self.name.utf8encode(), has_fixed_positional_count,
2139 min_positional_args, max_positional_args,
2141 code.putln(code.error_goto(self.pos))
2143 def generate_arg_default_assignments(self, code):
2144 for arg in self.args:
2145 if arg.is_generic and arg.default:
2149 arg.default_result_code))
2151 def generate_stararg_init_code(self, max_positional_args, code):
2152 if self.starstar_arg:
2153 self.starstar_arg.entry.xdecref_cleanup = 0
2154 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2155 self.starstar_arg.entry.cname,
2156 self.starstar_arg.entry.cname,
2157 self.error_value()))
2158 code.put_gotref(self.starstar_arg.entry.cname)
2160 self.star_arg.entry.xdecref_cleanup = 0
2161 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2163 max_positional_args))
2164 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2165 self.star_arg.entry.cname, Naming.args_cname,
2166 max_positional_args, Naming.args_cname))
2167 code.put_gotref(self.star_arg.entry.cname)
2168 if self.starstar_arg:
2170 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2171 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2172 code.putln('return %s;' % self.error_value())
2175 code.putln("if (unlikely(!%s)) return %s;" % (
2176 self.star_arg.entry.cname, self.error_value()))
2177 code.putln('} else {')
2178 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2179 code.put_incref(Naming.empty_tuple, py_object_type)
2182 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2183 has_fixed_positional_count, positional_args,
2184 kw_only_args, argtuple_error_label, code):
2185 all_args = tuple(positional_args) + tuple(kw_only_args)
2186 max_args = len(all_args)
2189 for i, arg in enumerate(all_args):
2190 if arg.default and arg.type.is_pyobject:
2191 default_value = arg.default_result_code
2192 if arg.type is not PyrexTypes.py_object_type:
2193 default_value = "(PyObject*)"+default_value
2194 default_args.append((i, default_value))
2196 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2198 # it looks funny to separate the init-to-0 from setting the
2199 # default value, but C89 needs this
2200 code.putln("PyObject* values[%d] = {%s};" % (
2201 max_args, ','.join(['0']*max_args)))
2202 for i, default_value in default_args:
2203 code.putln('values[%d] = %s;' % (i, default_value))
2205 # parse the tuple and check that it's not too long
2206 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2208 code.putln('default:')
2209 for i in range(max_positional_args-1, -1, -1):
2210 code.put('case %2d: ' % (i+1))
2211 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2212 i, Naming.args_cname, i))
2213 code.putln('case 0: break;')
2214 if not self.star_arg:
2215 code.put('default: ') # more arguments than allowed
2216 code.put_goto(argtuple_error_label)
2219 # now fill up the positional/required arguments with values
2221 if self.num_required_args or max_positional_args > 0:
2222 last_required_arg = -1
2223 for i, arg in enumerate(all_args):
2225 last_required_arg = i
2226 if last_required_arg < max_positional_args:
2227 last_required_arg = max_positional_args-1
2228 num_required_args = self.num_required_args
2229 if max_positional_args > 0:
2230 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2231 for i, arg in enumerate(all_args[:last_required_arg+1]):
2232 if max_positional_args > 0 and i <= max_positional_args:
2233 if self.star_arg and i == max_positional_args:
2234 code.putln('default:')
2236 code.putln('case %2d:' % i)
2239 # handled separately below
2241 code.putln('if (kw_args > %d) {' % num_required_args)
2242 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2243 Naming.kwds_cname, arg.name_entry.pystring_cname))
2244 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2247 num_required_args -= 1
2248 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2249 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2250 code.putln('if (likely(values[%d])) kw_args--;' % i);
2251 if i < min_positional_args:
2253 # special case: we know arg 0 is missing
2255 code.put_goto(argtuple_error_label)
2257 # print the correct number of values (args or
2258 # kwargs) that were passed into positional
2259 # arguments up to this point
2260 code.putln('else {')
2261 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2262 self.name.utf8encode(), has_fixed_positional_count,
2263 min_positional_args, max_positional_args, i))
2264 code.putln(code.error_goto(self.pos))
2267 code.putln('else {')
2268 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2269 self.name.utf8encode(), arg.name_entry.pystring_cname))
2270 code.putln(code.error_goto(self.pos))
2272 if max_positional_args > 0:
2275 if kw_only_args and not self.starstar_arg:
2276 # unpack optional keyword-only arguments
2277 # checking for interned strings in a dict is faster than iterating
2278 # but it's too likely that we must iterate if we expect **kwargs
2280 for i, arg in enumerate(all_args[max_positional_args:]):
2281 if not arg.kw_only or not arg.default:
2283 optional_args.append((i+max_positional_args, arg))
2285 # this mimics an unrolled loop so that we can "break" out of it
2286 code.putln('while (kw_args > 0) {')
2287 code.putln('PyObject* value;')
2288 for i, arg in optional_args:
2290 'value = PyDict_GetItem(%s, %s);' % (
2291 Naming.kwds_cname, arg.name_entry.pystring_cname))
2293 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2294 code.putln('break;')
2297 code.putln('if (unlikely(kw_args > 0)) {')
2298 # non-positional/-required kw args left in dict: default args,
2299 # kw-only args, **kwargs or error
2301 # This is sort of a catch-all: except for checking required
2302 # arguments, this will always do the right thing for unpacking
2303 # keyword arguments, so that we can concentrate on optimising
2304 # common cases above.
2305 if max_positional_args == 0:
2308 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2309 Naming.args_cname, max_positional_args,
2310 Naming.args_cname, max_positional_args))
2311 pos_arg_count = "used_pos_args"
2313 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2314 code.globalstate.use_utility_code(parse_keywords_utility_code)
2316 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2318 Naming.pykwdlist_cname,
2319 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2321 self.name.utf8encode()))
2322 code.putln(code.error_goto(self.pos))
2325 # convert arg values to their final type and assign them
2326 for i, arg in enumerate(all_args):
2327 if arg.default and not arg.type.is_pyobject:
2328 code.putln("if (values[%d]) {" % i)
2329 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2330 if arg.default and not arg.type.is_pyobject:
2331 code.putln('} else {')
2335 arg.default_result_code))
2338 def generate_argument_conversion_code(self, code):
2339 # Generate code to convert arguments from
2340 # signature type to declared type, if needed.
2341 for arg in self.args:
2342 if arg.needs_conversion:
2343 self.generate_arg_conversion(arg, code)
2345 def generate_arg_conversion(self, arg, code):
2346 # Generate conversion code for one argument.
2347 old_type = arg.hdr_type
2349 if old_type.is_pyobject:
2351 code.putln("if (%s) {" % arg.hdr_cname)
2353 code.putln("assert(%s); {" % arg.hdr_cname)
2354 self.generate_arg_conversion_from_pyobject(arg, code)
2356 elif new_type.is_pyobject:
2357 self.generate_arg_conversion_to_pyobject(arg, code)
2359 if new_type.assignable_from(old_type):
2361 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2364 "Cannot convert 1 argument from '%s' to '%s'" %
2365 (old_type, new_type))
2367 def generate_arg_conversion_from_pyobject(self, arg, code):
2369 func = new_type.from_py_function
2370 # copied from CoerceFromPyTypeNode
2372 code.putln("%s = %s(%s); %s" % (
2376 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2379 "Cannot convert Python object argument to type '%s'"
2382 def generate_arg_conversion_to_pyobject(self, arg, code):
2383 old_type = arg.hdr_type
2384 func = old_type.to_py_function
2386 code.putln("%s = %s(%s); %s" % (
2390 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2391 code.put_var_gotref(arg.entry)
2394 "Cannot convert argument of type '%s' to Python object"
2397 def generate_argument_type_tests(self, code):
2398 # Generate type tests for args whose signature
2399 # type is PyObject * and whose declared type is
2400 # a subtype thereof.
2401 for arg in self.args:
2402 if arg.needs_type_test:
2403 self.generate_arg_type_test(arg, code)
2405 def generate_arg_type_test(self, arg, code):
2406 # Generate type test for one argument.
2407 if arg.type.typeobj_is_available():
2408 typeptr_cname = arg.type.typeptr_cname
2409 arg_code = "((PyObject *)%s)" % arg.entry.cname
2411 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2416 arg.type.is_builtin_type,
2417 code.error_goto(arg.pos)))
2419 error(arg.pos, "Cannot test type of extern C class "
2420 "without type object name specification")
2422 def error_value(self):
2423 return self.entry.signature.error_value
2425 def caller_will_check_exceptions(self):
2428 class OverrideCheckNode(StatNode):
2429 # A Node for dispatching to the def method if it
2438 child_attrs = ['body']
2442 def analyse_expressions(self, env):
2443 self.args = env.arg_entries
2444 if self.py_func.is_module_scope:
2449 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2450 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2451 call_node = ExprNodes.SimpleCallNode(self.pos,
2452 function=self.func_node,
2453 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2454 self.body = ReturnStatNode(self.pos, value=call_node)
2455 self.body.analyse_expressions(env)
2457 def generate_execution_code(self, code):
2458 # Check to see if we are an extension type
2459 if self.py_func.is_module_scope:
2460 self_arg = "((PyObject *)%s)" % Naming.module_cname
2462 self_arg = "((PyObject *)%s)" % self.args[0].cname
2463 code.putln("/* Check if called by wrapper */")
2464 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2465 code.putln("/* Check if overriden in Python */")
2466 if self.py_func.is_module_scope:
2467 code.putln("else {")
2469 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2470 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2471 # need to get attribute manually--scope would return cdef method
2472 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2473 code.put_gotref(self.func_node.py_result())
2474 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2475 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2476 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2477 self.body.generate_execution_code(code)
2479 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2482 class ClassDefNode(StatNode, BlockNode):
2485 class PyClassDefNode(ClassDefNode):
2486 # A Python class definition.
2488 # name EncodedString Name of the class
2489 # doc string or None
2490 # body StatNode Attribute definition code
2491 # entry Symtab.Entry
2492 # scope PyClassScope
2494 # The following subnodes are constructed internally:
2496 # dict DictNode Class dictionary
2497 # classobj ClassNode Class object
2498 # target NameNode Variable to assign class object to
2500 child_attrs = ["body", "dict", "classobj", "target"]
2502 def __init__(self, pos, name, bases, doc, body):
2503 StatNode.__init__(self, pos)
2508 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2509 if self.doc and Options.docstrings:
2510 doc = embed_position(self.pos, self.doc)
2511 doc_node = ExprNodes.StringNode(pos, value = doc)
2514 self.classobj = ExprNodes.ClassNode(pos, name = name,
2515 bases = bases, dict = self.dict, doc = doc_node)
2516 self.target = ExprNodes.NameNode(pos, name = name)
2518 def as_cclass(self):
2520 Return this node as if it were declared as an extension class
2522 bases = self.classobj.bases.args
2524 base_class_name = None
2525 base_class_module = None
2526 elif len(bases) == 1:
2529 from ExprNodes import AttributeNode, NameNode
2530 while isinstance(base, AttributeNode):
2531 path.insert(0, base.attribute)
2533 if isinstance(base, NameNode):
2534 path.insert(0, base.name)
2535 base_class_name = path[-1]
2537 base_class_module = u'.'.join(path[:-1])
2539 base_class_module = None
2541 error(self.classobj.bases.args.pos, "Invalid base class")
2543 error(self.classobj.bases.args.pos, "C class may only have one base class")
2546 return CClassDefNode(self.pos,
2547 visibility = 'private',
2549 class_name = self.name,
2550 base_class_module = base_class_module,
2551 base_class_name = base_class_name,
2556 def create_scope(self, env):
2558 while env.is_py_class_scope or env.is_c_class_scope:
2559 env = env.outer_scope
2560 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2563 def analyse_declarations(self, env):
2564 self.target.analyse_target_declaration(env)
2565 cenv = self.create_scope(env)
2566 cenv.class_obj_cname = self.target.entry.cname
2567 self.body.analyse_declarations(cenv)
2569 def analyse_expressions(self, env):
2570 self.dict.analyse_expressions(env)
2571 self.classobj.analyse_expressions(env)
2572 genv = env.global_scope()
2574 cenv.class_dict_cname = self.dict.result()
2575 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2576 self.body.analyse_expressions(cenv)
2577 self.target.analyse_target_expression(env, self.classobj)
2578 self.dict.release_temp(env)
2579 #self.classobj.release_temp(env)
2580 #self.target.release_target_temp(env)
2582 def generate_function_definitions(self, env, code):
2583 self.generate_py_string_decls(self.scope, code)
2584 self.body.generate_function_definitions(self.scope, code)
2586 def generate_execution_code(self, code):
2587 self.dict.generate_evaluation_code(code)
2588 self.classobj.generate_evaluation_code(code)
2589 self.body.generate_execution_code(code)
2590 self.target.generate_assignment_code(self.classobj, code)
2591 self.dict.generate_disposal_code(code)
2592 self.dict.free_temps(code)
2595 class CClassDefNode(ClassDefNode):
2596 # An extension type definition.
2598 # visibility 'private' or 'public' or 'extern'
2599 # typedef_flag boolean
2601 # module_name string or None For import of extern type objects
2602 # class_name string Unqualified name of class
2603 # as_name string or None Name to declare as in this scope
2604 # base_class_module string or None Module containing the base class
2605 # base_class_name string or None Name of the base class
2606 # objstruct_name string or None Specified C name of object struct
2607 # typeobj_name string or None Specified C name of type object
2608 # in_pxd boolean Is in a .pxd file
2609 # doc string or None
2610 # body StatNode or None
2611 # entry Symtab.Entry
2612 # base_type PyExtensionType or None
2613 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2614 # buffer_defaults_pos
2616 child_attrs = ["body"]
2617 buffer_defaults_node = None
2618 buffer_defaults_pos = None
2619 typedef_flag = False
2621 objstruct_name = None
2624 def analyse_declarations(self, env):
2625 #print "CClassDefNode.analyse_declarations:", self.class_name
2626 #print "...visibility =", self.visibility
2627 #print "...module_name =", self.module_name
2630 if self.buffer_defaults_node:
2631 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2632 env, [], self.buffer_defaults_node,
2633 need_complete=False)
2635 buffer_defaults = None
2637 if env.in_cinclude and not self.objstruct_name:
2638 error(self.pos, "Object struct name specification required for "
2639 "C class defined in 'extern from' block")
2640 self.base_type = None
2641 # Now that module imports are cached, we need to
2642 # import the modules for extern classes.
2643 if self.module_name:
2645 for module in env.cimported_modules:
2646 if module.name == self.module_name:
2647 self.module = module
2648 if self.module is None:
2649 self.module = ModuleScope(self.module_name, None, env.context)
2650 self.module.has_extern_class = 1
2651 env.add_imported_module(self.module)
2653 if self.base_class_name:
2654 if self.base_class_module:
2655 base_class_scope = env.find_module(self.base_class_module, self.pos)
2657 base_class_scope = env
2658 if self.base_class_name == 'object':
2659 # extension classes are special and don't need to inherit from object
2660 if base_class_scope is None or base_class_scope.lookup('object') is None:
2661 self.base_class_name = None
2662 self.base_class_module = None
2663 base_class_scope = None
2664 if base_class_scope:
2665 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2666 if base_class_entry:
2667 if not base_class_entry.is_type:
2668 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2669 elif not base_class_entry.type.is_extension_type:
2670 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2671 elif not base_class_entry.type.is_complete():
2672 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2674 self.base_type = base_class_entry.type
2675 has_body = self.body is not None
2676 if self.module_name and self.visibility != 'extern':
2677 module_path = self.module_name.split(".")
2678 home_scope = env.find_imported_module(module_path, self.pos)
2684 if self.visibility == 'extern':
2685 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2686 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2688 self.entry = home_scope.declare_c_class(
2689 name = self.class_name,
2691 defining = has_body and self.in_pxd,
2692 implementing = has_body and not self.in_pxd,
2693 module_name = self.module_name,
2694 base_type = self.base_type,
2695 objstruct_cname = self.objstruct_name,
2696 typeobj_cname = self.typeobj_name,
2697 visibility = self.visibility,
2698 typedef_flag = self.typedef_flag,
2700 buffer_defaults = buffer_defaults)
2701 if home_scope is not env and self.visibility == 'extern':
2702 env.add_imported_entry(self.class_name, self.entry, pos)
2703 scope = self.entry.type.scope
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 self.body.analyse_declarations(entry.scope)
2756 def analyse_expressions(self, env):
2757 self.body.analyse_expressions(env)
2759 def generate_function_definitions(self, env, code):
2760 self.body.generate_function_definitions(env, code)
2762 def generate_execution_code(self, code):
2765 def annotate(self, code):
2766 self.body.annotate(code)
2769 class GlobalNode(StatNode):
2770 # Global variable declaration.
2776 def analyse_declarations(self, env):
2777 for name in self.names:
2778 env.declare_global(name, self.pos)
2780 def analyse_expressions(self, env):
2783 def generate_execution_code(self, code):
2787 class ExprStatNode(StatNode):
2788 # Expression used as a statement.
2792 child_attrs = ["expr"]
2794 def analyse_declarations(self, env):
2796 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2797 func = self.expr.function.as_cython_attribute()
2798 if func == u'declare':
2799 args, kwds = self.expr.explicit_args_kwds()
2801 error(self.expr.pos, "Variable names must be specified.")
2802 for var, type_node in kwds.key_value_pairs:
2803 type = type_node.analyse_as_type(env)
2805 error(type_node.pos, "Unknown type")
2807 env.declare_var(var.value, type, var.pos, is_cdef = True)
2808 self.__class__ = PassStatNode
2810 def analyse_expressions(self, env):
2811 self.expr.analyse_expressions(env)
2812 self.expr.release_temp(env)
2814 def generate_execution_code(self, code):
2815 self.expr.generate_evaluation_code(code)
2816 if not self.expr.is_temp and self.expr.result():
2817 code.putln("%s;" % self.expr.result())
2818 self.expr.generate_disposal_code(code)
2819 self.expr.free_temps(code)
2821 def annotate(self, code):
2822 self.expr.annotate(code)
2825 class AssignmentNode(StatNode):
2826 # Abstract base class for assignment nodes.
2828 # The analyse_expressions and generate_execution_code
2829 # phases of assignments are split into two sub-phases
2830 # each, to enable all the right hand sides of a
2831 # parallel assignment to be evaluated before assigning
2832 # to any of the left hand sides.
2834 def analyse_expressions(self, env):
2835 self.analyse_types(env)
2836 self.allocate_rhs_temps(env)
2837 self.allocate_lhs_temps(env)
2839 # def analyse_expressions(self, env):
2840 # self.analyse_expressions_1(env)
2841 # self.analyse_expressions_2(env)
2843 def generate_execution_code(self, code):
2844 self.generate_rhs_evaluation_code(code)
2845 self.generate_assignment_code(code)
2848 class SingleAssignmentNode(AssignmentNode):
2849 # The simplest case:
2853 # lhs ExprNode Left hand side
2854 # rhs ExprNode Right hand side
2855 # first bool Is this guaranteed the first assignment to lhs?
2857 child_attrs = ["lhs", "rhs"]
2859 declaration_only = False
2861 def analyse_declarations(self, env):
2864 # handle declarations of the form x = cython.foo()
2865 if isinstance(self.rhs, ExprNodes.CallNode):
2866 func_name = self.rhs.function.as_cython_attribute()
2868 args, kwds = self.rhs.explicit_args_kwds()
2870 if func_name in ['declare', 'typedef']:
2871 if len(args) > 2 or kwds is not None:
2872 error(rhs.pos, "Can only declare one type at a time.")
2874 type = args[0].analyse_as_type(env)
2876 error(args[0].pos, "Unknown type")
2879 if func_name == 'declare':
2880 if isinstance(lhs, ExprNodes.NameNode):
2881 vars = [(lhs.name, lhs.pos)]
2882 elif isinstance(lhs, ExprNodes.TupleNode):
2883 vars = [(var.name, var.pos) for var in lhs.args]
2885 error(lhs.pos, "Invalid declaration")
2887 for var, pos in vars:
2888 env.declare_var(var, type, pos, is_cdef = True)
2893 self.declaration_only = True
2895 self.declaration_only = True
2896 if not isinstance(lhs, ExprNodes.NameNode):
2897 error(lhs.pos, "Invalid declaration.")
2898 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2900 elif func_name in ['struct', 'union']:
2901 self.declaration_only = True
2902 if len(args) > 0 or kwds is None:
2903 error(rhs.pos, "Struct or union members must be given by name.")
2906 for member, type_node in kwds.key_value_pairs:
2907 type = type_node.analyse_as_type(env)
2909 error(type_node.pos, "Unknown type")
2911 members.append((member.value, type, member.pos))
2912 if len(members) < len(kwds.key_value_pairs):
2914 if not isinstance(self.lhs, ExprNodes.NameNode):
2915 error(self.lhs.pos, "Invalid declaration.")
2916 name = self.lhs.name
2917 scope = StructOrUnionScope(name)
2918 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2919 for member, type, pos in members:
2920 scope.declare_var(member, type, pos)
2922 if self.declaration_only:
2925 self.lhs.analyse_target_declaration(env)
2927 def analyse_types(self, env, use_temp = 0):
2928 self.rhs.analyse_types(env)
2929 self.lhs.analyse_target_types(env)
2930 self.lhs.gil_assignment_check(env)
2931 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2933 self.rhs = self.rhs.coerce_to_temp(env)
2935 def allocate_rhs_temps(self, env):
2936 self.rhs.allocate_temps(env)
2938 def allocate_lhs_temps(self, env):
2939 self.lhs.allocate_target_temps(env, self.rhs)
2940 #self.lhs.release_target_temp(env)
2941 #self.rhs.release_temp(env)
2943 def generate_rhs_evaluation_code(self, code):
2944 self.rhs.generate_evaluation_code(code)
2946 def generate_assignment_code(self, code):
2947 self.lhs.generate_assignment_code(self.rhs, code)
2949 def annotate(self, code):
2950 self.lhs.annotate(code)
2951 self.rhs.annotate(code)
2954 class CascadedAssignmentNode(AssignmentNode):
2955 # An assignment with multiple left hand sides:
2959 # lhs_list [ExprNode] Left hand sides
2960 # rhs ExprNode Right hand sides
2964 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2966 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2967 coerced_rhs_list = None
2969 def analyse_declarations(self, env):
2970 for lhs in self.lhs_list:
2971 lhs.analyse_target_declaration(env)
2973 def analyse_types(self, env, use_temp = 0):
2974 self.rhs.analyse_types(env)
2976 self.rhs = self.rhs.coerce_to_temp(env)
2978 self.rhs = self.rhs.coerce_to_simple(env)
2979 from ExprNodes import CloneNode
2980 self.coerced_rhs_list = []
2981 for lhs in self.lhs_list:
2982 lhs.analyse_target_types(env)
2983 lhs.gil_assignment_check(env)
2984 rhs = CloneNode(self.rhs)
2985 rhs = rhs.coerce_to(lhs.type, env)
2986 self.coerced_rhs_list.append(rhs)
2988 def allocate_rhs_temps(self, env):
2989 self.rhs.allocate_temps(env)
2991 def allocate_lhs_temps(self, env):
2992 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2993 rhs.allocate_temps(env)
2994 lhs.allocate_target_temps(env, rhs)
2995 #lhs.release_target_temp(env)
2996 #rhs.release_temp(env)
2997 self.rhs.release_temp(env)
2999 def generate_rhs_evaluation_code(self, code):
3000 self.rhs.generate_evaluation_code(code)
3002 def generate_assignment_code(self, code):
3003 for i in range(len(self.lhs_list)):
3004 lhs = self.lhs_list[i]
3005 rhs = self.coerced_rhs_list[i]
3006 rhs.generate_evaluation_code(code)
3007 lhs.generate_assignment_code(rhs, code)
3008 # Assignment has disposed of the cloned RHS
3009 self.rhs.generate_disposal_code(code)
3010 self.rhs.free_temps(code)
3012 def annotate(self, code):
3013 for i in range(len(self.lhs_list)):
3014 lhs = self.lhs_list[i].annotate(code)
3015 rhs = self.coerced_rhs_list[i].annotate(code)
3016 self.rhs.annotate(code)
3019 class ParallelAssignmentNode(AssignmentNode):
3020 # A combined packing/unpacking assignment:
3024 # This has been rearranged by the parser into
3026 # a = d ; b = e ; c = f
3028 # but we must evaluate all the right hand sides
3029 # before assigning to any of the left hand sides.
3031 # stats [AssignmentNode] The constituent assignments
3033 child_attrs = ["stats"]
3035 def analyse_declarations(self, env):
3036 for stat in self.stats:
3037 stat.analyse_declarations(env)
3039 def analyse_expressions(self, env):
3040 for stat in self.stats:
3041 stat.analyse_types(env, use_temp = 1)
3042 stat.allocate_rhs_temps(env)
3043 for stat in self.stats:
3044 stat.allocate_lhs_temps(env)
3046 # def analyse_expressions(self, env):
3047 # for stat in self.stats:
3048 # stat.analyse_expressions_1(env, use_temp = 1)
3049 # for stat in self.stats:
3050 # stat.analyse_expressions_2(env)
3052 def generate_execution_code(self, code):
3053 for stat in self.stats:
3054 stat.generate_rhs_evaluation_code(code)
3055 for stat in self.stats:
3056 stat.generate_assignment_code(code)
3058 def annotate(self, code):
3059 for stat in self.stats:
3063 class InPlaceAssignmentNode(AssignmentNode):
3064 # An in place arithmatic operand:
3070 # lhs ExprNode Left hand side
3071 # rhs ExprNode Right hand side
3072 # op char one of "+-*/%^&|"
3073 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3075 # This code is a bit tricky because in order to obey Python
3076 # semantics the sub-expressions (e.g. indices) of the lhs must
3077 # not be evaluated twice. So we must re-use the values calculated
3078 # in evaluation phase for the assignment phase as well.
3079 # Fortunately, the type of the lhs node is fairly constrained
3080 # (it must be a NameNode, AttributeNode, or IndexNode).
3082 child_attrs = ["lhs", "rhs"]
3085 def analyse_declarations(self, env):
3086 self.lhs.analyse_target_declaration(env)
3088 def analyse_types(self, env):
3089 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3090 self.rhs.analyse_types(env)
3091 self.lhs.analyse_target_types(env)
3092 if Options.incref_local_binop and self.dup.type.is_pyobject:
3093 self.dup = self.dup.coerce_to_temp(env)
3095 def allocate_rhs_temps(self, env):
3097 if self.lhs.type.is_pyobject:
3098 self.rhs = self.rhs.coerce_to_pyobject(env)
3099 elif self.rhs.type.is_pyobject:
3100 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3101 if self.lhs.type.is_pyobject:
3102 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3103 self.result_value.allocate_temps(env)
3105 # self.rhs = self.rhs.coerce_to_temp(env)
3106 self.rhs.allocate_temps(env)
3107 self.dup.allocate_subexpr_temps(env)
3108 self.dup.allocate_temp(env)
3110 def allocate_lhs_temps(self, env):
3111 self.lhs.allocate_target_temps(env, self.rhs)
3112 # self.lhs.release_target_temp(env)
3113 self.dup.release_temp(env)
3114 if self.dup.is_temp:
3115 self.dup.release_subexpr_temps(env)
3116 # self.rhs.release_temp(env)
3117 if self.lhs.type.is_pyobject:
3118 self.result_value.release_temp(env)
3120 def generate_execution_code(self, code):
3122 self.rhs.generate_evaluation_code(code)
3123 self.dup.generate_subexpr_evaluation_code(code)
3124 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3125 # This is because we're manually messing with subexpr nodes
3126 if self.dup.is_temp:
3127 self.dup.allocate_temp_result(code)
3128 # self.dup.generate_result_code is run only if it is not buffer access
3129 if self.operator == "**":
3133 if self.lhs.type.is_pyobject:
3134 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3135 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3136 self.dup.generate_result_code(code)
3138 "%s = %s(%s, %s%s); %s" % (
3139 self.result_value.result(),
3140 self.py_operation_function(),
3141 self.dup.py_result(),
3142 self.rhs.py_result(),
3144 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3145 code.put_gotref(self.result_value.py_result())
3146 self.result_value.generate_evaluation_code(code) # May be a type check...
3147 self.rhs.generate_disposal_code(code)
3148 self.rhs.free_temps(code)
3149 self.dup.generate_disposal_code(code)
3150 self.dup.free_temps(code)
3151 self.lhs.generate_assignment_code(self.result_value, code)
3153 c_op = self.operator
3157 if self.lhs.type.is_int and self.rhs.type.is_int:
3158 error(self.pos, "** with two C int types is ambiguous")
3160 error(self.pos, "No C inplace power operator")
3161 # have to do assignment directly to avoid side-effects
3162 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3163 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3165 self.dup.generate_result_code(code)
3166 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3167 self.rhs.generate_disposal_code(code)
3168 self.rhs.free_temps(code)
3169 if self.dup.is_temp:
3170 self.dup.generate_subexpr_disposal_code(code)
3171 self.dup.free_subexpr_temps(code)
3173 def create_dup_node(self, env):
3176 self.dup.analyse_types(env)
3177 if isinstance(self.lhs, ExprNodes.NameNode):
3178 target_lhs = ExprNodes.NameNode(self.dup.pos,
3179 name = self.dup.name,
3180 is_temp = self.dup.is_temp,
3181 entry = self.dup.entry)
3182 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3183 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3184 obj = ExprNodes.CloneNode(self.lhs.obj),
3185 attribute = self.dup.attribute,
3186 is_temp = self.dup.is_temp)
3187 elif isinstance(self.lhs, ExprNodes.IndexNode):
3189 index = ExprNodes.CloneNode(self.lhs.index)
3192 if self.lhs.indices:
3193 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3196 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3197 base = ExprNodes.CloneNode(self.dup.base),
3200 is_temp = self.dup.is_temp)
3203 self.lhs = target_lhs
3206 def py_operation_function(self):
3207 return self.py_functions[self.operator]
3210 "|": "PyNumber_InPlaceOr",
3211 "^": "PyNumber_InPlaceXor",
3212 "&": "PyNumber_InPlaceAnd",
3213 "+": "PyNumber_InPlaceAdd",
3214 "-": "PyNumber_InPlaceSubtract",
3215 "*": "PyNumber_InPlaceMultiply",
3216 "/": "PyNumber_InPlaceDivide",
3217 "%": "PyNumber_InPlaceRemainder",
3218 "<<": "PyNumber_InPlaceLshift",
3219 ">>": "PyNumber_InPlaceRshift",
3220 "**": "PyNumber_InPlacePower",
3221 "//": "PyNumber_InPlaceFloorDivide",
3224 def annotate(self, code):
3225 self.lhs.annotate(code)
3226 self.rhs.annotate(code)
3227 self.dup.annotate(code)
3230 class PrintStatNode(StatNode):
3233 # arg_tuple TupleNode
3234 # append_newline boolean
3236 child_attrs = ["arg_tuple"]
3238 def analyse_expressions(self, env):
3239 self.arg_tuple.analyse_expressions(env)
3240 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3241 self.arg_tuple.release_temp(env)
3242 env.use_utility_code(printing_utility_code)
3243 if len(self.arg_tuple.args) == 1 and self.append_newline:
3244 env.use_utility_code(printing_one_utility_code)
3247 gil_message = "Python print statement"
3249 def generate_execution_code(self, code):
3250 if len(self.arg_tuple.args) == 1 and self.append_newline:
3251 arg = self.arg_tuple.args[0]
3252 arg.generate_evaluation_code(code)
3255 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3257 code.error_goto(self.pos)))
3258 arg.generate_disposal_code(code)
3259 arg.free_temps(code)
3261 self.arg_tuple.generate_evaluation_code(code)
3263 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3264 self.arg_tuple.py_result(),
3265 self.append_newline,
3266 code.error_goto(self.pos)))
3267 self.arg_tuple.generate_disposal_code(code)
3268 self.arg_tuple.free_temps(code)
3270 def annotate(self, code):
3271 self.arg_tuple.annotate(code)
3274 class ExecStatNode(StatNode):
3279 child_attrs = ["args"]
3281 def analyse_expressions(self, env):
3282 for i, arg in enumerate(self.args):
3283 arg.analyse_expressions(env)
3284 arg = arg.coerce_to_pyobject(env)
3285 arg.release_temp(env)
3287 self.temp_result = env.allocate_temp_pyobject()
3288 env.release_temp(self.temp_result)
3289 env.use_utility_code(Builtin.pyexec_utility_code)
3292 gil_message = "Python exec statement"
3294 def generate_execution_code(self, code):
3296 for arg in self.args:
3297 arg.generate_evaluation_code(code)
3298 args.append( arg.py_result() )
3299 args = tuple(args + ['0', '0'][:3-len(args)])
3300 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3301 (self.temp_result,) + args))
3302 for arg in self.args:
3303 arg.generate_disposal_code(code)
3304 arg.free_temps(code)
3306 code.error_goto_if_null(self.temp_result, self.pos))
3307 code.put_gotref(self.temp_result)
3308 code.put_decref_clear(self.temp_result, py_object_type)
3310 def annotate(self, code):
3311 for arg in self.args:
3315 class DelStatNode(StatNode):
3320 child_attrs = ["args"]
3322 def analyse_declarations(self, env):
3323 for arg in self.args:
3324 arg.analyse_target_declaration(env)
3326 def analyse_expressions(self, env):
3327 for arg in self.args:
3328 arg.analyse_target_expression(env, None)
3329 if arg.type.is_pyobject:
3332 error(arg.pos, "Deletion of non-Python object")
3333 #arg.release_target_temp(env)
3335 gil_message = "Deleting Python object"
3337 def generate_execution_code(self, code):
3338 for arg in self.args:
3339 if arg.type.is_pyobject:
3340 arg.generate_deletion_code(code)
3341 # else error reported earlier
3343 def annotate(self, code):
3344 for arg in self.args:
3348 class PassStatNode(StatNode):
3353 def analyse_expressions(self, env):
3356 def generate_execution_code(self, code):
3360 class BreakStatNode(StatNode):
3364 def analyse_expressions(self, env):
3367 def generate_execution_code(self, code):
3368 if not code.break_label:
3369 error(self.pos, "break statement not inside loop")
3371 code.put_goto(code.break_label)
3374 class ContinueStatNode(StatNode):
3378 def analyse_expressions(self, env):
3381 def generate_execution_code(self, code):
3382 if code.funcstate.in_try_finally:
3383 error(self.pos, "continue statement inside try of try...finally")
3384 elif not code.continue_label:
3385 error(self.pos, "continue statement not inside loop")
3387 code.put_goto(code.continue_label)
3390 class ReturnStatNode(StatNode):
3393 # value ExprNode or None
3394 # return_type PyrexType
3395 # temps_in_use [Entry] Temps in use at time of return
3397 child_attrs = ["value"]
3399 def analyse_expressions(self, env):
3400 return_type = env.return_type
3401 self.return_type = return_type
3402 self.temps_in_use = env.temps_in_use()
3404 error(self.pos, "Return not inside a function body")
3407 self.value.analyse_types(env)
3408 if return_type.is_void or return_type.is_returncode:
3409 error(self.value.pos,
3410 "Return with value in void function")
3412 self.value = self.value.coerce_to(env.return_type, env)
3413 self.value.allocate_temps(env)
3414 self.value.release_temp(env)
3416 if (not return_type.is_void
3417 and not return_type.is_pyobject
3418 and not return_type.is_returncode):
3419 error(self.pos, "Return value required")
3420 if return_type.is_pyobject:
3423 gil_message = "Returning Python object"
3425 def generate_execution_code(self, code):
3426 code.mark_pos(self.pos)
3427 if not self.return_type:
3428 # error reported earlier
3430 if self.return_type.is_pyobject:
3431 code.put_xdecref(Naming.retval_cname,
3434 self.value.generate_evaluation_code(code)
3435 self.value.make_owned_reference(code)
3438 Naming.retval_cname,
3439 self.value.result_as(self.return_type)))
3440 self.value.generate_post_assignment_code(code)
3441 self.value.free_temps(code)
3443 if self.return_type.is_pyobject:
3444 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3445 elif self.return_type.is_returncode:
3448 Naming.retval_cname,
3449 self.return_type.default_value))
3450 # free temps the old way
3451 for entry in self.temps_in_use:
3452 code.put_var_decref_clear(entry)
3453 # free temps the new way
3454 for cname, type in code.funcstate.temps_holding_reference():
3455 code.put_decref_clear(cname, type)
3458 # code.return_label)
3459 code.put_goto(code.return_label)
3461 def annotate(self, code):
3463 self.value.annotate(code)
3466 class RaiseStatNode(StatNode):
3469 # exc_type ExprNode or None
3470 # exc_value ExprNode or None
3471 # exc_tb ExprNode or None
3473 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3475 def analyse_expressions(self, env):
3477 self.exc_type.analyse_types(env)
3478 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3479 self.exc_type.allocate_temps(env)
3481 self.exc_value.analyse_types(env)
3482 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3483 self.exc_value.allocate_temps(env)
3485 self.exc_tb.analyse_types(env)
3486 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3487 self.exc_tb.allocate_temps(env)
3489 self.exc_type.release_temp(env)
3491 self.exc_value.release_temp(env)
3493 self.exc_tb.release_temp(env)
3494 env.use_utility_code(raise_utility_code)
3495 env.use_utility_code(restore_exception_utility_code)
3498 gil_message = "Raising exception"
3500 def generate_execution_code(self, code):
3502 self.exc_type.generate_evaluation_code(code)
3503 type_code = self.exc_type.py_result()
3507 self.exc_value.generate_evaluation_code(code)
3508 value_code = self.exc_value.py_result()
3512 self.exc_tb.generate_evaluation_code(code)
3513 tb_code = self.exc_tb.py_result()
3516 if self.exc_type or self.exc_value or self.exc_tb:
3518 "__Pyx_Raise(%s, %s, %s);" % (
3525 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3527 obj.generate_disposal_code(code)
3528 obj.free_temps(code)
3530 code.error_goto(self.pos))
3532 def annotate(self, code):
3534 self.exc_type.annotate(code)
3536 self.exc_value.annotate(code)
3538 self.exc_tb.annotate(code)
3541 class ReraiseStatNode(StatNode):
3545 def analyse_expressions(self, env):
3547 env.use_utility_code(raise_utility_code)
3548 env.use_utility_code(restore_exception_utility_code)
3550 gil_message = "Raising exception"
3552 def generate_execution_code(self, code):
3553 vars = code.funcstate.exc_vars
3555 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3556 code.putln(code.error_goto(self.pos))
3558 error(self.pos, "Reraise not inside except clause")
3561 class AssertStatNode(StatNode):
3565 # value ExprNode or None
3567 child_attrs = ["cond", "value"]
3569 def analyse_expressions(self, env):
3570 self.cond = self.cond.analyse_boolean_expression(env)
3572 self.value.analyse_types(env)
3573 self.value = self.value.coerce_to_pyobject(env)
3574 self.value.allocate_temps(env)
3575 self.cond.release_temp(env)
3577 self.value.release_temp(env)
3579 #env.recycle_pending_temps() # TEMPORARY
3581 gil_message = "Raising exception"
3583 def generate_execution_code(self, code):
3584 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3585 self.cond.generate_evaluation_code(code)
3587 "if (unlikely(!%s)) {" %
3590 self.value.generate_evaluation_code(code)
3592 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3593 self.value.py_result())
3594 self.value.generate_disposal_code(code)
3595 self.value.free_temps(code)
3598 "PyErr_SetNone(PyExc_AssertionError);")
3600 code.error_goto(self.pos))
3603 self.cond.generate_disposal_code(code)
3604 self.cond.free_temps(code)
3605 code.putln("#endif")
3607 def annotate(self, code):
3608 self.cond.annotate(code)
3610 self.value.annotate(code)
3613 class IfStatNode(StatNode):
3616 # if_clauses [IfClauseNode]
3617 # else_clause StatNode or None
3619 child_attrs = ["if_clauses", "else_clause"]
3621 def analyse_control_flow(self, env):
3622 env.start_branching(self.pos)
3623 for if_clause in self.if_clauses:
3624 if_clause.analyse_control_flow(env)
3625 env.next_branch(if_clause.end_pos())
3626 if self.else_clause:
3627 self.else_clause.analyse_control_flow(env)
3628 env.finish_branching(self.end_pos())
3630 def analyse_declarations(self, env):
3631 for if_clause in self.if_clauses:
3632 if_clause.analyse_declarations(env)
3633 if self.else_clause:
3634 self.else_clause.analyse_declarations(env)
3636 def analyse_expressions(self, env):
3637 for if_clause in self.if_clauses:
3638 if_clause.analyse_expressions(env)
3639 if self.else_clause:
3640 self.else_clause.analyse_expressions(env)
3642 def generate_execution_code(self, code):
3643 code.mark_pos(self.pos)
3644 end_label = code.new_label()
3645 for if_clause in self.if_clauses:
3646 if_clause.generate_execution_code(code, end_label)
3647 if self.else_clause:
3648 code.putln("/*else*/ {")
3649 self.else_clause.generate_execution_code(code)
3651 code.put_label(end_label)
3653 def annotate(self, code):
3654 for if_clause in self.if_clauses:
3655 if_clause.annotate(code)
3656 if self.else_clause:
3657 self.else_clause.annotate(code)
3660 class IfClauseNode(Node):
3661 # if or elif clause in an if statement
3663 # condition ExprNode
3666 child_attrs = ["condition", "body"]
3668 def analyse_control_flow(self, env):
3669 self.body.analyse_control_flow(env)
3671 def analyse_declarations(self, env):
3672 self.condition.analyse_declarations(env)
3673 self.body.analyse_declarations(env)
3675 def analyse_expressions(self, env):
3677 self.condition.analyse_temp_boolean_expression(env)
3678 self.condition.release_temp(env)
3679 self.body.analyse_expressions(env)
3681 def generate_execution_code(self, code, end_label):
3682 self.condition.generate_evaluation_code(code)
3685 self.condition.result())
3686 self.condition.generate_disposal_code(code)
3687 self.condition.free_temps(code)
3688 self.body.generate_execution_code(code)
3692 code.put_goto(end_label)
3695 def annotate(self, code):
3696 self.condition.annotate(code)
3697 self.body.annotate(code)
3700 class SwitchCaseNode(StatNode):
3701 # Generated in the optimization of an if-elif-else node
3703 # conditions [ExprNode]
3706 child_attrs = ['conditions', 'body']
3708 def generate_execution_code(self, code):
3709 for cond in self.conditions:
3710 code.mark_pos(cond.pos)
3711 code.putln("case %s:" % cond.calculate_result_code())
3712 self.body.generate_execution_code(code)
3713 code.putln("break;")
3715 def annotate(self, code):
3716 for cond in self.conditions:
3718 self.body.annotate(code)
3720 class SwitchStatNode(StatNode):
3721 # Generated in the optimization of an if-elif-else node
3724 # cases [SwitchCaseNode]
3725 # else_clause StatNode or None
3727 child_attrs = ['test', 'cases', 'else_clause']
3729 def generate_execution_code(self, code):
3730 code.putln("switch (%s) {" % self.test.calculate_result_code())
3731 for case in self.cases:
3732 case.generate_execution_code(code)
3733 if self.else_clause is not None:
3734 code.putln("default:")
3735 self.else_clause.generate_execution_code(code)
3736 code.putln("break;")
3739 def annotate(self, code):
3740 self.test.annotate(code)
3741 for case in self.cases:
3743 if self.else_clause is not None:
3744 self.else_clause.annotate(code)
3746 class LoopNode(object):
3748 def analyse_control_flow(self, env):
3749 env.start_branching(self.pos)
3750 self.body.analyse_control_flow(env)
3751 env.next_branch(self.body.end_pos())
3752 if self.else_clause:
3753 self.else_clause.analyse_control_flow(env)
3754 env.finish_branching(self.end_pos())
3757 class WhileStatNode(LoopNode, StatNode):
3760 # condition ExprNode
3762 # else_clause StatNode
3764 child_attrs = ["condition", "body", "else_clause"]
3766 def analyse_declarations(self, env):
3767 self.body.analyse_declarations(env)
3768 if self.else_clause:
3769 self.else_clause.analyse_declarations(env)
3771 def analyse_expressions(self, env):
3773 self.condition.analyse_temp_boolean_expression(env)
3774 self.condition.release_temp(env)
3775 #env.recycle_pending_temps() # TEMPORARY
3776 self.body.analyse_expressions(env)
3777 if self.else_clause:
3778 self.else_clause.analyse_expressions(env)
3780 def generate_execution_code(self, code):
3781 old_loop_labels = code.new_loop_labels()
3784 self.condition.generate_evaluation_code(code)
3785 self.condition.generate_disposal_code(code)
3788 self.condition.result())
3789 self.condition.free_temps(code)
3790 self.body.generate_execution_code(code)
3791 code.put_label(code.continue_label)
3793 break_label = code.break_label
3794 code.set_loop_labels(old_loop_labels)
3795 if self.else_clause:
3796 code.putln("/*else*/ {")
3797 self.else_clause.generate_execution_code(code)
3799 code.put_label(break_label)
3801 def annotate(self, code):
3802 self.condition.annotate(code)
3803 self.body.annotate(code)
3804 if self.else_clause:
3805 self.else_clause.annotate(code)
3808 def ForStatNode(pos, **kw):
3809 if 'iterator' in kw:
3810 return ForInStatNode(pos, **kw)
3812 return ForFromStatNode(pos, **kw)
3814 class ForInStatNode(LoopNode, StatNode):
3818 # iterator IteratorNode
3820 # else_clause StatNode
3821 # item NextNode used internally
3823 child_attrs = ["target", "iterator", "body", "else_clause"]
3826 def analyse_declarations(self, env):
3827 self.target.analyse_target_declaration(env)
3828 self.body.analyse_declarations(env)
3829 if self.else_clause:
3830 self.else_clause.analyse_declarations(env)
3832 def analyse_expressions(self, env):
3834 self.target.analyse_target_types(env)
3835 self.iterator.analyse_expressions(env)
3836 self.item = ExprNodes.NextNode(self.iterator, env)
3837 self.item = self.item.coerce_to(self.target.type, env)
3838 self.item.allocate_temps(env)
3839 self.target.allocate_target_temps(env, self.item)
3840 #self.item.release_temp(env)
3841 #self.target.release_target_temp(env)
3842 self.body.analyse_expressions(env)
3843 if self.else_clause:
3844 self.else_clause.analyse_expressions(env)
3845 self.iterator.release_temp(env)
3847 def generate_execution_code(self, code):
3848 old_loop_labels = code.new_loop_labels()
3849 self.iterator.allocate_counter_temp(code)
3850 self.iterator.generate_evaluation_code(code)
3853 self.item.generate_evaluation_code(code)
3854 self.target.generate_assignment_code(self.item, code)
3855 self.body.generate_execution_code(code)
3856 code.put_label(code.continue_label)
3859 break_label = code.break_label
3860 code.set_loop_labels(old_loop_labels)
3861 if self.else_clause:
3862 code.putln("/*else*/ {")
3863 self.else_clause.generate_execution_code(code)
3865 code.put_label(break_label)
3866 self.iterator.release_counter_temp(code)
3867 self.iterator.generate_disposal_code(code)
3868 self.iterator.free_temps(code)
3870 def annotate(self, code):
3871 self.target.annotate(code)
3872 self.iterator.annotate(code)
3873 self.body.annotate(code)
3874 if self.else_clause:
3875 self.else_clause.annotate(code)
3876 self.item.annotate(code)
3879 class ForFromStatNode(LoopNode, StatNode):
3880 # for name from expr rel name rel expr
3887 # step ExprNode or None
3889 # else_clause StatNode or None
3895 # loopvar_node ExprNode (usually a NameNode or temp node)
3896 # py_loopvar_node PyTempNode or None
3897 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3899 is_py_target = False
3901 py_loopvar_node = None
3904 def analyse_declarations(self, env):
3905 self.target.analyse_target_declaration(env)
3906 self.body.analyse_declarations(env)
3907 if self.else_clause:
3908 self.else_clause.analyse_declarations(env)
3910 def analyse_expressions(self, env):
3912 self.target.analyse_target_types(env)
3913 self.bound1.analyse_types(env)
3914 self.bound2.analyse_types(env)
3915 if self.step is not None:
3916 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3917 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3918 self.step.analyse_types(env)
3920 target_type = self.target.type
3921 if self.target.type.is_numeric:
3922 loop_type = self.target.type
3924 loop_type = PyrexTypes.c_int_type
3925 if not self.bound1.type.is_pyobject:
3926 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3927 if not self.bound2.type.is_pyobject:
3928 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3929 if self.step is not None and not self.step.type.is_pyobject:
3930 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3931 self.bound1 = self.bound1.coerce_to(loop_type, env)
3932 self.bound2 = self.bound2.coerce_to(loop_type, env)
3933 if not self.bound2.is_literal:
3934 self.bound2 = self.bound2.coerce_to_temp(env)
3935 if self.step is not None:
3936 self.step = self.step.coerce_to(loop_type, env)
3937 if not self.step.is_literal:
3938 self.step = self.step.coerce_to_temp(env)
3940 target_type = self.target.type
3941 if not (target_type.is_pyobject or target_type.is_numeric):
3942 error(self.target.pos,
3943 "for-from loop variable must be c numeric type or Python object")
3944 if target_type.is_numeric:
3945 self.is_py_target = False
3946 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3947 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3948 self.loopvar_node = self.target
3949 self.py_loopvar_node = None
3951 self.is_py_target = True
3952 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3953 c_loopvar_node.allocate_temps(env)
3954 self.loopvar_node = c_loopvar_node
3955 self.py_loopvar_node = \
3956 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3957 self.bound1.allocate_temps(env)
3958 self.bound2.allocate_temps(env)
3959 if self.step is not None:
3960 self.step.allocate_temps(env)
3961 if self.is_py_target:
3962 self.py_loopvar_node.allocate_temps(env)
3963 self.target.allocate_target_temps(env, self.py_loopvar_node)
3964 #self.target.release_target_temp(env)
3965 #self.py_loopvar_node.release_temp(env)
3966 self.body.analyse_expressions(env)
3967 if self.is_py_target:
3968 c_loopvar_node.release_temp(env)
3969 if self.else_clause:
3970 self.else_clause.analyse_expressions(env)
3971 self.bound1.release_temp(env)
3972 self.bound2.release_temp(env)
3973 if self.step is not None:
3974 self.step.release_temp(env)
3976 def generate_execution_code(self, code):
3977 old_loop_labels = code.new_loop_labels()
3978 from_range = self.from_range
3979 self.bound1.generate_evaluation_code(code)
3980 self.bound2.generate_evaluation_code(code)
3981 offset, incop = self.relation_table[self.relation1]
3982 if self.step is not None:
3983 self.step.generate_evaluation_code(code)
3984 step = self.step.result()
3985 incop = "%s=%s" % (incop[0], step)
3987 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3989 loopvar_name = self.loopvar_node.result()
3991 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3993 self.bound1.result(), offset,
3994 loopvar_name, self.relation2, self.bound2.result(),
3995 loopvar_name, incop))
3996 if self.py_loopvar_node:
3997 self.py_loopvar_node.generate_evaluation_code(code)
3998 self.target.generate_assignment_code(self.py_loopvar_node, code)
4000 code.putln("%s = %s;" % (
4001 self.target.result(), loopvar_name))
4002 self.body.generate_execution_code(code)
4003 code.put_label(code.continue_label)
4004 if self.py_loopvar_node:
4005 # Reassign py variable to loop var here.
4006 # (For consistancy, should rarely come up in practice.)
4008 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, self.target, None)
4009 from_py_node.temp_code = loopvar_name
4010 from_py_node.generate_result_code(code)
4012 if self.py_loopvar_node:
4013 # This is potentially wasteful, but we don't want the semantics to
4014 # depend on whether or not the loop is a python type.
4015 self.py_loopvar_node.generate_evaluation_code(code)
4016 self.target.generate_assignment_code(self.py_loopvar_node, code)
4017 break_label = code.break_label
4018 code.set_loop_labels(old_loop_labels)
4019 if self.else_clause:
4020 code.putln("/*else*/ {")
4021 self.else_clause.generate_execution_code(code)
4023 code.put_label(break_label)
4024 self.bound1.generate_disposal_code(code)
4025 self.bound1.free_temps(code)
4026 self.bound2.generate_disposal_code(code)
4027 self.bound2.free_temps(code)
4028 if self.step is not None:
4029 self.step.generate_disposal_code(code)
4030 self.step.free_temps(code)
4032 code.funcstate.release_temp(loopvar_name)
4035 # {relop : (initial offset, increment op)}
4042 def annotate(self, code):
4043 self.target.annotate(code)
4044 self.bound1.annotate(code)
4045 self.bound2.annotate(code)
4047 self.bound2.annotate(code)
4048 self.body.annotate(code)
4049 if self.else_clause:
4050 self.else_clause.annotate(code)
4053 class WithStatNode(StatNode):
4055 Represents a Python with statement.
4057 This is only used at parse tree level; and is not present in
4058 analysis or generation phases.
4060 # manager The with statement manager object
4061 # target Node (lhs expression)
4063 child_attrs = ["manager", "target", "body"]
4065 class TryExceptStatNode(StatNode):
4066 # try .. except statement
4069 # except_clauses [ExceptClauseNode]
4070 # else_clause StatNode or None
4071 # cleanup_list [Entry] old style temps to clean up on error
4073 child_attrs = ["body", "except_clauses", "else_clause"]
4075 def analyse_control_flow(self, env):
4076 env.start_branching(self.pos)
4077 self.body.analyse_control_flow(env)
4078 successful_try = env.control_flow # grab this for later
4079 env.next_branch(self.body.end_pos())
4080 env.finish_branching(self.body.end_pos())
4082 env.start_branching(self.except_clauses[0].pos)
4083 for except_clause in self.except_clauses:
4084 except_clause.analyse_control_flow(env)
4085 env.next_branch(except_clause.end_pos())
4087 # the else cause it executed only when the try clause finishes
4088 env.control_flow.incoming = successful_try
4089 if self.else_clause:
4090 self.else_clause.analyse_control_flow(env)
4091 env.finish_branching(self.end_pos())
4093 def analyse_declarations(self, env):
4094 self.body.analyse_declarations(env)
4095 for except_clause in self.except_clauses:
4096 except_clause.analyse_declarations(env)
4097 if self.else_clause:
4098 self.else_clause.analyse_declarations(env)
4100 env.use_utility_code(reset_exception_utility_code)
4102 def analyse_expressions(self, env):
4103 self.body.analyse_expressions(env)
4104 self.cleanup_list = env.free_temp_entries[:]
4105 default_clause_seen = 0
4106 for except_clause in self.except_clauses:
4107 except_clause.analyse_expressions(env)
4108 if default_clause_seen:
4109 error(except_clause.pos, "default 'except:' must be last")
4110 if not except_clause.pattern:
4111 default_clause_seen = 1
4112 self.has_default_clause = default_clause_seen
4113 if self.else_clause:
4114 self.else_clause.analyse_expressions(env)
4117 gil_message = "Try-except statement"
4119 def generate_execution_code(self, code):
4120 old_return_label = code.return_label
4121 old_break_label = code.break_label
4122 old_continue_label = code.continue_label
4123 old_error_label = code.new_error_label()
4124 our_error_label = code.error_label
4125 except_end_label = code.new_label('exception_handled')
4126 except_error_label = code.new_label('except_error')
4127 except_return_label = code.new_label('except_return')
4128 try_return_label = code.new_label('try_return')
4129 try_break_label = code.new_label('try_break')
4130 try_continue_label = code.new_label('try_continue')
4131 try_end_label = code.new_label('try_end')
4134 code.putln("PyObject %s;" %
4135 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4136 code.putln("__Pyx_ExceptionSave(%s);" %
4137 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4138 for var in Naming.exc_save_vars:
4139 code.put_xgotref(var)
4142 code.return_label = try_return_label
4143 code.break_label = try_break_label
4144 code.continue_label = try_continue_label
4145 self.body.generate_execution_code(code)
4148 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4149 code.error_label = except_error_label
4150 code.return_label = except_return_label
4151 if self.else_clause:
4154 self.else_clause.generate_execution_code(code)
4157 for var in Naming.exc_save_vars:
4158 code.put_xdecref_clear(var, py_object_type)
4159 code.put_goto(try_end_label)
4160 if code.label_used(try_return_label):
4161 code.put_label(try_return_label)
4162 for var in Naming.exc_save_vars:
4163 code.put_xdecref_clear(var, py_object_type)
4164 code.put_goto(old_return_label)
4165 code.put_label(our_error_label)
4166 code.put_var_xdecrefs_clear(self.cleanup_list)
4167 for temp_name, type in temps_to_clean_up:
4168 code.put_xdecref_clear(temp_name, type)
4169 for except_clause in self.except_clauses:
4170 except_clause.generate_handling_code(code, except_end_label)
4172 error_label_used = code.label_used(except_error_label)
4173 if error_label_used or not self.has_default_clause:
4174 if error_label_used:
4175 code.put_label(except_error_label)
4176 for var in Naming.exc_save_vars:
4177 code.put_xdecref(var, py_object_type)
4178 code.put_goto(old_error_label)
4180 if code.label_used(try_break_label):
4181 code.put_label(try_break_label)
4182 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4183 code.putln("__Pyx_ExceptionReset(%s);" %
4184 ', '.join(Naming.exc_save_vars))
4185 code.put_goto(old_break_label)
4187 if code.label_used(try_continue_label):
4188 code.put_label(try_continue_label)
4189 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4190 code.putln("__Pyx_ExceptionReset(%s);" %
4191 ', '.join(Naming.exc_save_vars))
4192 code.put_goto(old_continue_label)
4194 if code.label_used(except_return_label):
4195 code.put_label(except_return_label)
4196 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4197 code.putln("__Pyx_ExceptionReset(%s);" %
4198 ', '.join(Naming.exc_save_vars))
4199 code.put_goto(old_return_label)
4201 if code.label_used(except_end_label):
4202 code.put_label(except_end_label)
4203 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4204 code.putln("__Pyx_ExceptionReset(%s);" %
4205 ', '.join(Naming.exc_save_vars))
4206 code.put_label(try_end_label)
4209 code.return_label = old_return_label
4210 code.break_label = old_break_label
4211 code.continue_label = old_continue_label
4212 code.error_label = old_error_label
4214 def annotate(self, code):
4215 self.body.annotate(code)
4216 for except_node in self.except_clauses:
4217 except_node.annotate(code)
4218 if self.else_clause:
4219 self.else_clause.annotate(code)
4222 class ExceptClauseNode(Node):
4223 # Part of try ... except statement.
4226 # target ExprNode or None
4228 # excinfo_target NameNode or None optional target for exception info
4229 # match_flag string result of exception match
4230 # exc_value ExcValueNode used internally
4231 # function_name string qualified name of enclosing function
4232 # exc_vars (string * 3) local exception variables
4234 # excinfo_target is never set by the parser, but can be set by a transform
4235 # in order to extract more extensive information about the exception as a
4236 # sys.exc_info()-style tuple into a target variable
4238 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4241 excinfo_target = None
4243 def analyse_declarations(self, env):
4245 self.target.analyse_target_declaration(env)
4246 if self.excinfo_target is not None:
4247 self.excinfo_target.analyse_target_declaration(env)
4248 self.body.analyse_declarations(env)
4250 def analyse_expressions(self, env):
4252 genv = env.global_scope()
4253 self.function_name = env.qualified_name
4255 self.pattern.analyse_expressions(env)
4256 self.pattern = self.pattern.coerce_to_pyobject(env)
4257 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4258 self.pattern.release_temp(env)
4259 env.release_temp(self.match_flag)
4261 if self.target or self.excinfo_target:
4262 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4264 self.exc_vars = None
4267 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4268 self.exc_value.allocate_temps(env)
4269 self.target.analyse_target_expression(env, self.exc_value)
4270 if self.excinfo_target is not None:
4272 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4273 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4274 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4275 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4277 self.excinfo_tuple.analyse_expressions(env)
4278 self.excinfo_tuple.allocate_temps(env)
4279 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4281 self.body.analyse_expressions(env)
4284 for var in self.exc_vars:
4285 env.release_temp(var)
4287 def generate_handling_code(self, code, end_label):
4288 code.mark_pos(self.pos)
4290 self.pattern.generate_evaluation_code(code)
4292 "%s = PyErr_ExceptionMatches(%s);" % (
4294 self.pattern.py_result()))
4295 self.pattern.generate_disposal_code(code)
4296 self.pattern.free_temps(code)
4301 code.putln("/*except:*/ {")
4304 exc_vars = self.exc_vars
4305 elif not getattr(self.body, 'stats', True):
4306 # most simple case: no exception variable, empty body (pass)
4307 # => reset the exception state, done
4308 code.putln("PyErr_Restore(0,0,0);")
4309 code.put_goto(end_label)
4313 # during type analysis, we didn't know if we need the
4314 # exception value, but apparently, we do
4315 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4319 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4320 # We always have to fetch the exception value even if
4321 # there is no target, because this also normalises the
4322 # exception and stores it in the thread state.
4323 code.globalstate.use_utility_code(get_exception_utility_code)
4324 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4325 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4326 code.error_goto(self.pos)))
4330 self.exc_value.generate_evaluation_code(code)
4331 self.target.generate_assignment_code(self.exc_value, code)
4332 if self.excinfo_target is not None:
4333 self.excinfo_tuple.generate_evaluation_code(code)
4334 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4337 old_break_label, old_continue_label = code.break_label, code.continue_label
4338 code.break_label = code.new_label('except_break')
4339 code.continue_label = code.new_label('except_continue')
4341 old_exc_vars = code.funcstate.exc_vars
4342 code.funcstate.exc_vars = exc_vars
4343 self.body.generate_execution_code(code)
4344 code.funcstate.exc_vars = old_exc_vars
4345 for var in exc_vars:
4346 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4347 code.put_goto(end_label)
4349 if code.label_used(code.break_label):
4350 code.put_label(code.break_label)
4351 for var in exc_vars:
4352 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4353 code.put_goto(old_break_label)
4354 code.break_label = old_break_label
4356 if code.label_used(code.continue_label):
4357 code.put_label(code.continue_label)
4358 for var in exc_vars:
4359 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4360 code.put_goto(old_continue_label)
4361 code.continue_label = old_continue_label
4363 if not self.exc_vars:
4364 # clean up locally allocated temps
4365 for temp in exc_vars:
4366 code.funcstate.release_temp(temp)
4371 def annotate(self, code):
4373 self.pattern.annotate(code)
4375 self.target.annotate(code)
4376 self.body.annotate(code)
4379 class TryFinallyStatNode(StatNode):
4380 # try ... finally statement
4383 # finally_clause StatNode
4385 # cleanup_list [Entry] old_style temps to clean up on error
4387 # The plan is that we funnel all continue, break
4388 # return and error gotos into the beginning of the
4389 # finally block, setting a variable to remember which
4390 # one we're doing. At the end of the finally block, we
4391 # switch on the variable to figure out where to go.
4392 # In addition, if we're doing an error, we save the
4393 # exception on entry to the finally block and restore
4396 child_attrs = ["body", "finally_clause"]
4398 preserve_exception = 1
4400 disallow_continue_in_try_finally = 0
4401 # There doesn't seem to be any point in disallowing
4402 # continue in the try block, since we have no problem
4405 def create_analysed(pos, env, body, finally_clause):
4406 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4407 node.cleanup_list = []
4409 create_analysed = staticmethod(create_analysed)
4411 def analyse_control_flow(self, env):
4412 env.start_branching(self.pos)
4413 self.body.analyse_control_flow(env)
4414 env.next_branch(self.body.end_pos())
4415 env.finish_branching(self.body.end_pos())
4416 self.finally_clause.analyse_control_flow(env)
4418 def analyse_declarations(self, env):
4419 self.body.analyse_declarations(env)
4420 self.finally_clause.analyse_declarations(env)
4422 def analyse_expressions(self, env):
4423 self.body.analyse_expressions(env)
4424 self.cleanup_list = env.free_temp_entries[:]
4425 self.finally_clause.analyse_expressions(env)
4428 gil_message = "Try-finally statement"
4430 def generate_execution_code(self, code):
4431 old_error_label = code.error_label
4432 old_labels = code.all_new_labels()
4433 new_labels = code.get_all_labels()
4434 new_error_label = code.error_label
4435 catch_label = code.new_label()
4438 if self.disallow_continue_in_try_finally:
4439 was_in_try_finally = code.funcstate.in_try_finally
4440 code.funcstate.in_try_finally = 1
4441 self.body.generate_execution_code(code)
4442 if self.disallow_continue_in_try_finally:
4443 code.funcstate.in_try_finally = was_in_try_finally
4446 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4450 error_label_used = 0
4451 for i, new_label in enumerate(new_labels):
4452 if new_label in code.labels_used:
4453 cases_used.append(i)
4454 if new_label == new_error_label:
4455 error_label_used = 1
4456 error_label_case = i
4460 if error_label_used and self.preserve_exception:
4462 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4464 "int %s;" % Naming.exc_lineno_name)
4465 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4466 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4467 code.putln(exc_var_init_zero)
4469 exc_var_init_zero = None
4470 code.use_label(catch_label)
4472 "__pyx_why = 0; goto %s;" % catch_label)
4473 for i in cases_used:
4474 new_label = new_labels[i]
4475 #if new_label and new_label != "<try>":
4476 if new_label == new_error_label and self.preserve_exception:
4477 self.put_error_catcher(code,
4478 new_error_label, i+1, catch_label, temps_to_clean_up)
4480 code.put('%s: ' % new_label)
4481 if exc_var_init_zero:
4482 code.putln(exc_var_init_zero)
4483 code.putln("__pyx_why = %s; goto %s;" % (
4486 code.put_label(catch_label)
4487 code.set_all_labels(old_labels)
4488 if error_label_used:
4489 code.new_error_label()
4490 finally_error_label = code.error_label
4491 self.finally_clause.generate_execution_code(code)
4492 if error_label_used:
4493 if finally_error_label in code.labels_used and self.preserve_exception:
4494 over_label = code.new_label()
4495 code.put_goto(over_label);
4496 code.put_label(finally_error_label)
4497 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4498 for var in Naming.exc_vars:
4499 code.putln("Py_XDECREF(%s);" % var)
4501 code.put_goto(old_error_label)
4502 code.put_label(over_label)
4503 code.error_label = old_error_label
4506 "switch (__pyx_why) {")
4507 for i in cases_used:
4508 old_label = old_labels[i]
4509 if old_label == old_error_label and self.preserve_exception:
4510 self.put_error_uncatcher(code, i+1, old_error_label)
4512 code.use_label(old_label)
4514 "case %s: goto %s;" % (
4522 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4523 code.globalstate.use_utility_code(restore_exception_utility_code)
4530 code.put_var_xdecrefs_clear(self.cleanup_list)
4531 for temp_name, type in temps_to_clean_up:
4532 code.put_xdecref_clear(temp_name, type)
4534 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4538 Naming.exc_lineno_name, Naming.lineno_cname))
4542 code.put_goto(catch_label)
4546 def put_error_uncatcher(self, code, i, error_label):
4547 code.globalstate.use_utility_code(restore_exception_utility_code)
4552 "__Pyx_ErrRestore(%s, %s, %s);" %
4556 Naming.lineno_cname, Naming.exc_lineno_name))
4557 for var in Naming.exc_vars:
4561 code.put_goto(error_label)
4565 def annotate(self, code):
4566 self.body.annotate(code)
4567 self.finally_clause.annotate(code)
4570 class GILStatNode(TryFinallyStatNode):
4571 # 'with gil' or 'with nogil' statement
4573 # state string 'gil' or 'nogil'
4577 preserve_exception = 0
4579 def __init__(self, pos, state, body):
4581 TryFinallyStatNode.__init__(self, pos,
4583 finally_clause = GILExitNode(pos, state = state))
4585 def analyse_expressions(self, env):
4586 env.use_utility_code(force_init_threads_utility_code)
4587 was_nogil = env.nogil
4589 TryFinallyStatNode.analyse_expressions(self, env)
4590 env.nogil = was_nogil
4592 def gil_check(self, env):
4595 def generate_execution_code(self, code):
4596 code.mark_pos(self.pos)
4597 if self.state == 'gil':
4598 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4600 code.putln("{ PyThreadState *_save;")
4601 code.putln("Py_UNBLOCK_THREADS")
4602 TryFinallyStatNode.generate_execution_code(self, code)
4606 class GILExitNode(StatNode):
4607 # Used as the 'finally' block in a GILStatNode
4609 # state string 'gil' or 'nogil'
4613 def analyse_expressions(self, env):
4616 def generate_execution_code(self, code):
4617 if self.state == 'gil':
4618 code.putln("PyGILState_Release();")
4620 code.putln("Py_BLOCK_THREADS")
4623 class CImportStatNode(StatNode):
4626 # module_name string Qualified name of module being imported
4627 # as_name string or None Name specified in "as" clause, if any
4631 def analyse_declarations(self, env):
4632 if not env.is_module_scope:
4633 error(self.pos, "cimport only allowed at module level")
4635 module_scope = env.find_module(self.module_name, self.pos)
4636 if "." in self.module_name:
4637 names = [EncodedString(name) for name in self.module_name.split(".")]
4639 top_module_scope = env.context.find_submodule(top_name)
4640 module_scope = top_module_scope
4641 for name in names[1:]:
4642 submodule_scope = module_scope.find_submodule(name)
4643 module_scope.declare_module(name, submodule_scope, self.pos)
4644 module_scope = submodule_scope
4646 env.declare_module(self.as_name, module_scope, self.pos)
4648 env.declare_module(top_name, top_module_scope, self.pos)
4650 name = self.as_name or self.module_name
4651 env.declare_module(name, module_scope, self.pos)
4653 def analyse_expressions(self, env):
4656 def generate_execution_code(self, code):
4660 class FromCImportStatNode(StatNode):
4661 # from ... cimport statement
4663 # module_name string Qualified name of module
4664 # imported_names [(pos, name, as_name, kind)] Names to be imported
4668 def analyse_declarations(self, env):
4669 if not env.is_module_scope:
4670 error(self.pos, "cimport only allowed at module level")
4672 module_scope = env.find_module(self.module_name, self.pos)
4673 env.add_imported_module(module_scope)
4674 for pos, name, as_name, kind in self.imported_names:
4676 for local_name, entry in module_scope.entries.items():
4677 env.add_imported_entry(local_name, entry, pos)
4679 entry = module_scope.lookup(name)
4681 if kind and not self.declaration_matches(entry, kind):
4682 entry.redeclared(pos)
4684 if kind == 'struct' or kind == 'union':
4685 entry = module_scope.declare_struct_or_union(name,
4686 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4687 elif kind == 'class':
4688 entry = module_scope.declare_c_class(name, pos = pos,
4689 module_name = self.module_name)
4691 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4692 if submodule_scope.parent_module is module_scope:
4693 env.declare_module(as_name or name, submodule_scope, self.pos)
4695 error(pos, "Name '%s' not declared in module '%s'"
4696 % (name, self.module_name))
4699 local_name = as_name or name
4700 env.add_imported_entry(local_name, entry, pos)
4702 def declaration_matches(self, entry, kind):
4703 if not entry.is_type:
4707 if not type.is_extension_type:
4710 if not type.is_struct_or_union:
4712 if kind != type.kind:
4716 def analyse_expressions(self, env):
4719 def generate_execution_code(self, code):
4723 class FromImportStatNode(StatNode):
4724 # from ... import statement
4727 # items [(string, NameNode)]
4728 # interned_items [(string, NameNode, ExprNode)]
4729 # item PyTempNode used internally
4730 # import_star boolean used internally
4732 child_attrs = ["module"]
4735 def analyse_declarations(self, env):
4736 for name, target in self.items:
4738 if not env.is_module_scope:
4739 error(self.pos, "import * only allowed at module level")
4741 env.has_import_star = 1
4742 self.import_star = 1
4744 target.analyse_target_declaration(env)
4746 def analyse_expressions(self, env):
4748 self.module.analyse_expressions(env)
4749 self.item = ExprNodes.PyTempNode(self.pos, env)
4750 self.item.allocate_temp(env)
4751 self.interned_items = []
4752 for name, target in self.items:
4754 for _, entry in env.entries.items():
4755 if not entry.is_type and entry.type.is_extension_type:
4756 env.use_utility_code(ExprNodes.type_test_utility_code)
4759 entry = env.lookup(target.name)
4760 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4761 continue # already cimported
4762 target.analyse_target_expression(env, None)
4763 if target.type is py_object_type:
4766 coerced_item = self.item.coerce_to(target.type, env)
4767 self.interned_items.append(
4768 (env.intern_identifier(name), target, coerced_item))
4769 #target.release_target_temp(env) # was release_temp ?!?
4770 self.module.release_temp(env)
4771 self.item.release_temp(env)
4773 def generate_execution_code(self, code):
4774 self.module.generate_evaluation_code(code)
4775 if self.import_star:
4777 'if (%s(%s) < 0) %s;' % (
4779 self.module.py_result(),
4780 code.error_goto(self.pos)))
4781 for cname, target, coerced_item in self.interned_items:
4783 '%s = PyObject_GetAttr(%s, %s); %s' % (
4785 self.module.py_result(),
4787 code.error_goto_if_null(self.item.result(), self.pos)))
4788 code.put_gotref(self.item.py_result())
4789 if coerced_item is None:
4790 target.generate_assignment_code(self.item, code)
4792 coerced_item.allocate_temp_result(code)
4793 coerced_item.generate_result_code(code)
4794 target.generate_assignment_code(coerced_item, code)
4795 if self.item.result() != coerced_item.result():
4796 code.put_decref_clear(self.item.result(), self.item.type)
4797 self.module.generate_disposal_code(code)
4798 self.module.free_temps(code)
4802 #------------------------------------------------------------------------------------
4804 # Runtime support code
4806 #------------------------------------------------------------------------------------
4808 utility_function_predeclarations = \
4811 #define INLINE __inline__
4813 #define INLINE __inline
4818 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4822 static int %(skip_dispatch_cname)s = 0;
4824 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4826 if Options.gcc_branch_hints:
4827 branch_prediction_macros = \
4830 /* Test for GCC > 2.95 */
4831 #if __GNUC__ > 2 || \
4832 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4833 #define likely(x) __builtin_expect(!!(x), 1)
4834 #define unlikely(x) __builtin_expect(!!(x), 0)
4835 #else /* __GNUC__ > 2 ... */
4836 #define likely(x) (x)
4837 #define unlikely(x) (x)
4838 #endif /* __GNUC__ > 2 ... */
4839 #else /* __GNUC__ */
4840 #define likely(x) (x)
4841 #define unlikely(x) (x)
4842 #endif /* __GNUC__ */
4845 branch_prediction_macros = \
4847 #define likely(x) (x)
4848 #define unlikely(x) (x)
4851 #get_name_predeclaration = \
4852 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4854 #get_name_interned_predeclaration = \
4855 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4857 #------------------------------------------------------------------------------------
4859 printing_utility_code = UtilityCode(
4861 static int __Pyx_Print(PyObject *, int); /*proto*/
4862 #if PY_MAJOR_VERSION >= 3
4863 static PyObject* %s = 0;
4864 static PyObject* %s = 0;
4866 """ % (Naming.print_function, Naming.print_function_kwargs),
4868 #if PY_MAJOR_VERSION < 3
4869 static PyObject *__Pyx_GetStdout(void) {
4870 PyObject *f = PySys_GetObject((char *)"stdout");
4872 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4877 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4882 if (!(f = __Pyx_GetStdout()))
4884 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4885 if (PyFile_SoftSpace(f, 1)) {
4886 if (PyFile_WriteString(" ", f) < 0)
4889 v = PyTuple_GET_ITEM(arg_tuple, i);
4890 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4892 if (PyString_Check(v)) {
4893 char *s = PyString_AsString(v);
4894 Py_ssize_t len = PyString_Size(v);
4896 isspace(Py_CHARMASK(s[len-1])) &&
4898 PyFile_SoftSpace(f, 0);
4902 if (PyFile_WriteString("\n", f) < 0)
4904 PyFile_SoftSpace(f, 0);
4909 #else /* Python 3 has a print function */
4911 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4912 PyObject* kwargs = 0;
4913 PyObject* result = 0;
4914 PyObject* end_string;
4915 if (!%(PRINT_FUNCTION)s) {
4916 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4917 if (!%(PRINT_FUNCTION)s)
4921 if (!%(PRINT_KWARGS)s) {
4922 %(PRINT_KWARGS)s = PyDict_New();
4923 if (!%(PRINT_KWARGS)s)
4925 end_string = PyUnicode_FromStringAndSize(" ", 1);
4928 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4929 Py_DECREF(end_string);
4932 Py_DECREF(end_string);
4934 kwargs = %(PRINT_KWARGS)s;
4936 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4944 """ % {'BUILTINS' : Naming.builtins_cname,
4945 'PRINT_FUNCTION' : Naming.print_function,
4946 'PRINT_KWARGS' : Naming.print_function_kwargs}
4950 printing_one_utility_code = UtilityCode(
4952 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4955 #if PY_MAJOR_VERSION < 3
4957 static int __Pyx_PrintOne(PyObject *o) {
4959 if (!(f = __Pyx_GetStdout()))
4961 if (PyFile_SoftSpace(f, 0)) {
4962 if (PyFile_WriteString(" ", f) < 0)
4965 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4967 if (PyFile_WriteString("\n", f) < 0)
4970 /* the line below is just to avoid compiler
4971 * compiler warnings about unused functions */
4972 return __Pyx_Print(NULL, 0);
4975 #else /* Python 3 has a print function */
4977 static int __Pyx_PrintOne(PyObject *o) {
4979 PyObject* arg_tuple = PyTuple_New(1);
4980 if (unlikely(!arg_tuple))
4983 PyTuple_SET_ITEM(arg_tuple, 0, o);
4984 res = __Pyx_Print(arg_tuple, 1);
4985 Py_DECREF(arg_tuple);
4991 requires=[printing_utility_code])
4995 #------------------------------------------------------------------------------------
4997 # The following function is based on do_raise() from ceval.c.
4999 raise_utility_code = UtilityCode(
5001 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5004 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5008 /* First, check the traceback argument, replacing None with NULL. */
5009 if (tb == Py_None) {
5013 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5014 PyErr_SetString(PyExc_TypeError,
5015 "raise: arg 3 must be a traceback or None");
5018 /* Next, replace a missing value with None */
5019 if (value == NULL) {
5023 #if PY_VERSION_HEX < 0x02050000
5024 if (!PyClass_Check(type))
5026 if (!PyType_Check(type))
5029 /* Raising an instance. The value should be a dummy. */
5030 if (value != Py_None) {
5031 PyErr_SetString(PyExc_TypeError,
5032 "instance exception may not have a separate value");
5035 /* Normalize to raise <class>, <instance> */
5038 #if PY_VERSION_HEX < 0x02050000
5039 if (PyInstance_Check(type)) {
5040 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5045 PyErr_SetString(PyExc_TypeError,
5046 "raise: exception must be an old-style class or instance");
5050 type = (PyObject*) Py_TYPE(type);
5052 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5053 PyErr_SetString(PyExc_TypeError,
5054 "raise: exception class must be a subclass of BaseException");
5059 __Pyx_ErrRestore(type, value, tb);
5069 #------------------------------------------------------------------------------------
5071 reraise_utility_code = UtilityCode(
5073 static void __Pyx_ReRaise(void); /*proto*/
5076 static void __Pyx_ReRaise(void) {
5077 PyThreadState *tstate = PyThreadState_GET();
5078 PyObject* tmp_type = tstate->curexc_type;
5079 PyObject* tmp_value = tstate->curexc_value;
5080 PyObject* tmp_tb = tstate->curexc_traceback;
5081 tstate->curexc_type = tstate->exc_type;
5082 tstate->curexc_value = tstate->exc_value;
5083 tstate->curexc_traceback = tstate->exc_traceback;
5084 tstate->exc_type = 0;
5085 tstate->exc_value = 0;
5086 tstate->exc_traceback = 0;
5087 Py_XDECREF(tmp_type);
5088 Py_XDECREF(tmp_value);
5093 #------------------------------------------------------------------------------------
5095 arg_type_test_utility_code = UtilityCode(
5097 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5098 const char *name, int exact); /*proto*/
5101 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5102 const char *name, int exact)
5105 PyErr_Format(PyExc_SystemError, "Missing type object");
5108 if (none_allowed && obj == Py_None) return 1;
5110 if (Py_TYPE(obj) == type) return 1;
5113 if (PyObject_TypeCheck(obj, type)) return 1;
5115 PyErr_Format(PyExc_TypeError,
5116 "Argument '%s' has incorrect type (expected %s, got %s)",
5117 name, type->tp_name, Py_TYPE(obj)->tp_name);
5122 #------------------------------------------------------------------------------------
5124 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5125 # many or too few positional arguments were found. This handles
5126 # Py_ssize_t formatting correctly.
5128 raise_argtuple_invalid_utility_code = UtilityCode(
5130 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5131 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5134 static void __Pyx_RaiseArgtupleInvalid(
5135 const char* func_name,
5139 Py_ssize_t num_found)
5141 Py_ssize_t num_expected;
5142 const char *number, *more_or_less;
5144 if (num_found < num_min) {
5145 num_expected = num_min;
5146 more_or_less = "at least";
5148 num_expected = num_max;
5149 more_or_less = "at most";
5152 more_or_less = "exactly";
5154 number = (num_expected == 1) ? "" : "s";
5155 PyErr_Format(PyExc_TypeError,
5156 #if PY_VERSION_HEX < 0x02050000
5157 "%s() takes %s %d positional argument%s (%d given)",
5159 "%s() takes %s %zd positional argument%s (%zd given)",
5161 func_name, more_or_less, num_expected, number, num_found);
5165 raise_keyword_required_utility_code = UtilityCode(
5167 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5170 static INLINE void __Pyx_RaiseKeywordRequired(
5171 const char* func_name,
5174 PyErr_Format(PyExc_TypeError,
5175 #if PY_MAJOR_VERSION >= 3
5176 "%s() needs keyword-only argument %U", func_name, kw_name);
5178 "%s() needs keyword-only argument %s", func_name,
5179 PyString_AS_STRING(kw_name));
5184 raise_double_keywords_utility_code = UtilityCode(
5186 static void __Pyx_RaiseDoubleKeywordsError(
5187 const char* func_name, PyObject* kw_name); /*proto*/
5190 static void __Pyx_RaiseDoubleKeywordsError(
5191 const char* func_name,
5194 PyErr_Format(PyExc_TypeError,
5195 #if PY_MAJOR_VERSION >= 3
5196 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5198 "%s() got multiple values for keyword argument '%s'", func_name,
5199 PyString_AS_STRING(kw_name));
5204 #------------------------------------------------------------------------------------
5206 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5207 # were passed to a function, or if any keywords were passed to a
5208 # function that does not accept them.
5210 keyword_string_check_utility_code = UtilityCode(
5212 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5213 const char* function_name, int kw_allowed); /*proto*/
5216 static INLINE int __Pyx_CheckKeywordStrings(
5218 const char* function_name,
5223 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5224 #if PY_MAJOR_VERSION < 3
5225 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5227 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5229 goto invalid_keyword_type;
5231 if ((!kw_allowed) && unlikely(key))
5232 goto invalid_keyword;
5234 invalid_keyword_type:
5235 PyErr_Format(PyExc_TypeError,
5236 "%s() keywords must be strings", function_name);
5239 PyErr_Format(PyExc_TypeError,
5240 #if PY_MAJOR_VERSION < 3
5241 "%s() got an unexpected keyword argument '%s'",
5242 function_name, PyString_AsString(key));
5244 "%s() got an unexpected keyword argument '%U'",
5245 function_name, key);
5251 #------------------------------------------------------------------------------------
5253 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5254 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5255 # keywords will raise an invalid keyword error.
5257 # Three kinds of errors are checked: 1) non-string keywords, 2)
5258 # unexpected keywords and 3) overlap with positional arguments.
5260 # If num_posargs is greater 0, it denotes the number of positional
5261 # arguments that were passed and that must therefore not appear
5262 # amongst the keywords as well.
5264 # This method does not check for required keyword arguments.
5267 parse_keywords_utility_code = UtilityCode(
5269 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5270 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5271 const char* function_name); /*proto*/
5274 static int __Pyx_ParseOptionalKeywords(
5276 PyObject **argnames[],
5279 Py_ssize_t num_pos_args,
5280 const char* function_name)
5282 PyObject *key = 0, *value = 0;
5285 PyObject*** first_kw_arg = argnames + num_pos_args;
5287 while (PyDict_Next(kwds, &pos, &key, &value)) {
5288 name = first_kw_arg;
5289 while (*name && (**name != key)) name++;
5291 values[name-argnames] = value;
5293 #if PY_MAJOR_VERSION < 3
5294 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5296 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5298 goto invalid_keyword_type;
5300 for (name = first_kw_arg; *name; name++) {
5301 #if PY_MAJOR_VERSION >= 3
5302 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5303 PyUnicode_Compare(**name, key) == 0) break;
5305 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5306 _PyString_Eq(**name, key)) break;
5310 values[name-argnames] = value;
5312 /* unexpected keyword found */
5313 for (name=argnames; name != first_kw_arg; name++) {
5314 if (**name == key) goto arg_passed_twice;
5315 #if PY_MAJOR_VERSION >= 3
5316 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5317 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5319 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5320 _PyString_Eq(**name, key)) goto arg_passed_twice;
5324 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5326 goto invalid_keyword;
5334 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5336 invalid_keyword_type:
5337 PyErr_Format(PyExc_TypeError,
5338 "%s() keywords must be strings", function_name);
5341 PyErr_Format(PyExc_TypeError,
5342 #if PY_MAJOR_VERSION < 3
5343 "%s() got an unexpected keyword argument '%s'",
5344 function_name, PyString_AsString(key));
5346 "%s() got an unexpected keyword argument '%U'",
5347 function_name, key);
5354 #------------------------------------------------------------------------------------
5356 traceback_utility_code = UtilityCode(
5358 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5361 #include "compile.h"
5362 #include "frameobject.h"
5363 #include "traceback.h"
5365 static void __Pyx_AddTraceback(const char *funcname) {
5366 PyObject *py_srcfile = 0;
5367 PyObject *py_funcname = 0;
5368 PyObject *py_globals = 0;
5369 PyObject *empty_string = 0;
5370 PyCodeObject *py_code = 0;
5371 PyFrameObject *py_frame = 0;
5373 #if PY_MAJOR_VERSION < 3
5374 py_srcfile = PyString_FromString(%(FILENAME)s);
5376 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5378 if (!py_srcfile) goto bad;
5380 #if PY_MAJOR_VERSION < 3
5381 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5383 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5387 #if PY_MAJOR_VERSION < 3
5388 py_funcname = PyString_FromString(funcname);
5390 py_funcname = PyUnicode_FromString(funcname);
5393 if (!py_funcname) goto bad;
5394 py_globals = PyModule_GetDict(%(GLOBALS)s);
5395 if (!py_globals) goto bad;
5396 #if PY_MAJOR_VERSION < 3
5397 empty_string = PyString_FromStringAndSize("", 0);
5399 empty_string = PyBytes_FromStringAndSize("", 0);
5401 if (!empty_string) goto bad;
5402 py_code = PyCode_New(
5403 0, /*int argcount,*/
5404 #if PY_MAJOR_VERSION >= 3
5405 0, /*int kwonlyargcount,*/
5408 0, /*int stacksize,*/
5410 empty_string, /*PyObject *code,*/
5411 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5412 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5413 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5414 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5415 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5416 py_srcfile, /*PyObject *filename,*/
5417 py_funcname, /*PyObject *name,*/
5418 %(LINENO)s, /*int firstlineno,*/
5419 empty_string /*PyObject *lnotab*/
5421 if (!py_code) goto bad;
5422 py_frame = PyFrame_New(
5423 PyThreadState_GET(), /*PyThreadState *tstate,*/
5424 py_code, /*PyCodeObject *code,*/
5425 py_globals, /*PyObject *globals,*/
5426 0 /*PyObject *locals*/
5428 if (!py_frame) goto bad;
5429 py_frame->f_lineno = %(LINENO)s;
5430 PyTraceBack_Here(py_frame);
5432 Py_XDECREF(py_srcfile);
5433 Py_XDECREF(py_funcname);
5434 Py_XDECREF(empty_string);
5435 Py_XDECREF(py_code);
5436 Py_XDECREF(py_frame);
5439 'FILENAME': Naming.filename_cname,
5440 'LINENO': Naming.lineno_cname,
5441 'CFILENAME': Naming.cfilenm_cname,
5442 'CLINENO': Naming.clineno_cname,
5443 'GLOBALS': Naming.module_cname,
5444 'EMPTY_TUPLE' : Naming.empty_tuple,
5447 restore_exception_utility_code = UtilityCode(
5449 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5450 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5453 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5454 PyObject *tmp_type, *tmp_value, *tmp_tb;
5455 PyThreadState *tstate = PyThreadState_GET();
5457 #if PY_MAJOR_VERSION >= 3
5458 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5459 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5460 tmp_type = tstate->exc_type;
5461 tmp_value = tstate->exc_value;
5462 tmp_tb = tstate->exc_traceback;
5463 PyErr_NormalizeException(&type, &value, &tb);
5464 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5465 tstate->exc_type = 0;
5466 tstate->exc_value = 0;
5467 tstate->exc_traceback = 0;
5468 PyException_SetContext(value, tmp_value);
5469 Py_DECREF(tmp_type);
5474 tmp_type = tstate->curexc_type;
5475 tmp_value = tstate->curexc_value;
5476 tmp_tb = tstate->curexc_traceback;
5477 tstate->curexc_type = type;
5478 tstate->curexc_value = value;
5479 tstate->curexc_traceback = tb;
5480 Py_XDECREF(tmp_type);
5481 Py_XDECREF(tmp_value);
5485 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5486 PyThreadState *tstate = PyThreadState_GET();
5487 *type = tstate->curexc_type;
5488 *value = tstate->curexc_value;
5489 *tb = tstate->curexc_traceback;
5491 tstate->curexc_type = 0;
5492 tstate->curexc_value = 0;
5493 tstate->curexc_traceback = 0;
5498 #------------------------------------------------------------------------------------
5500 unraisable_exception_utility_code = UtilityCode(
5502 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5505 static void __Pyx_WriteUnraisable(const char *name) {
5506 PyObject *old_exc, *old_val, *old_tb;
5508 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5509 #if PY_MAJOR_VERSION < 3
5510 ctx = PyString_FromString(name);
5512 ctx = PyUnicode_FromString(name);
5514 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5516 PyErr_WriteUnraisable(Py_None);
5518 PyErr_WriteUnraisable(ctx);
5523 requires=[restore_exception_utility_code])
5525 #------------------------------------------------------------------------------------
5527 set_vtable_utility_code = UtilityCode(
5529 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5532 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5533 PyObject *pycobj = 0;
5536 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5539 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5552 #------------------------------------------------------------------------------------
5554 get_vtable_utility_code = UtilityCode(
5556 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5559 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5563 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5566 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5567 if (!*(void **)vtabptr)
5580 #------------------------------------------------------------------------------------
5582 init_string_tab_utility_code = UtilityCode(
5584 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5587 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5589 #if PY_MAJOR_VERSION < 3
5590 if (t->is_unicode && (!t->is_identifier)) {
5591 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5592 } else if (t->intern) {
5593 *t->p = PyString_InternFromString(t->s);
5595 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5597 #else /* Python 3+ has unicode identifiers */
5598 if (t->is_identifier || (t->is_unicode && t->intern)) {
5599 *t->p = PyUnicode_InternFromString(t->s);
5600 } else if (t->is_unicode) {
5601 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5603 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5614 #------------------------------------------------------------------------------------
5616 get_exception_utility_code = UtilityCode(
5618 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5621 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5622 PyObject *tmp_type, *tmp_value, *tmp_tb;
5623 PyThreadState *tstate = PyThreadState_GET();
5624 *type = tstate->curexc_type;
5625 *value = tstate->curexc_value;
5626 *tb = tstate->curexc_traceback;
5627 tstate->curexc_type = 0;
5628 tstate->curexc_value = 0;
5629 tstate->curexc_traceback = 0;
5630 PyErr_NormalizeException(type, value, tb);
5631 if (PyErr_Occurred())
5636 tmp_type = tstate->exc_type;
5637 tmp_value = tstate->exc_value;
5638 tmp_tb = tstate->exc_traceback;
5639 tstate->exc_type = *type;
5640 tstate->exc_value = *value;
5641 tstate->exc_traceback = *tb;
5642 /* Make sure tstate is in a consistent state when we XDECREF
5643 these objects (XDECREF may run arbitrary code). */
5644 Py_XDECREF(tmp_type);
5645 Py_XDECREF(tmp_value);
5657 #------------------------------------------------------------------------------------
5659 reset_exception_utility_code = UtilityCode(
5661 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5662 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5665 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5666 PyThreadState *tstate = PyThreadState_GET();
5667 *type = tstate->exc_type;
5668 *value = tstate->exc_value;
5669 *tb = tstate->exc_traceback;
5675 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5676 PyObject *tmp_type, *tmp_value, *tmp_tb;
5677 PyThreadState *tstate = PyThreadState_GET();
5678 tmp_type = tstate->exc_type;
5679 tmp_value = tstate->exc_value;
5680 tmp_tb = tstate->exc_traceback;
5681 tstate->exc_type = type;
5682 tstate->exc_value = value;
5683 tstate->exc_traceback = tb;
5684 Py_XDECREF(tmp_type);
5685 Py_XDECREF(tmp_value);
5690 #------------------------------------------------------------------------------------
5692 force_init_threads_utility_code = UtilityCode(
5694 #ifndef __PYX_FORCE_INIT_THREADS
5695 #if PY_VERSION_HEX < 0x02040200
5696 #define __PYX_FORCE_INIT_THREADS 1
5698 #define __PYX_FORCE_INIT_THREADS 0
5703 #------------------------------------------------------------------------------------