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 cname = arg_count_member)
555 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
556 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
557 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
558 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
563 cname = struct_cname)
564 self.op_args_struct.defined_in_pxd = 1
565 self.op_args_struct.used = 1
569 if return_type.is_pyobject \
570 and (self.exception_value or self.exception_check) \
571 and self.exception_check != '+':
573 "Exception clause not allowed for function returning Python object")
575 if self.exception_value:
576 self.exception_value.analyse_const_expression(env)
577 if self.exception_check == '+':
578 exc_val_type = self.exception_value.type
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.analyse_default_values(env)
1402 if self.py_func is not None:
1403 self.py_func.analyse_expressions(env)
1405 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1408 visibility = self.entry.visibility
1409 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1410 arg_decls.append(arg.declaration_code())
1411 if with_dispatch and self.overridable:
1412 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1413 if type.optional_arg_count and with_opt_args:
1414 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1415 if type.has_varargs:
1416 arg_decls.append("...")
1418 arg_decls = ["void"]
1420 cname = self.entry.func_cname
1421 entity = type.function_header_code(cname, ', '.join(arg_decls))
1422 if visibility == 'public':
1423 dll_linkage = "DL_EXPORT"
1426 header = self.return_type.declaration_code(entity,
1427 dll_linkage = dll_linkage)
1428 if visibility == 'extern':
1429 storage_class = "%s " % Naming.extern_c_macro
1430 elif visibility == 'public':
1433 storage_class = "static "
1434 code.putln("%s%s %s {" % (
1436 ' '.join(self.modifiers).upper(), # macro forms
1439 def generate_argument_declarations(self, env, code):
1440 for arg in self.args:
1442 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1444 def generate_keyword_list(self, code):
1447 def generate_argument_parsing_code(self, env, code):
1449 if self.type.optional_arg_count:
1450 code.putln('if (%s) {' % Naming.optional_args_cname)
1451 for arg in self.args:
1453 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1454 declarator = arg.declarator
1455 while not hasattr(declarator, 'name'):
1456 declarator = declarator.base
1457 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1459 for _ in range(self.type.optional_arg_count):
1463 def generate_argument_conversion_code(self, code):
1466 def generate_argument_type_tests(self, code):
1467 # Generate type tests for args whose type in a parent
1468 # class is a supertype of the declared type.
1469 for arg in self.type.args:
1470 if arg.needs_type_test:
1471 self.generate_arg_type_test(arg, code)
1473 def generate_arg_type_test(self, arg, code):
1474 # Generate type test for one argument.
1475 if arg.type.typeobj_is_available():
1476 typeptr_cname = arg.type.typeptr_cname
1477 arg_code = "((PyObject *)%s)" % arg.cname
1479 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1484 type.is_builtin_type,
1485 code.error_goto(arg.pos)))
1487 error(arg.pos, "Cannot test type of extern C class "
1488 "without type object name specification")
1490 def error_value(self):
1491 if self.return_type.is_pyobject:
1495 return self.entry.type.exception_value
1497 def caller_will_check_exceptions(self):
1498 return self.entry.type.exception_check
1500 def generate_wrapper_functions(self, code):
1501 # If the C signature of a function has changed, we need to generate
1502 # wrappers to put in the slots here.
1505 func_type = entry.type
1506 while entry.prev_entry is not None:
1508 entry = entry.prev_entry
1509 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1511 self.generate_function_header(code,
1513 with_dispatch = entry.type.is_overridable,
1514 with_opt_args = entry.type.optional_arg_count,
1515 cname = entry.func_cname)
1516 if not self.return_type.is_void:
1518 args = self.type.args
1519 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1520 if entry.type.is_overridable:
1521 arglist.append(Naming.skip_dispatch_cname)
1522 elif func_type.is_overridable:
1524 if entry.type.optional_arg_count:
1525 arglist.append(Naming.optional_args_cname)
1526 elif func_type.optional_arg_count:
1527 arglist.append('NULL')
1528 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1532 class PyArgDeclNode(Node):
1533 # Argument which must be a Python object (used
1534 # for * and ** arguments).
1537 # entry Symtab.Entry
1541 class DecoratorNode(Node):
1544 # decorator NameNode or CallNode
1545 child_attrs = ['decorator']
1548 class DefNode(FuncDefNode):
1549 # A Python function definition.
1551 # name string the Python name of the function
1552 # decorators [DecoratorNode] list of decorators
1553 # args [CArgDeclNode] formal arguments
1554 # star_arg PyArgDeclNode or None * argument
1555 # starstar_arg PyArgDeclNode or None ** argument
1556 # doc EncodedString or None
1559 # The following subnode is constructed internally
1560 # when the def statement is inside a Python class definition.
1562 # assmt AssignmentNode Function construction/assignment
1564 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1568 num_required_kw_args = 0
1569 reqd_kw_flags_cname = "0"
1575 def __init__(self, pos, **kwds):
1576 FuncDefNode.__init__(self, pos, **kwds)
1578 for arg in self.args:
1585 self.num_kwonly_args = k
1586 self.num_required_kw_args = rk
1587 self.num_required_args = r
1589 def as_cfunction(self, cfunc=None, scope=None):
1591 error(self.star_arg.pos, "cdef function cannot have star argument")
1592 if self.starstar_arg:
1593 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1596 for formal_arg in self.args:
1597 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1598 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1600 type = py_object_type,
1601 pos = formal_arg.pos))
1602 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1604 has_varargs = False,
1605 exception_value = None,
1606 exception_check = False,
1609 is_overridable = True)
1610 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1612 cfunc_type = cfunc.type
1613 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1614 error(self.pos, "wrong number of arguments")
1615 error(declarator.pos, "previous declaration here")
1616 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1617 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1618 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1619 formal_arg.type = type_arg.type
1620 formal_arg.name_declarator = name_declarator
1622 if cfunc_type.exception_value is None:
1623 exception_value = None
1625 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1626 declarator = CFuncDeclaratorNode(self.pos,
1627 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1629 has_varargs = False,
1630 exception_check = cfunc_type.exception_check,
1631 exception_value = exception_value,
1632 with_gil = cfunc_type.with_gil,
1633 nogil = cfunc_type.nogil)
1634 return CFuncDefNode(self.pos,
1636 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1637 declarator = declarator,
1640 overridable = cfunc_type.is_overridable,
1642 with_gil = cfunc_type.with_gil,
1643 nogil = cfunc_type.nogil,
1644 visibility = 'private',
1646 directive_locals = cfunc.directive_locals)
1648 def analyse_declarations(self, env):
1649 if 'locals' in env.directives:
1650 directive_locals = env.directives['locals']
1652 directive_locals = {}
1653 self.directive_locals = directive_locals
1654 for arg in self.args:
1655 if hasattr(arg, 'name'):
1657 name_declarator = None
1659 base_type = arg.base_type.analyse(env)
1660 name_declarator, type = \
1661 arg.declarator.analyse(base_type, env)
1662 arg.name = name_declarator.name
1663 if arg.name in directive_locals:
1664 type_node = directive_locals[arg.name]
1665 other_type = type_node.analyse_as_type(env)
1666 if other_type is None:
1667 error(type_node.pos, "Not a type")
1668 elif (type is not PyrexTypes.py_object_type
1669 and not type.same_as(other_type)):
1670 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1671 error(type_node.pos, "Previous declaration here")
1674 if name_declarator and name_declarator.cname:
1676 "Python function argument cannot have C name specification")
1677 arg.type = type.as_argument_type()
1679 arg.needs_conversion = 0
1680 arg.needs_type_test = 0
1682 if arg.not_none and not arg.type.is_extension_type:
1684 "Only extension type arguments can have 'not None'")
1685 self.declare_pyfunction(env)
1686 self.analyse_signature(env)
1687 self.return_type = self.entry.signature.return_type()
1689 def analyse_signature(self, env):
1690 any_type_tests_needed = 0
1691 # Use the simpler calling signature for zero- and one-argument functions.
1692 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1693 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1694 if len(self.args) == 0:
1695 self.entry.signature = TypeSlots.pyfunction_noargs
1696 elif len(self.args) == 1:
1697 if self.args[0].default is None and not self.args[0].kw_only:
1698 self.entry.signature = TypeSlots.pyfunction_onearg
1699 elif self.entry.signature is TypeSlots.pymethod_signature:
1700 if len(self.args) == 1:
1701 self.entry.signature = TypeSlots.unaryfunc
1702 elif len(self.args) == 2:
1703 if self.args[1].default is None and not self.args[1].kw_only:
1704 self.entry.signature = TypeSlots.ibinaryfunc
1705 elif self.entry.is_special:
1706 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1707 sig = self.entry.signature
1708 nfixed = sig.num_fixed_args()
1709 for i in range(nfixed):
1710 if i < len(self.args):
1713 if sig.is_self_arg(i):
1715 arg.hdr_type = arg.type = env.parent_type
1716 arg.needs_conversion = 0
1718 arg.hdr_type = sig.fixed_arg_type(i)
1719 if not arg.type.same_as(arg.hdr_type):
1720 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1721 arg.needs_type_test = 1
1722 any_type_tests_needed = 1
1724 arg.needs_conversion = 1
1725 if arg.needs_conversion:
1726 arg.hdr_cname = Naming.arg_prefix + arg.name
1728 arg.hdr_cname = Naming.var_prefix + arg.name
1730 self.bad_signature()
1732 if nfixed < len(self.args):
1733 if not sig.has_generic_args:
1734 self.bad_signature()
1735 for arg in self.args:
1736 if arg.is_generic and \
1737 (arg.type.is_extension_type or arg.type.is_builtin_type):
1738 arg.needs_type_test = 1
1739 any_type_tests_needed = 1
1740 if any_type_tests_needed:
1741 env.use_utility_code(arg_type_test_utility_code)
1743 def bad_signature(self):
1744 sig = self.entry.signature
1745 expected_str = "%d" % sig.num_fixed_args()
1746 if sig.has_generic_args:
1747 expected_str = expected_str + " or more"
1749 if name.startswith("__") and name.endswith("__"):
1750 desc = "Special method"
1754 "%s %s has wrong number of arguments "
1755 "(%d declared, %s expected)" % (
1756 desc, self.name, len(self.args), expected_str))
1758 def signature_has_nongeneric_args(self):
1759 argcount = len(self.args)
1760 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1764 def signature_has_generic_args(self):
1765 return self.entry.signature.has_generic_args
1767 def declare_pyfunction(self, env):
1768 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1770 entry = env.lookup_here(self.name)
1771 if entry and entry.type.is_cfunction and not self.is_wrapper:
1772 warning(self.pos, "Overriding cdef method with def method.", 5)
1773 entry = env.declare_pyfunction(self.name, self.pos)
1775 prefix = env.scope_prefix
1776 entry.func_cname = \
1777 Naming.pyfunc_prefix + prefix + name
1778 entry.pymethdef_cname = \
1779 Naming.pymethdef_prefix + prefix + name
1780 if Options.docstrings:
1781 entry.doc = embed_position(self.pos, self.doc)
1783 Naming.funcdoc_prefix + prefix + name
1787 def declare_arguments(self, env):
1788 for arg in self.args:
1790 error(arg.pos, "Missing argument name")
1791 if arg.needs_conversion:
1792 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1793 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1794 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1795 if arg.type.is_pyobject:
1796 arg.entry.init = "0"
1797 arg.entry.init_to_none = 0
1799 arg.entry = self.declare_argument(env, arg)
1801 arg.entry.is_self_arg = arg.is_self_arg
1802 if not arg.is_self_arg:
1803 arg.name_entry = env.get_string_const(
1804 arg.name, identifier = True)
1805 env.add_py_string(arg.name_entry, identifier = True)
1807 if arg.is_self_arg or \
1808 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1809 arg.entry.is_declared_generic = 1
1810 self.declare_python_arg(env, self.star_arg)
1811 self.declare_python_arg(env, self.starstar_arg)
1813 def declare_python_arg(self, env, arg):
1815 entry = env.declare_var(arg.name,
1816 PyrexTypes.py_object_type, arg.pos)
1819 entry.init_to_none = 0
1820 entry.xdecref_cleanup = 1
1822 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1824 def analyse_expressions(self, env):
1825 self.analyse_default_values(env)
1826 if env.is_py_class_scope:
1827 self.synthesize_assignment_node(env)
1829 def synthesize_assignment_node(self, env):
1831 self.assmt = SingleAssignmentNode(self.pos,
1832 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1833 rhs = ExprNodes.UnboundMethodNode(self.pos,
1834 class_cname = env.class_obj_cname,
1835 function = ExprNodes.PyCFunctionNode(self.pos,
1836 pymethdef_cname = self.entry.pymethdef_cname)))
1837 self.assmt.analyse_declarations(env)
1838 self.assmt.analyse_expressions(env)
1840 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1842 sig = self.entry.signature
1843 if sig.has_dummy_arg:
1844 arg_code_list.append(
1845 "PyObject *%s" % Naming.self_cname)
1846 for arg in self.args:
1847 if not arg.is_generic:
1849 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1851 arg_code_list.append(
1852 arg.hdr_type.declaration_code(arg.hdr_cname))
1853 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1854 arg_code_list.append("PyObject *unused")
1855 if sig.has_generic_args:
1856 arg_code_list.append(
1857 "PyObject *%s, PyObject *%s"
1858 % (Naming.args_cname, Naming.kwds_cname))
1859 arg_code = ", ".join(arg_code_list)
1860 dc = self.return_type.declaration_code(self.entry.func_cname)
1861 header = "static %s(%s)" % (dc, arg_code)
1862 code.putln("%s; /*proto*/" % header)
1865 if self.entry.doc and Options.docstrings:
1866 docstr = self.entry.doc
1867 if not isinstance(docstr, str):
1868 docstr = docstr.utf8encode()
1870 'static char %s[] = "%s";' % (
1871 self.entry.doc_cname,
1872 split_docstring(escape_byte_string(docstr))))
1875 "static PyMethodDef %s = " %
1876 self.entry.pymethdef_cname)
1877 code.put_pymethoddef(self.entry, ";")
1878 code.putln("%s {" % header)
1880 def generate_argument_declarations(self, env, code):
1881 for arg in self.args:
1882 if arg.is_generic: # or arg.needs_conversion:
1883 if arg.needs_conversion:
1884 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1886 code.put_var_declaration(arg.entry)
1888 def generate_keyword_list(self, code):
1889 if self.signature_has_generic_args() and \
1890 self.signature_has_nongeneric_args():
1892 "static PyObject **%s[] = {" %
1893 Naming.pykwdlist_cname)
1894 for arg in self.args:
1896 code.put('&%s,' % arg.name_entry.pystring_cname)
1899 def generate_argument_parsing_code(self, env, code):
1900 # Generate PyArg_ParseTuple call for generic
1901 # arguments, if any.
1902 if self.entry.signature.has_dummy_arg:
1903 # get rid of unused argument warning
1904 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1906 old_error_label = code.new_error_label()
1907 our_error_label = code.error_label
1908 end_label = code.new_label("argument_unpacking_done")
1910 has_kwonly_args = self.num_kwonly_args > 0
1911 has_star_or_kw_args = self.star_arg is not None \
1912 or self.starstar_arg is not None or has_kwonly_args
1914 if not self.signature_has_generic_args():
1915 if has_star_or_kw_args:
1916 error(self.pos, "This method cannot have * or keyword arguments")
1917 self.generate_argument_conversion_code(code)
1919 elif not self.signature_has_nongeneric_args():
1920 # func(*args) or func(**kw) or func(*args, **kw)
1921 self.generate_stararg_copy_code(code)
1924 positional_args = []
1927 for arg in self.args:
1928 arg_entry = arg.entry
1932 if not arg.is_self_arg:
1934 kw_only_args.append(arg)
1936 positional_args.append(arg)
1938 kw_only_args.append(arg)
1941 error(arg.pos, "Non-default argument following default argument")
1942 elif not arg.is_self_arg:
1943 positional_args.append(arg)
1945 self.generate_tuple_and_keyword_parsing_code(
1946 positional_args, kw_only_args, end_label, code)
1948 code.error_label = old_error_label
1949 if code.label_used(our_error_label):
1950 if not code.label_used(end_label):
1951 code.put_goto(end_label)
1952 code.put_label(our_error_label)
1953 if has_star_or_kw_args:
1954 self.generate_arg_decref(self.star_arg, code)
1955 if self.starstar_arg:
1956 if self.starstar_arg.entry.xdecref_cleanup:
1957 code.put_var_xdecref(self.starstar_arg.entry)
1959 code.put_var_decref(self.starstar_arg.entry)
1960 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1961 code.putln("return %s;" % self.error_value())
1962 if code.label_used(end_label):
1963 code.put_label(end_label)
1965 def generate_arg_assignment(self, arg, item, code):
1966 if arg.type.is_pyobject:
1968 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1969 code.putln("%s = %s;" % (arg.entry.cname, item))
1971 func = arg.type.from_py_function
1973 code.putln("%s = %s(%s); %s" % (
1977 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1979 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1981 def generate_arg_xdecref(self, arg, code):
1983 code.put_var_xdecref(arg.entry)
1985 def generate_arg_decref(self, arg, code):
1987 code.put_var_decref(arg.entry)
1989 def generate_stararg_copy_code(self, code):
1990 if not self.star_arg:
1991 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1992 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1994 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1995 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1998 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2000 if self.starstar_arg:
2002 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2004 kwarg_check = "%s" % Naming.kwds_cname
2006 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2007 Naming.kwds_cname, Naming.kwds_cname)
2009 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2010 kwarg_check, Naming.kwds_cname, self.name,
2011 bool(self.starstar_arg), self.error_value()))
2013 if self.starstar_arg:
2014 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2015 self.starstar_arg.entry.cname,
2018 code.putln("if (unlikely(!%s)) return %s;" % (
2019 self.starstar_arg.entry.cname, self.error_value()))
2020 self.starstar_arg.entry.xdecref_cleanup = 0
2021 code.put_gotref(self.starstar_arg.entry.cname)
2025 code.put_incref(Naming.args_cname, py_object_type)
2026 code.putln("%s = %s;" % (
2027 self.star_arg.entry.cname,
2029 self.star_arg.entry.xdecref_cleanup = 0
2031 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2032 kw_only_args, success_label, code):
2033 argtuple_error_label = code.new_label("argtuple_error")
2035 min_positional_args = self.num_required_args - self.num_required_kw_args
2036 if len(self.args) > 0 and self.args[0].is_self_arg:
2037 min_positional_args -= 1
2038 max_positional_args = len(positional_args)
2039 has_fixed_positional_count = not self.star_arg and \
2040 min_positional_args == max_positional_args
2042 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2043 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2044 if self.num_required_kw_args:
2045 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2047 if self.starstar_arg or self.star_arg:
2048 self.generate_stararg_init_code(max_positional_args, code)
2050 # --- optimised code when we receive keyword arguments
2051 if self.num_required_kw_args:
2052 likely_hint = "likely"
2054 likely_hint = "unlikely"
2055 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2056 self.generate_keyword_unpacking_code(
2057 min_positional_args, max_positional_args,
2058 has_fixed_positional_count,
2059 positional_args, kw_only_args, argtuple_error_label, code)
2061 # --- optimised code when we do not receive any keyword arguments
2062 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2063 # Python raises arg tuple related errors first, so we must
2064 # check the length here
2065 if min_positional_args == max_positional_args and not self.star_arg:
2069 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2070 Naming.args_cname, compare, min_positional_args))
2071 code.put_goto(argtuple_error_label)
2073 if self.num_required_kw_args:
2074 # pure error case: keywords required but not passed
2075 if max_positional_args > min_positional_args and not self.star_arg:
2076 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2077 Naming.args_cname, max_positional_args))
2078 code.put_goto(argtuple_error_label)
2079 code.putln('} else {')
2080 for i, arg in enumerate(kw_only_args):
2082 # required keyword-only argument missing
2083 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2084 self.name.utf8encode(),
2085 arg.name_entry.pystring_cname))
2086 code.putln(code.error_goto(self.pos))
2089 elif min_positional_args == max_positional_args:
2090 # parse the exact number of positional arguments from the
2092 code.putln('} else {')
2093 for i, arg in enumerate(positional_args):
2094 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2095 self.generate_arg_assignment(arg, item, code)
2096 self.generate_arg_default_assignments(code)
2099 # parse the positional arguments from the variable length
2101 code.putln('} else {')
2102 self.generate_arg_default_assignments(code)
2103 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2105 code.putln('default:')
2106 reversed_args = list(enumerate(positional_args))[::-1]
2107 for i, arg in reversed_args:
2108 if i >= min_positional_args-1:
2109 if min_positional_args > 1:
2110 code.putln('case %2d:' % (i+1)) # pure code beautification
2112 code.put('case %2d: ' % (i+1))
2113 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2114 self.generate_arg_assignment(arg, item, code)
2115 if min_positional_args == 0:
2116 code.put('case 0: ')
2117 code.putln('break;')
2119 if min_positional_args:
2120 for i in range(min_positional_args-1, -1, -1):
2121 code.putln('case %2d:' % i)
2122 code.put_goto(argtuple_error_label)
2124 code.put('default: ')
2125 code.put_goto(argtuple_error_label)
2130 if code.label_used(argtuple_error_label):
2131 code.put_goto(success_label)
2132 code.put_label(argtuple_error_label)
2133 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2134 self.name.utf8encode(), has_fixed_positional_count,
2135 min_positional_args, max_positional_args,
2137 code.putln(code.error_goto(self.pos))
2139 def generate_arg_default_assignments(self, code):
2140 for arg in self.args:
2141 if arg.is_generic and arg.default:
2145 arg.default_result_code))
2147 def generate_stararg_init_code(self, max_positional_args, code):
2148 if self.starstar_arg:
2149 self.starstar_arg.entry.xdecref_cleanup = 0
2150 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2151 self.starstar_arg.entry.cname,
2152 self.starstar_arg.entry.cname,
2153 self.error_value()))
2154 code.put_gotref(self.starstar_arg.entry.cname)
2156 self.star_arg.entry.xdecref_cleanup = 0
2157 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2159 max_positional_args))
2160 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2161 self.star_arg.entry.cname, Naming.args_cname,
2162 max_positional_args, Naming.args_cname))
2163 code.put_gotref(self.star_arg.entry.cname)
2164 if self.starstar_arg:
2166 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2167 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2168 code.putln('return %s;' % self.error_value())
2171 code.putln("if (unlikely(!%s)) return %s;" % (
2172 self.star_arg.entry.cname, self.error_value()))
2173 code.putln('} else {')
2174 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2175 code.put_incref(Naming.empty_tuple, py_object_type)
2178 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2179 has_fixed_positional_count, positional_args,
2180 kw_only_args, argtuple_error_label, code):
2181 all_args = tuple(positional_args) + tuple(kw_only_args)
2182 max_args = len(all_args)
2185 for i, arg in enumerate(all_args):
2186 if arg.default and arg.type.is_pyobject:
2187 default_value = arg.default_result_code
2188 if arg.type is not PyrexTypes.py_object_type:
2189 default_value = "(PyObject*)"+default_value
2190 default_args.append((i, default_value))
2192 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2194 # it looks funny to separate the init-to-0 from setting the
2195 # default value, but C89 needs this
2196 code.putln("PyObject* values[%d] = {%s};" % (
2197 max_args, ','.join(['0']*max_args)))
2198 for i, default_value in default_args:
2199 code.putln('values[%d] = %s;' % (i, default_value))
2201 # parse the tuple and check that it's not too long
2202 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2204 code.putln('default:')
2205 for i in range(max_positional_args-1, -1, -1):
2206 code.put('case %2d: ' % (i+1))
2207 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2208 i, Naming.args_cname, i))
2209 code.putln('case 0: break;')
2210 if not self.star_arg:
2211 code.put('default: ') # more arguments than allowed
2212 code.put_goto(argtuple_error_label)
2215 # now fill up the positional/required arguments with values
2217 if self.num_required_args or max_positional_args > 0:
2218 last_required_arg = -1
2219 for i, arg in enumerate(all_args):
2221 last_required_arg = i
2222 if last_required_arg < max_positional_args:
2223 last_required_arg = max_positional_args-1
2224 num_required_args = self.num_required_args
2225 if max_positional_args > 0:
2226 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2227 for i, arg in enumerate(all_args[:last_required_arg+1]):
2228 if max_positional_args > 0 and i <= max_positional_args:
2229 if self.star_arg and i == max_positional_args:
2230 code.putln('default:')
2232 code.putln('case %2d:' % i)
2235 # handled separately below
2237 code.putln('if (kw_args > %d) {' % num_required_args)
2238 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2239 Naming.kwds_cname, arg.name_entry.pystring_cname))
2240 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2243 num_required_args -= 1
2244 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2245 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2246 code.putln('if (likely(values[%d])) kw_args--;' % i);
2247 if i < min_positional_args:
2249 # special case: we know arg 0 is missing
2251 code.put_goto(argtuple_error_label)
2253 # print the correct number of values (args or
2254 # kwargs) that were passed into positional
2255 # arguments up to this point
2256 code.putln('else {')
2257 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2258 self.name.utf8encode(), has_fixed_positional_count,
2259 min_positional_args, max_positional_args, i))
2260 code.putln(code.error_goto(self.pos))
2263 code.putln('else {')
2264 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2265 self.name.utf8encode(), arg.name_entry.pystring_cname))
2266 code.putln(code.error_goto(self.pos))
2268 if max_positional_args > 0:
2271 if kw_only_args and not self.starstar_arg:
2272 # unpack optional keyword-only arguments
2273 # checking for interned strings in a dict is faster than iterating
2274 # but it's too likely that we must iterate if we expect **kwargs
2276 for i, arg in enumerate(all_args[max_positional_args:]):
2277 if not arg.kw_only or not arg.default:
2279 optional_args.append((i+max_positional_args, arg))
2281 # this mimics an unrolled loop so that we can "break" out of it
2282 code.putln('while (kw_args > 0) {')
2283 code.putln('PyObject* value;')
2284 for i, arg in optional_args:
2286 'value = PyDict_GetItem(%s, %s);' % (
2287 Naming.kwds_cname, arg.name_entry.pystring_cname))
2289 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2290 code.putln('break;')
2293 code.putln('if (unlikely(kw_args > 0)) {')
2294 # non-positional/-required kw args left in dict: default args,
2295 # kw-only args, **kwargs or error
2297 # This is sort of a catch-all: except for checking required
2298 # arguments, this will always do the right thing for unpacking
2299 # keyword arguments, so that we can concentrate on optimising
2300 # common cases above.
2301 if max_positional_args == 0:
2304 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2305 Naming.args_cname, max_positional_args,
2306 Naming.args_cname, max_positional_args))
2307 pos_arg_count = "used_pos_args"
2309 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2310 code.globalstate.use_utility_code(parse_keywords_utility_code)
2312 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2314 Naming.pykwdlist_cname,
2315 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2317 self.name.utf8encode()))
2318 code.putln(code.error_goto(self.pos))
2321 # convert arg values to their final type and assign them
2322 for i, arg in enumerate(all_args):
2323 if arg.default and not arg.type.is_pyobject:
2324 code.putln("if (values[%d]) {" % i)
2325 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2326 if arg.default and not arg.type.is_pyobject:
2327 code.putln('} else {')
2331 arg.default_result_code))
2334 def generate_argument_conversion_code(self, code):
2335 # Generate code to convert arguments from
2336 # signature type to declared type, if needed.
2337 for arg in self.args:
2338 if arg.needs_conversion:
2339 self.generate_arg_conversion(arg, code)
2341 def generate_arg_conversion(self, arg, code):
2342 # Generate conversion code for one argument.
2343 old_type = arg.hdr_type
2345 if old_type.is_pyobject:
2347 code.putln("if (%s) {" % arg.hdr_cname)
2349 code.putln("assert(%s); {" % arg.hdr_cname)
2350 self.generate_arg_conversion_from_pyobject(arg, code)
2352 elif new_type.is_pyobject:
2353 self.generate_arg_conversion_to_pyobject(arg, code)
2355 if new_type.assignable_from(old_type):
2357 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2360 "Cannot convert 1 argument from '%s' to '%s'" %
2361 (old_type, new_type))
2363 def generate_arg_conversion_from_pyobject(self, arg, code):
2365 func = new_type.from_py_function
2366 # copied from CoerceFromPyTypeNode
2368 code.putln("%s = %s(%s); %s" % (
2372 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2375 "Cannot convert Python object argument to type '%s'"
2378 def generate_arg_conversion_to_pyobject(self, arg, code):
2379 old_type = arg.hdr_type
2380 func = old_type.to_py_function
2382 code.putln("%s = %s(%s); %s" % (
2386 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2387 code.put_var_gotref(arg.entry)
2390 "Cannot convert argument of type '%s' to Python object"
2393 def generate_argument_type_tests(self, code):
2394 # Generate type tests for args whose signature
2395 # type is PyObject * and whose declared type is
2396 # a subtype thereof.
2397 for arg in self.args:
2398 if arg.needs_type_test:
2399 self.generate_arg_type_test(arg, code)
2401 def generate_arg_type_test(self, arg, code):
2402 # Generate type test for one argument.
2403 if arg.type.typeobj_is_available():
2404 typeptr_cname = arg.type.typeptr_cname
2405 arg_code = "((PyObject *)%s)" % arg.entry.cname
2407 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2412 arg.type.is_builtin_type,
2413 code.error_goto(arg.pos)))
2415 error(arg.pos, "Cannot test type of extern C class "
2416 "without type object name specification")
2418 def error_value(self):
2419 return self.entry.signature.error_value
2421 def caller_will_check_exceptions(self):
2424 class OverrideCheckNode(StatNode):
2425 # A Node for dispatching to the def method if it
2434 child_attrs = ['body']
2438 def analyse_expressions(self, env):
2439 self.args = env.arg_entries
2440 if self.py_func.is_module_scope:
2445 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2446 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2447 call_node = ExprNodes.SimpleCallNode(self.pos,
2448 function=self.func_node,
2449 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2450 self.body = ReturnStatNode(self.pos, value=call_node)
2451 self.body.analyse_expressions(env)
2453 def generate_execution_code(self, code):
2454 # Check to see if we are an extension type
2455 if self.py_func.is_module_scope:
2456 self_arg = "((PyObject *)%s)" % Naming.module_cname
2458 self_arg = "((PyObject *)%s)" % self.args[0].cname
2459 code.putln("/* Check if called by wrapper */")
2460 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2461 code.putln("/* Check if overriden in Python */")
2462 if self.py_func.is_module_scope:
2463 code.putln("else {")
2465 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2466 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2467 # need to get attribute manually--scope would return cdef method
2468 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2469 code.put_gotref(self.func_node.py_result())
2470 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2471 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2472 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2473 self.body.generate_execution_code(code)
2475 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2478 class ClassDefNode(StatNode, BlockNode):
2481 class PyClassDefNode(ClassDefNode):
2482 # A Python class definition.
2484 # name EncodedString Name of the class
2485 # doc string or None
2486 # body StatNode Attribute definition code
2487 # entry Symtab.Entry
2488 # scope PyClassScope
2490 # The following subnodes are constructed internally:
2492 # dict DictNode Class dictionary
2493 # classobj ClassNode Class object
2494 # target NameNode Variable to assign class object to
2496 child_attrs = ["body", "dict", "classobj", "target"]
2498 def __init__(self, pos, name, bases, doc, body):
2499 StatNode.__init__(self, pos)
2504 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2505 if self.doc and Options.docstrings:
2506 doc = embed_position(self.pos, self.doc)
2507 doc_node = ExprNodes.StringNode(pos, value = doc)
2510 self.classobj = ExprNodes.ClassNode(pos, name = name,
2511 bases = bases, dict = self.dict, doc = doc_node)
2512 self.target = ExprNodes.NameNode(pos, name = name)
2514 def as_cclass(self):
2516 Return this node as if it were declared as an extension class
2518 bases = self.classobj.bases.args
2520 base_class_name = None
2521 base_class_module = None
2522 elif len(bases) == 1:
2525 from ExprNodes import AttributeNode, NameNode
2526 while isinstance(base, AttributeNode):
2527 path.insert(0, base.attribute)
2529 if isinstance(base, NameNode):
2530 path.insert(0, base.name)
2531 base_class_name = path[-1]
2533 base_class_module = u'.'.join(path[:-1])
2535 base_class_module = None
2537 error(self.classobj.bases.args.pos, "Invalid base class")
2539 error(self.classobj.bases.args.pos, "C class may only have one base class")
2542 return CClassDefNode(self.pos,
2543 visibility = 'private',
2545 class_name = self.name,
2546 base_class_module = base_class_module,
2547 base_class_name = base_class_name,
2552 def create_scope(self, env):
2554 while env.is_py_class_scope or env.is_c_class_scope:
2555 env = env.outer_scope
2556 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2559 def analyse_declarations(self, env):
2560 self.target.analyse_target_declaration(env)
2561 cenv = self.create_scope(env)
2562 cenv.class_obj_cname = self.target.entry.cname
2563 self.body.analyse_declarations(cenv)
2565 def analyse_expressions(self, env):
2566 self.dict.analyse_expressions(env)
2567 self.classobj.analyse_expressions(env)
2568 genv = env.global_scope()
2570 cenv.class_dict_cname = self.dict.result()
2571 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2572 self.body.analyse_expressions(cenv)
2573 self.target.analyse_target_expression(env, self.classobj)
2574 self.dict.release_temp(env)
2575 #self.classobj.release_temp(env)
2576 #self.target.release_target_temp(env)
2578 def generate_function_definitions(self, env, code):
2579 self.generate_py_string_decls(self.scope, code)
2580 self.body.generate_function_definitions(self.scope, code)
2582 def generate_execution_code(self, code):
2583 self.dict.generate_evaluation_code(code)
2584 self.classobj.generate_evaluation_code(code)
2585 self.body.generate_execution_code(code)
2586 self.target.generate_assignment_code(self.classobj, code)
2587 self.dict.generate_disposal_code(code)
2588 self.dict.free_temps(code)
2591 class CClassDefNode(ClassDefNode):
2592 # An extension type definition.
2594 # visibility 'private' or 'public' or 'extern'
2595 # typedef_flag boolean
2597 # module_name string or None For import of extern type objects
2598 # class_name string Unqualified name of class
2599 # as_name string or None Name to declare as in this scope
2600 # base_class_module string or None Module containing the base class
2601 # base_class_name string or None Name of the base class
2602 # objstruct_name string or None Specified C name of object struct
2603 # typeobj_name string or None Specified C name of type object
2604 # in_pxd boolean Is in a .pxd file
2605 # doc string or None
2606 # body StatNode or None
2607 # entry Symtab.Entry
2608 # base_type PyExtensionType or None
2609 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2610 # buffer_defaults_pos
2612 child_attrs = ["body"]
2613 buffer_defaults_node = None
2614 buffer_defaults_pos = None
2615 typedef_flag = False
2617 objstruct_name = None
2620 def analyse_declarations(self, env):
2621 #print "CClassDefNode.analyse_declarations:", self.class_name
2622 #print "...visibility =", self.visibility
2623 #print "...module_name =", self.module_name
2626 if self.buffer_defaults_node:
2627 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2628 env, [], self.buffer_defaults_node,
2629 need_complete=False)
2631 buffer_defaults = None
2633 if env.in_cinclude and not self.objstruct_name:
2634 error(self.pos, "Object struct name specification required for "
2635 "C class defined in 'extern from' block")
2636 self.base_type = None
2637 # Now that module imports are cached, we need to
2638 # import the modules for extern classes.
2639 if self.module_name:
2641 for module in env.cimported_modules:
2642 if module.name == self.module_name:
2643 self.module = module
2644 if self.module is None:
2645 self.module = ModuleScope(self.module_name, None, env.context)
2646 self.module.has_extern_class = 1
2647 env.add_imported_module(self.module)
2649 if self.base_class_name:
2650 if self.base_class_module:
2651 base_class_scope = env.find_module(self.base_class_module, self.pos)
2653 base_class_scope = env
2654 if self.base_class_name == 'object':
2655 # extension classes are special and don't need to inherit from object
2656 if base_class_scope is None or base_class_scope.lookup('object') is None:
2657 self.base_class_name = None
2658 self.base_class_module = None
2659 base_class_scope = None
2660 if base_class_scope:
2661 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2662 if base_class_entry:
2663 if not base_class_entry.is_type:
2664 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2665 elif not base_class_entry.type.is_extension_type:
2666 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2667 elif not base_class_entry.type.is_complete():
2668 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2670 self.base_type = base_class_entry.type
2671 has_body = self.body is not None
2672 if self.module_name and self.visibility != 'extern':
2673 module_path = self.module_name.split(".")
2674 home_scope = env.find_imported_module(module_path, self.pos)
2680 if self.visibility == 'extern':
2681 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2682 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2684 self.entry = home_scope.declare_c_class(
2685 name = self.class_name,
2687 defining = has_body and self.in_pxd,
2688 implementing = has_body and not self.in_pxd,
2689 module_name = self.module_name,
2690 base_type = self.base_type,
2691 objstruct_cname = self.objstruct_name,
2692 typeobj_cname = self.typeobj_name,
2693 visibility = self.visibility,
2694 typedef_flag = self.typedef_flag,
2696 buffer_defaults = buffer_defaults)
2697 if home_scope is not env and self.visibility == 'extern':
2698 env.add_imported_entry(self.class_name, self.entry, pos)
2699 scope = self.entry.type.scope
2701 if self.doc and Options.docstrings:
2702 scope.doc = embed_position(self.pos, self.doc)
2705 self.body.analyse_declarations(scope)
2709 scope.implemented = 1
2710 env.allocate_vtable_names(self.entry)
2712 def analyse_expressions(self, env):
2714 scope = self.entry.type.scope
2715 self.body.analyse_expressions(scope)
2717 def generate_function_definitions(self, env, code):
2718 self.generate_py_string_decls(self.entry.type.scope, code)
2720 self.body.generate_function_definitions(
2721 self.entry.type.scope, code)
2723 def generate_execution_code(self, code):
2724 # This is needed to generate evaluation code for
2725 # default values of method arguments.
2727 self.body.generate_execution_code(code)
2729 def annotate(self, code):
2731 self.body.annotate(code)
2734 class PropertyNode(StatNode):
2735 # Definition of a property in an extension type.
2738 # doc EncodedString or None Doc string
2741 child_attrs = ["body"]
2743 def analyse_declarations(self, env):
2744 entry = env.declare_property(self.name, self.doc, self.pos)
2746 if self.doc and Options.docstrings:
2747 doc_entry = env.get_string_const(
2748 self.doc, identifier = False)
2749 entry.doc_cname = doc_entry.cname
2750 self.body.analyse_declarations(entry.scope)
2752 def analyse_expressions(self, env):
2753 self.body.analyse_expressions(env)
2755 def generate_function_definitions(self, env, code):
2756 self.body.generate_function_definitions(env, code)
2758 def generate_execution_code(self, code):
2761 def annotate(self, code):
2762 self.body.annotate(code)
2765 class GlobalNode(StatNode):
2766 # Global variable declaration.
2772 def analyse_declarations(self, env):
2773 for name in self.names:
2774 env.declare_global(name, self.pos)
2776 def analyse_expressions(self, env):
2779 def generate_execution_code(self, code):
2783 class ExprStatNode(StatNode):
2784 # Expression used as a statement.
2788 child_attrs = ["expr"]
2790 def analyse_declarations(self, env):
2792 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2793 func = self.expr.function.as_cython_attribute()
2794 if func == u'declare':
2795 args, kwds = self.expr.explicit_args_kwds()
2797 error(self.expr.pos, "Variable names must be specified.")
2798 for var, type_node in kwds.key_value_pairs:
2799 type = type_node.analyse_as_type(env)
2801 error(type_node.pos, "Unknown type")
2803 env.declare_var(var.value, type, var.pos, is_cdef = True)
2804 self.__class__ = PassStatNode
2806 def analyse_expressions(self, env):
2807 self.expr.analyse_expressions(env)
2808 self.expr.release_temp(env)
2810 def generate_execution_code(self, code):
2811 self.expr.generate_evaluation_code(code)
2812 if not self.expr.is_temp and self.expr.result():
2813 code.putln("%s;" % self.expr.result())
2814 self.expr.generate_disposal_code(code)
2815 self.expr.free_temps(code)
2817 def annotate(self, code):
2818 self.expr.annotate(code)
2821 class AssignmentNode(StatNode):
2822 # Abstract base class for assignment nodes.
2824 # The analyse_expressions and generate_execution_code
2825 # phases of assignments are split into two sub-phases
2826 # each, to enable all the right hand sides of a
2827 # parallel assignment to be evaluated before assigning
2828 # to any of the left hand sides.
2830 def analyse_expressions(self, env):
2831 self.analyse_types(env)
2832 self.allocate_rhs_temps(env)
2833 self.allocate_lhs_temps(env)
2835 # def analyse_expressions(self, env):
2836 # self.analyse_expressions_1(env)
2837 # self.analyse_expressions_2(env)
2839 def generate_execution_code(self, code):
2840 self.generate_rhs_evaluation_code(code)
2841 self.generate_assignment_code(code)
2844 class SingleAssignmentNode(AssignmentNode):
2845 # The simplest case:
2849 # lhs ExprNode Left hand side
2850 # rhs ExprNode Right hand side
2851 # first bool Is this guaranteed the first assignment to lhs?
2853 child_attrs = ["lhs", "rhs"]
2855 declaration_only = False
2857 def analyse_declarations(self, env):
2860 # handle declarations of the form x = cython.foo()
2861 if isinstance(self.rhs, ExprNodes.CallNode):
2862 func_name = self.rhs.function.as_cython_attribute()
2864 args, kwds = self.rhs.explicit_args_kwds()
2866 if func_name in ['declare', 'typedef']:
2867 if len(args) > 2 or kwds is not None:
2868 error(rhs.pos, "Can only declare one type at a time.")
2870 type = args[0].analyse_as_type(env)
2872 error(args[0].pos, "Unknown type")
2875 if func_name == 'declare':
2876 if isinstance(lhs, ExprNodes.NameNode):
2877 vars = [(lhs.name, lhs.pos)]
2878 elif isinstance(lhs, ExprNodes.TupleNode):
2879 vars = [(var.name, var.pos) for var in lhs.args]
2881 error(lhs.pos, "Invalid declaration")
2883 for var, pos in vars:
2884 env.declare_var(var, type, pos, is_cdef = True)
2889 self.declaration_only = True
2891 self.declaration_only = True
2892 if not isinstance(lhs, ExprNodes.NameNode):
2893 error(lhs.pos, "Invalid declaration.")
2894 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2896 elif func_name in ['struct', 'union']:
2897 self.declaration_only = True
2898 if len(args) > 0 or kwds is None:
2899 error(rhs.pos, "Struct or union members must be given by name.")
2902 for member, type_node in kwds.key_value_pairs:
2903 type = type_node.analyse_as_type(env)
2905 error(type_node.pos, "Unknown type")
2907 members.append((member.value, type, member.pos))
2908 if len(members) < len(kwds.key_value_pairs):
2910 if not isinstance(self.lhs, ExprNodes.NameNode):
2911 error(self.lhs.pos, "Invalid declaration.")
2912 name = self.lhs.name
2913 scope = StructOrUnionScope(name)
2914 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2915 for member, type, pos in members:
2916 scope.declare_var(member, type, pos)
2918 if self.declaration_only:
2921 self.lhs.analyse_target_declaration(env)
2923 def analyse_types(self, env, use_temp = 0):
2924 self.rhs.analyse_types(env)
2925 self.lhs.analyse_target_types(env)
2926 self.lhs.gil_assignment_check(env)
2927 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2929 self.rhs = self.rhs.coerce_to_temp(env)
2931 def allocate_rhs_temps(self, env):
2932 self.rhs.allocate_temps(env)
2934 def allocate_lhs_temps(self, env):
2935 self.lhs.allocate_target_temps(env, self.rhs)
2936 #self.lhs.release_target_temp(env)
2937 #self.rhs.release_temp(env)
2939 def generate_rhs_evaluation_code(self, code):
2940 self.rhs.generate_evaluation_code(code)
2942 def generate_assignment_code(self, code):
2943 self.lhs.generate_assignment_code(self.rhs, code)
2945 def annotate(self, code):
2946 self.lhs.annotate(code)
2947 self.rhs.annotate(code)
2950 class CascadedAssignmentNode(AssignmentNode):
2951 # An assignment with multiple left hand sides:
2955 # lhs_list [ExprNode] Left hand sides
2956 # rhs ExprNode Right hand sides
2960 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2962 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2963 coerced_rhs_list = None
2965 def analyse_declarations(self, env):
2966 for lhs in self.lhs_list:
2967 lhs.analyse_target_declaration(env)
2969 def analyse_types(self, env, use_temp = 0):
2970 self.rhs.analyse_types(env)
2972 self.rhs = self.rhs.coerce_to_temp(env)
2974 self.rhs = self.rhs.coerce_to_simple(env)
2975 from ExprNodes import CloneNode
2976 self.coerced_rhs_list = []
2977 for lhs in self.lhs_list:
2978 lhs.analyse_target_types(env)
2979 lhs.gil_assignment_check(env)
2980 rhs = CloneNode(self.rhs)
2981 rhs = rhs.coerce_to(lhs.type, env)
2982 self.coerced_rhs_list.append(rhs)
2984 def allocate_rhs_temps(self, env):
2985 self.rhs.allocate_temps(env)
2987 def allocate_lhs_temps(self, env):
2988 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2989 rhs.allocate_temps(env)
2990 lhs.allocate_target_temps(env, rhs)
2991 #lhs.release_target_temp(env)
2992 #rhs.release_temp(env)
2993 self.rhs.release_temp(env)
2995 def generate_rhs_evaluation_code(self, code):
2996 self.rhs.generate_evaluation_code(code)
2998 def generate_assignment_code(self, code):
2999 for i in range(len(self.lhs_list)):
3000 lhs = self.lhs_list[i]
3001 rhs = self.coerced_rhs_list[i]
3002 rhs.generate_evaluation_code(code)
3003 lhs.generate_assignment_code(rhs, code)
3004 # Assignment has disposed of the cloned RHS
3005 self.rhs.generate_disposal_code(code)
3006 self.rhs.free_temps(code)
3008 def annotate(self, code):
3009 for i in range(len(self.lhs_list)):
3010 lhs = self.lhs_list[i].annotate(code)
3011 rhs = self.coerced_rhs_list[i].annotate(code)
3012 self.rhs.annotate(code)
3015 class ParallelAssignmentNode(AssignmentNode):
3016 # A combined packing/unpacking assignment:
3020 # This has been rearranged by the parser into
3022 # a = d ; b = e ; c = f
3024 # but we must evaluate all the right hand sides
3025 # before assigning to any of the left hand sides.
3027 # stats [AssignmentNode] The constituent assignments
3029 child_attrs = ["stats"]
3031 def analyse_declarations(self, env):
3032 for stat in self.stats:
3033 stat.analyse_declarations(env)
3035 def analyse_expressions(self, env):
3036 for stat in self.stats:
3037 stat.analyse_types(env, use_temp = 1)
3038 stat.allocate_rhs_temps(env)
3039 for stat in self.stats:
3040 stat.allocate_lhs_temps(env)
3042 # def analyse_expressions(self, env):
3043 # for stat in self.stats:
3044 # stat.analyse_expressions_1(env, use_temp = 1)
3045 # for stat in self.stats:
3046 # stat.analyse_expressions_2(env)
3048 def generate_execution_code(self, code):
3049 for stat in self.stats:
3050 stat.generate_rhs_evaluation_code(code)
3051 for stat in self.stats:
3052 stat.generate_assignment_code(code)
3054 def annotate(self, code):
3055 for stat in self.stats:
3059 class InPlaceAssignmentNode(AssignmentNode):
3060 # An in place arithmatic operand:
3066 # lhs ExprNode Left hand side
3067 # rhs ExprNode Right hand side
3068 # op char one of "+-*/%^&|"
3069 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3071 # This code is a bit tricky because in order to obey Python
3072 # semantics the sub-expressions (e.g. indices) of the lhs must
3073 # not be evaluated twice. So we must re-use the values calculated
3074 # in evaluation phase for the assignment phase as well.
3075 # Fortunately, the type of the lhs node is fairly constrained
3076 # (it must be a NameNode, AttributeNode, or IndexNode).
3078 child_attrs = ["lhs", "rhs"]
3081 def analyse_declarations(self, env):
3082 self.lhs.analyse_target_declaration(env)
3084 def analyse_types(self, env):
3085 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3086 self.rhs.analyse_types(env)
3087 self.lhs.analyse_target_types(env)
3088 if Options.incref_local_binop and self.dup.type.is_pyobject:
3089 self.dup = self.dup.coerce_to_temp(env)
3091 def allocate_rhs_temps(self, env):
3093 if self.lhs.type.is_pyobject:
3094 self.rhs = self.rhs.coerce_to_pyobject(env)
3095 elif self.rhs.type.is_pyobject:
3096 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3097 if self.lhs.type.is_pyobject:
3098 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3099 self.result_value.allocate_temps(env)
3101 # self.rhs = self.rhs.coerce_to_temp(env)
3102 self.rhs.allocate_temps(env)
3103 self.dup.allocate_subexpr_temps(env)
3104 self.dup.allocate_temp(env)
3106 def allocate_lhs_temps(self, env):
3107 self.lhs.allocate_target_temps(env, self.rhs)
3108 # self.lhs.release_target_temp(env)
3109 self.dup.release_temp(env)
3110 if self.dup.is_temp:
3111 self.dup.release_subexpr_temps(env)
3112 # self.rhs.release_temp(env)
3113 if self.lhs.type.is_pyobject:
3114 self.result_value.release_temp(env)
3116 def generate_execution_code(self, code):
3118 self.rhs.generate_evaluation_code(code)
3119 self.dup.generate_subexpr_evaluation_code(code)
3120 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3121 # This is because we're manually messing with subexpr nodes
3122 if self.dup.is_temp:
3123 self.dup.allocate_temp_result(code)
3124 # self.dup.generate_result_code is run only if it is not buffer access
3125 if self.operator == "**":
3129 if self.lhs.type.is_pyobject:
3130 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3131 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3132 self.dup.generate_result_code(code)
3134 "%s = %s(%s, %s%s); %s" % (
3135 self.result_value.result(),
3136 self.py_operation_function(),
3137 self.dup.py_result(),
3138 self.rhs.py_result(),
3140 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3141 code.put_gotref(self.result_value.py_result())
3142 self.result_value.generate_evaluation_code(code) # May be a type check...
3143 self.rhs.generate_disposal_code(code)
3144 self.rhs.free_temps(code)
3145 self.dup.generate_disposal_code(code)
3146 self.dup.free_temps(code)
3147 self.lhs.generate_assignment_code(self.result_value, code)
3149 c_op = self.operator
3153 if self.lhs.type.is_int and self.rhs.type.is_int:
3154 error(self.pos, "** with two C int types is ambiguous")
3156 error(self.pos, "No C inplace power operator")
3157 # have to do assignment directly to avoid side-effects
3158 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3159 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3161 self.dup.generate_result_code(code)
3162 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3163 self.rhs.generate_disposal_code(code)
3164 self.rhs.free_temps(code)
3165 if self.dup.is_temp:
3166 self.dup.generate_subexpr_disposal_code(code)
3167 self.dup.free_subexpr_temps(code)
3169 def create_dup_node(self, env):
3172 self.dup.analyse_types(env)
3173 if isinstance(self.lhs, ExprNodes.NameNode):
3174 target_lhs = ExprNodes.NameNode(self.dup.pos,
3175 name = self.dup.name,
3176 is_temp = self.dup.is_temp,
3177 entry = self.dup.entry)
3178 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3179 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3180 obj = ExprNodes.CloneNode(self.lhs.obj),
3181 attribute = self.dup.attribute,
3182 is_temp = self.dup.is_temp)
3183 elif isinstance(self.lhs, ExprNodes.IndexNode):
3185 index = ExprNodes.CloneNode(self.lhs.index)
3188 if self.lhs.indices:
3189 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3192 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3193 base = ExprNodes.CloneNode(self.dup.base),
3196 is_temp = self.dup.is_temp)
3199 self.lhs = target_lhs
3202 def py_operation_function(self):
3203 return self.py_functions[self.operator]
3206 "|": "PyNumber_InPlaceOr",
3207 "^": "PyNumber_InPlaceXor",
3208 "&": "PyNumber_InPlaceAnd",
3209 "+": "PyNumber_InPlaceAdd",
3210 "-": "PyNumber_InPlaceSubtract",
3211 "*": "PyNumber_InPlaceMultiply",
3212 "/": "PyNumber_InPlaceDivide",
3213 "%": "PyNumber_InPlaceRemainder",
3214 "<<": "PyNumber_InPlaceLshift",
3215 ">>": "PyNumber_InPlaceRshift",
3216 "**": "PyNumber_InPlacePower",
3217 "//": "PyNumber_InPlaceFloorDivide",
3220 def annotate(self, code):
3221 self.lhs.annotate(code)
3222 self.rhs.annotate(code)
3223 self.dup.annotate(code)
3226 class PrintStatNode(StatNode):
3229 # arg_tuple TupleNode
3230 # append_newline boolean
3232 child_attrs = ["arg_tuple"]
3234 def analyse_expressions(self, env):
3235 self.arg_tuple.analyse_expressions(env)
3236 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3237 self.arg_tuple.release_temp(env)
3238 env.use_utility_code(printing_utility_code)
3239 if len(self.arg_tuple.args) == 1 and self.append_newline:
3240 env.use_utility_code(printing_one_utility_code)
3243 gil_message = "Python print statement"
3245 def generate_execution_code(self, code):
3246 if len(self.arg_tuple.args) == 1 and self.append_newline:
3247 arg = self.arg_tuple.args[0]
3248 arg.generate_evaluation_code(code)
3251 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3253 code.error_goto(self.pos)))
3254 arg.generate_disposal_code(code)
3255 arg.free_temps(code)
3257 self.arg_tuple.generate_evaluation_code(code)
3259 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3260 self.arg_tuple.py_result(),
3261 self.append_newline,
3262 code.error_goto(self.pos)))
3263 self.arg_tuple.generate_disposal_code(code)
3264 self.arg_tuple.free_temps(code)
3266 def annotate(self, code):
3267 self.arg_tuple.annotate(code)
3270 class ExecStatNode(StatNode):
3275 child_attrs = ["args"]
3277 def analyse_expressions(self, env):
3278 for i, arg in enumerate(self.args):
3279 arg.analyse_expressions(env)
3280 arg = arg.coerce_to_pyobject(env)
3281 arg.release_temp(env)
3283 self.temp_result = env.allocate_temp_pyobject()
3284 env.release_temp(self.temp_result)
3285 env.use_utility_code(Builtin.pyexec_utility_code)
3288 gil_message = "Python exec statement"
3290 def generate_execution_code(self, code):
3292 for arg in self.args:
3293 arg.generate_evaluation_code(code)
3294 args.append( arg.py_result() )
3295 args = tuple(args + ['0', '0'][:3-len(args)])
3296 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3297 (self.temp_result,) + args))
3298 for arg in self.args:
3299 arg.generate_disposal_code(code)
3300 arg.free_temps(code)
3302 code.error_goto_if_null(self.temp_result, self.pos))
3303 code.put_gotref(self.temp_result)
3304 code.put_decref_clear(self.temp_result, py_object_type)
3306 def annotate(self, code):
3307 for arg in self.args:
3311 class DelStatNode(StatNode):
3316 child_attrs = ["args"]
3318 def analyse_declarations(self, env):
3319 for arg in self.args:
3320 arg.analyse_target_declaration(env)
3322 def analyse_expressions(self, env):
3323 for arg in self.args:
3324 arg.analyse_target_expression(env, None)
3325 if arg.type.is_pyobject:
3328 error(arg.pos, "Deletion of non-Python object")
3329 #arg.release_target_temp(env)
3331 gil_message = "Deleting Python object"
3333 def generate_execution_code(self, code):
3334 for arg in self.args:
3335 if arg.type.is_pyobject:
3336 arg.generate_deletion_code(code)
3337 # else error reported earlier
3339 def annotate(self, code):
3340 for arg in self.args:
3344 class PassStatNode(StatNode):
3349 def analyse_expressions(self, env):
3352 def generate_execution_code(self, code):
3356 class BreakStatNode(StatNode):
3360 def analyse_expressions(self, env):
3363 def generate_execution_code(self, code):
3364 if not code.break_label:
3365 error(self.pos, "break statement not inside loop")
3367 code.put_goto(code.break_label)
3370 class ContinueStatNode(StatNode):
3374 def analyse_expressions(self, env):
3377 def generate_execution_code(self, code):
3378 if code.funcstate.in_try_finally:
3379 error(self.pos, "continue statement inside try of try...finally")
3380 elif not code.continue_label:
3381 error(self.pos, "continue statement not inside loop")
3383 code.put_goto(code.continue_label)
3386 class ReturnStatNode(StatNode):
3389 # value ExprNode or None
3390 # return_type PyrexType
3391 # temps_in_use [Entry] Temps in use at time of return
3393 child_attrs = ["value"]
3395 def analyse_expressions(self, env):
3396 return_type = env.return_type
3397 self.return_type = return_type
3398 self.temps_in_use = env.temps_in_use()
3400 error(self.pos, "Return not inside a function body")
3403 self.value.analyse_types(env)
3404 if return_type.is_void or return_type.is_returncode:
3405 error(self.value.pos,
3406 "Return with value in void function")
3408 self.value = self.value.coerce_to(env.return_type, env)
3409 self.value.allocate_temps(env)
3410 self.value.release_temp(env)
3412 if (not return_type.is_void
3413 and not return_type.is_pyobject
3414 and not return_type.is_returncode):
3415 error(self.pos, "Return value required")
3416 if return_type.is_pyobject:
3419 gil_message = "Returning Python object"
3421 def generate_execution_code(self, code):
3422 code.mark_pos(self.pos)
3423 if not self.return_type:
3424 # error reported earlier
3426 if self.return_type.is_pyobject:
3427 code.put_xdecref(Naming.retval_cname,
3430 self.value.generate_evaluation_code(code)
3431 self.value.make_owned_reference(code)
3434 Naming.retval_cname,
3435 self.value.result_as(self.return_type)))
3436 self.value.generate_post_assignment_code(code)
3437 self.value.free_temps(code)
3439 if self.return_type.is_pyobject:
3440 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3441 elif self.return_type.is_returncode:
3444 Naming.retval_cname,
3445 self.return_type.default_value))
3446 # free temps the old way
3447 for entry in self.temps_in_use:
3448 code.put_var_decref_clear(entry)
3449 # free temps the new way
3450 for cname, type in code.funcstate.temps_holding_reference():
3451 code.put_decref_clear(cname, type)
3454 # code.return_label)
3455 code.put_goto(code.return_label)
3457 def annotate(self, code):
3459 self.value.annotate(code)
3462 class RaiseStatNode(StatNode):
3465 # exc_type ExprNode or None
3466 # exc_value ExprNode or None
3467 # exc_tb ExprNode or None
3469 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3471 def analyse_expressions(self, env):
3473 self.exc_type.analyse_types(env)
3474 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3475 self.exc_type.allocate_temps(env)
3477 self.exc_value.analyse_types(env)
3478 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3479 self.exc_value.allocate_temps(env)
3481 self.exc_tb.analyse_types(env)
3482 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3483 self.exc_tb.allocate_temps(env)
3485 self.exc_type.release_temp(env)
3487 self.exc_value.release_temp(env)
3489 self.exc_tb.release_temp(env)
3490 env.use_utility_code(raise_utility_code)
3491 env.use_utility_code(restore_exception_utility_code)
3494 gil_message = "Raising exception"
3496 def generate_execution_code(self, code):
3498 self.exc_type.generate_evaluation_code(code)
3499 type_code = self.exc_type.py_result()
3503 self.exc_value.generate_evaluation_code(code)
3504 value_code = self.exc_value.py_result()
3508 self.exc_tb.generate_evaluation_code(code)
3509 tb_code = self.exc_tb.py_result()
3512 if self.exc_type or self.exc_value or self.exc_tb:
3514 "__Pyx_Raise(%s, %s, %s);" % (
3521 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3523 obj.generate_disposal_code(code)
3524 obj.free_temps(code)
3526 code.error_goto(self.pos))
3528 def annotate(self, code):
3530 self.exc_type.annotate(code)
3532 self.exc_value.annotate(code)
3534 self.exc_tb.annotate(code)
3537 class ReraiseStatNode(StatNode):
3541 def analyse_expressions(self, env):
3543 env.use_utility_code(raise_utility_code)
3544 env.use_utility_code(restore_exception_utility_code)
3546 gil_message = "Raising exception"
3548 def generate_execution_code(self, code):
3549 vars = code.funcstate.exc_vars
3551 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3552 code.putln(code.error_goto(self.pos))
3554 error(self.pos, "Reraise not inside except clause")
3557 class AssertStatNode(StatNode):
3561 # value ExprNode or None
3563 child_attrs = ["cond", "value"]
3565 def analyse_expressions(self, env):
3566 self.cond = self.cond.analyse_boolean_expression(env)
3568 self.value.analyse_types(env)
3569 self.value = self.value.coerce_to_pyobject(env)
3570 self.value.allocate_temps(env)
3571 self.cond.release_temp(env)
3573 self.value.release_temp(env)
3575 #env.recycle_pending_temps() # TEMPORARY
3577 gil_message = "Raising exception"
3579 def generate_execution_code(self, code):
3580 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3581 self.cond.generate_evaluation_code(code)
3583 "if (unlikely(!%s)) {" %
3586 self.value.generate_evaluation_code(code)
3588 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3589 self.value.py_result())
3590 self.value.generate_disposal_code(code)
3591 self.value.free_temps(code)
3594 "PyErr_SetNone(PyExc_AssertionError);")
3596 code.error_goto(self.pos))
3599 self.cond.generate_disposal_code(code)
3600 self.cond.free_temps(code)
3601 code.putln("#endif")
3603 def annotate(self, code):
3604 self.cond.annotate(code)
3606 self.value.annotate(code)
3609 class IfStatNode(StatNode):
3612 # if_clauses [IfClauseNode]
3613 # else_clause StatNode or None
3615 child_attrs = ["if_clauses", "else_clause"]
3617 def analyse_control_flow(self, env):
3618 env.start_branching(self.pos)
3619 for if_clause in self.if_clauses:
3620 if_clause.analyse_control_flow(env)
3621 env.next_branch(if_clause.end_pos())
3622 if self.else_clause:
3623 self.else_clause.analyse_control_flow(env)
3624 env.finish_branching(self.end_pos())
3626 def analyse_declarations(self, env):
3627 for if_clause in self.if_clauses:
3628 if_clause.analyse_declarations(env)
3629 if self.else_clause:
3630 self.else_clause.analyse_declarations(env)
3632 def analyse_expressions(self, env):
3633 for if_clause in self.if_clauses:
3634 if_clause.analyse_expressions(env)
3635 if self.else_clause:
3636 self.else_clause.analyse_expressions(env)
3638 def generate_execution_code(self, code):
3639 code.mark_pos(self.pos)
3640 end_label = code.new_label()
3641 for if_clause in self.if_clauses:
3642 if_clause.generate_execution_code(code, end_label)
3643 if self.else_clause:
3644 code.putln("/*else*/ {")
3645 self.else_clause.generate_execution_code(code)
3647 code.put_label(end_label)
3649 def annotate(self, code):
3650 for if_clause in self.if_clauses:
3651 if_clause.annotate(code)
3652 if self.else_clause:
3653 self.else_clause.annotate(code)
3656 class IfClauseNode(Node):
3657 # if or elif clause in an if statement
3659 # condition ExprNode
3662 child_attrs = ["condition", "body"]
3664 def analyse_control_flow(self, env):
3665 self.body.analyse_control_flow(env)
3667 def analyse_declarations(self, env):
3668 self.condition.analyse_declarations(env)
3669 self.body.analyse_declarations(env)
3671 def analyse_expressions(self, env):
3673 self.condition.analyse_temp_boolean_expression(env)
3674 self.condition.release_temp(env)
3675 self.body.analyse_expressions(env)
3677 def generate_execution_code(self, code, end_label):
3678 self.condition.generate_evaluation_code(code)
3681 self.condition.result())
3682 self.condition.generate_disposal_code(code)
3683 self.condition.free_temps(code)
3684 self.body.generate_execution_code(code)
3688 code.put_goto(end_label)
3691 def annotate(self, code):
3692 self.condition.annotate(code)
3693 self.body.annotate(code)
3696 class SwitchCaseNode(StatNode):
3697 # Generated in the optimization of an if-elif-else node
3699 # conditions [ExprNode]
3702 child_attrs = ['conditions', 'body']
3704 def generate_execution_code(self, code):
3705 for cond in self.conditions:
3706 code.mark_pos(cond.pos)
3707 code.putln("case %s:" % cond.calculate_result_code())
3708 self.body.generate_execution_code(code)
3709 code.putln("break;")
3711 def annotate(self, code):
3712 for cond in self.conditions:
3714 self.body.annotate(code)
3716 class SwitchStatNode(StatNode):
3717 # Generated in the optimization of an if-elif-else node
3720 # cases [SwitchCaseNode]
3721 # else_clause StatNode or None
3723 child_attrs = ['test', 'cases', 'else_clause']
3725 def generate_execution_code(self, code):
3726 code.putln("switch (%s) {" % self.test.calculate_result_code())
3727 for case in self.cases:
3728 case.generate_execution_code(code)
3729 if self.else_clause is not None:
3730 code.putln("default:")
3731 self.else_clause.generate_execution_code(code)
3732 code.putln("break;")
3735 def annotate(self, code):
3736 self.test.annotate(code)
3737 for case in self.cases:
3739 if self.else_clause is not None:
3740 self.else_clause.annotate(code)
3742 class LoopNode(object):
3744 def analyse_control_flow(self, env):
3745 env.start_branching(self.pos)
3746 self.body.analyse_control_flow(env)
3747 env.next_branch(self.body.end_pos())
3748 if self.else_clause:
3749 self.else_clause.analyse_control_flow(env)
3750 env.finish_branching(self.end_pos())
3753 class WhileStatNode(LoopNode, StatNode):
3756 # condition ExprNode
3758 # else_clause StatNode
3760 child_attrs = ["condition", "body", "else_clause"]
3762 def analyse_declarations(self, env):
3763 self.body.analyse_declarations(env)
3764 if self.else_clause:
3765 self.else_clause.analyse_declarations(env)
3767 def analyse_expressions(self, env):
3769 self.condition.analyse_temp_boolean_expression(env)
3770 self.condition.release_temp(env)
3771 #env.recycle_pending_temps() # TEMPORARY
3772 self.body.analyse_expressions(env)
3773 if self.else_clause:
3774 self.else_clause.analyse_expressions(env)
3776 def generate_execution_code(self, code):
3777 old_loop_labels = code.new_loop_labels()
3780 self.condition.generate_evaluation_code(code)
3781 self.condition.generate_disposal_code(code)
3784 self.condition.result())
3785 self.condition.free_temps(code)
3786 self.body.generate_execution_code(code)
3787 code.put_label(code.continue_label)
3789 break_label = code.break_label
3790 code.set_loop_labels(old_loop_labels)
3791 if self.else_clause:
3792 code.putln("/*else*/ {")
3793 self.else_clause.generate_execution_code(code)
3795 code.put_label(break_label)
3797 def annotate(self, code):
3798 self.condition.annotate(code)
3799 self.body.annotate(code)
3800 if self.else_clause:
3801 self.else_clause.annotate(code)
3804 def ForStatNode(pos, **kw):
3805 if 'iterator' in kw:
3806 return ForInStatNode(pos, **kw)
3808 return ForFromStatNode(pos, **kw)
3810 class ForInStatNode(LoopNode, StatNode):
3814 # iterator IteratorNode
3816 # else_clause StatNode
3817 # item NextNode used internally
3819 child_attrs = ["target", "iterator", "body", "else_clause"]
3822 def analyse_declarations(self, env):
3823 self.target.analyse_target_declaration(env)
3824 self.body.analyse_declarations(env)
3825 if self.else_clause:
3826 self.else_clause.analyse_declarations(env)
3828 def analyse_expressions(self, env):
3830 self.target.analyse_target_types(env)
3831 self.iterator.analyse_expressions(env)
3832 self.item = ExprNodes.NextNode(self.iterator, env)
3833 self.item = self.item.coerce_to(self.target.type, env)
3834 self.item.allocate_temps(env)
3835 self.target.allocate_target_temps(env, self.item)
3836 #self.item.release_temp(env)
3837 #self.target.release_target_temp(env)
3838 self.body.analyse_expressions(env)
3839 if self.else_clause:
3840 self.else_clause.analyse_expressions(env)
3841 self.iterator.release_temp(env)
3843 def generate_execution_code(self, code):
3844 old_loop_labels = code.new_loop_labels()
3845 self.iterator.allocate_counter_temp(code)
3846 self.iterator.generate_evaluation_code(code)
3849 self.item.generate_evaluation_code(code)
3850 self.target.generate_assignment_code(self.item, code)
3851 self.body.generate_execution_code(code)
3852 code.put_label(code.continue_label)
3855 break_label = code.break_label
3856 code.set_loop_labels(old_loop_labels)
3857 if self.else_clause:
3858 code.putln("/*else*/ {")
3859 self.else_clause.generate_execution_code(code)
3861 code.put_label(break_label)
3862 self.iterator.release_counter_temp(code)
3863 self.iterator.generate_disposal_code(code)
3864 self.iterator.free_temps(code)
3866 def annotate(self, code):
3867 self.target.annotate(code)
3868 self.iterator.annotate(code)
3869 self.body.annotate(code)
3870 if self.else_clause:
3871 self.else_clause.annotate(code)
3872 self.item.annotate(code)
3875 class ForFromStatNode(LoopNode, StatNode):
3876 # for name from expr rel name rel expr
3883 # step ExprNode or None
3885 # else_clause StatNode or None
3890 # loopvar_node ExprNode (usually a NameNode or temp node)
3891 # py_loopvar_node PyTempNode or None
3892 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3894 is_py_target = False
3896 py_loopvar_node = None
3898 def analyse_declarations(self, env):
3899 self.target.analyse_target_declaration(env)
3900 self.body.analyse_declarations(env)
3901 if self.else_clause:
3902 self.else_clause.analyse_declarations(env)
3904 def analyse_expressions(self, env):
3906 self.target.analyse_target_types(env)
3907 self.bound1.analyse_types(env)
3908 self.bound2.analyse_types(env)
3909 if self.target.type.is_numeric:
3910 self.bound1 = self.bound1.coerce_to(self.target.type, env)
3911 self.bound2 = self.bound2.coerce_to(self.target.type, env)
3913 self.bound1 = self.bound1.coerce_to_integer(env)
3914 self.bound2 = self.bound2.coerce_to_integer(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)
3919 self.step = self.step.coerce_to_integer(env)
3920 if not (self.bound2.is_name or self.bound2.is_literal):
3921 self.bound2 = self.bound2.coerce_to_temp(env)
3922 target_type = self.target.type
3923 if not (target_type.is_pyobject or target_type.is_numeric):
3924 error(self.target.pos,
3925 "Integer for-loop variable must be of type int or Python object")
3926 #if not (target_type.is_pyobject
3927 # or target_type.assignable_from(PyrexTypes.c_int_type)):
3928 # error(self.target.pos,
3929 # "Cannot assign integer to variable of type '%s'" % target_type)
3930 if target_type.is_numeric:
3931 self.is_py_target = 0
3932 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3933 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3934 self.loopvar_node = self.target
3935 self.py_loopvar_node = None
3937 self.is_py_target = 1
3938 c_loopvar_node = ExprNodes.TempNode(self.pos,
3939 PyrexTypes.c_long_type, env)
3940 c_loopvar_node.allocate_temps(env)
3941 self.loopvar_node = c_loopvar_node
3942 self.py_loopvar_node = \
3943 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3944 self.bound1.allocate_temps(env)
3945 self.bound2.allocate_temps(env)
3946 if self.step is not None:
3947 self.step.allocate_temps(env)
3948 if self.is_py_target:
3949 self.py_loopvar_node.allocate_temps(env)
3950 self.target.allocate_target_temps(env, self.py_loopvar_node)
3951 #self.target.release_target_temp(env)
3952 #self.py_loopvar_node.release_temp(env)
3953 self.body.analyse_expressions(env)
3954 if self.is_py_target:
3955 c_loopvar_node.release_temp(env)
3956 if self.else_clause:
3957 self.else_clause.analyse_expressions(env)
3958 self.bound1.release_temp(env)
3959 self.bound2.release_temp(env)
3960 if self.step is not None:
3961 self.step.release_temp(env)
3963 def generate_execution_code(self, code):
3964 old_loop_labels = code.new_loop_labels()
3965 from_range = getattr(self, "from_range", False)
3966 self.bound1.generate_evaluation_code(code)
3967 self.bound2.generate_evaluation_code(code)
3968 offset, incop = self.relation_table[self.relation1]
3973 if self.step is not None:
3974 self.step.generate_evaluation_code(code)
3975 step = self.step.result()
3976 incop = "%s=%s" % (incop[0], step)
3977 decop = "%s=%s" % (decop[0], step)
3978 loopvar_name = self.loopvar_node.result()
3980 range_bound = code.funcstate.allocate_temp(self.bound2.type, manage_ref=False)
3981 code.putln("%s = %s;" % (range_bound, self.bound2.result()))
3982 # Skip the loop entirely (and avoid assigning to the loopvar) if
3983 # the loop is empty:
3984 code.putln("if (%s%s %s %s) {" % (
3985 self.bound1.result(), offset, self.relation2, range_bound
3988 range_bound = self.bound2.result()
3990 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3992 self.bound1.result(), offset,
3993 loopvar_name, self.relation2, range_bound,
3994 loopvar_name, incop))
3995 if self.py_loopvar_node:
3996 self.py_loopvar_node.generate_evaluation_code(code)
3997 self.target.generate_assignment_code(self.py_loopvar_node, code)
3998 self.body.generate_execution_code(code)
3999 code.put_label(code.continue_label)
4001 # Undo last increment to maintain Python semantics:
4002 code.putln("} %s%s;" % (loopvar_name, decop))
4003 # End the outer if statement:
4004 code.putln("} /* end if */")
4005 code.funcstate.release_temp(range_bound)
4008 break_label = code.break_label
4009 code.set_loop_labels(old_loop_labels)
4010 if self.else_clause:
4011 code.putln("/*else*/ {")
4012 self.else_clause.generate_execution_code(code)
4014 code.put_label(break_label)
4015 self.bound1.generate_disposal_code(code)
4016 self.bound1.free_temps(code)
4017 self.bound2.generate_disposal_code(code)
4018 self.bound2.free_temps(code)
4019 if self.step is not None:
4020 self.step.generate_disposal_code(code)
4021 self.step.free_temps(code)
4024 # {relop : (initial offset, increment op)}
4031 def annotate(self, code):
4032 self.target.annotate(code)
4033 self.bound1.annotate(code)
4034 self.bound2.annotate(code)
4036 self.bound2.annotate(code)
4037 self.body.annotate(code)
4038 if self.else_clause:
4039 self.else_clause.annotate(code)
4042 class WithStatNode(StatNode):
4044 Represents a Python with statement.
4046 This is only used at parse tree level; and is not present in
4047 analysis or generation phases.
4049 # manager The with statement manager object
4050 # target Node (lhs expression)
4052 child_attrs = ["manager", "target", "body"]
4054 class TryExceptStatNode(StatNode):
4055 # try .. except statement
4058 # except_clauses [ExceptClauseNode]
4059 # else_clause StatNode or None
4060 # cleanup_list [Entry] old style temps to clean up on error
4062 child_attrs = ["body", "except_clauses", "else_clause"]
4064 def analyse_control_flow(self, env):
4065 env.start_branching(self.pos)
4066 self.body.analyse_control_flow(env)
4067 successful_try = env.control_flow # grab this for later
4068 env.next_branch(self.body.end_pos())
4069 env.finish_branching(self.body.end_pos())
4071 env.start_branching(self.except_clauses[0].pos)
4072 for except_clause in self.except_clauses:
4073 except_clause.analyse_control_flow(env)
4074 env.next_branch(except_clause.end_pos())
4076 # the else cause it executed only when the try clause finishes
4077 env.control_flow.incoming = successful_try
4078 if self.else_clause:
4079 self.else_clause.analyse_control_flow(env)
4080 env.finish_branching(self.end_pos())
4082 def analyse_declarations(self, env):
4083 self.body.analyse_declarations(env)
4084 for except_clause in self.except_clauses:
4085 except_clause.analyse_declarations(env)
4086 if self.else_clause:
4087 self.else_clause.analyse_declarations(env)
4089 env.use_utility_code(reset_exception_utility_code)
4091 def analyse_expressions(self, env):
4092 self.body.analyse_expressions(env)
4093 self.cleanup_list = env.free_temp_entries[:]
4094 default_clause_seen = 0
4095 for except_clause in self.except_clauses:
4096 except_clause.analyse_expressions(env)
4097 if default_clause_seen:
4098 error(except_clause.pos, "default 'except:' must be last")
4099 if not except_clause.pattern:
4100 default_clause_seen = 1
4101 self.has_default_clause = default_clause_seen
4102 if self.else_clause:
4103 self.else_clause.analyse_expressions(env)
4106 gil_message = "Try-except statement"
4108 def generate_execution_code(self, code):
4109 old_return_label = code.return_label
4110 old_break_label = code.break_label
4111 old_continue_label = code.continue_label
4112 old_error_label = code.new_error_label()
4113 our_error_label = code.error_label
4114 except_end_label = code.new_label('exception_handled')
4115 except_error_label = code.new_label('except_error')
4116 except_return_label = code.new_label('except_return')
4117 try_return_label = code.new_label('try_return')
4118 try_break_label = code.new_label('try_break')
4119 try_continue_label = code.new_label('try_continue')
4120 try_end_label = code.new_label('try_end')
4123 code.putln("PyObject %s;" %
4124 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4125 code.putln("__Pyx_ExceptionSave(%s);" %
4126 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4127 for var in Naming.exc_save_vars:
4128 code.put_xgotref(var)
4131 code.return_label = try_return_label
4132 code.break_label = try_break_label
4133 code.continue_label = try_continue_label
4134 self.body.generate_execution_code(code)
4137 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4138 code.error_label = except_error_label
4139 code.return_label = except_return_label
4140 if self.else_clause:
4143 self.else_clause.generate_execution_code(code)
4146 for var in Naming.exc_save_vars:
4147 code.put_xdecref_clear(var, py_object_type)
4148 code.put_goto(try_end_label)
4149 if code.label_used(try_return_label):
4150 code.put_label(try_return_label)
4151 for var in Naming.exc_save_vars:
4152 code.put_xdecref_clear(var, py_object_type)
4153 code.put_goto(old_return_label)
4154 code.put_label(our_error_label)
4155 code.put_var_xdecrefs_clear(self.cleanup_list)
4156 for temp_name, type in temps_to_clean_up:
4157 code.put_xdecref_clear(temp_name, type)
4158 for except_clause in self.except_clauses:
4159 except_clause.generate_handling_code(code, except_end_label)
4161 error_label_used = code.label_used(except_error_label)
4162 if error_label_used or not self.has_default_clause:
4163 if error_label_used:
4164 code.put_label(except_error_label)
4165 for var in Naming.exc_save_vars:
4166 code.put_xdecref(var, py_object_type)
4167 code.put_goto(old_error_label)
4169 if code.label_used(try_break_label):
4170 code.put_label(try_break_label)
4171 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4172 code.putln("__Pyx_ExceptionReset(%s);" %
4173 ', '.join(Naming.exc_save_vars))
4174 code.put_goto(old_break_label)
4176 if code.label_used(try_continue_label):
4177 code.put_label(try_continue_label)
4178 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4179 code.putln("__Pyx_ExceptionReset(%s);" %
4180 ', '.join(Naming.exc_save_vars))
4181 code.put_goto(old_continue_label)
4183 if code.label_used(except_return_label):
4184 code.put_label(except_return_label)
4185 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4186 code.putln("__Pyx_ExceptionReset(%s);" %
4187 ', '.join(Naming.exc_save_vars))
4188 code.put_goto(old_return_label)
4190 if code.label_used(except_end_label):
4191 code.put_label(except_end_label)
4192 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4193 code.putln("__Pyx_ExceptionReset(%s);" %
4194 ', '.join(Naming.exc_save_vars))
4195 code.put_label(try_end_label)
4198 code.return_label = old_return_label
4199 code.break_label = old_break_label
4200 code.continue_label = old_continue_label
4201 code.error_label = old_error_label
4203 def annotate(self, code):
4204 self.body.annotate(code)
4205 for except_node in self.except_clauses:
4206 except_node.annotate(code)
4207 if self.else_clause:
4208 self.else_clause.annotate(code)
4211 class ExceptClauseNode(Node):
4212 # Part of try ... except statement.
4215 # target ExprNode or None
4217 # excinfo_target NameNode or None optional target for exception info
4218 # match_flag string result of exception match
4219 # exc_value ExcValueNode used internally
4220 # function_name string qualified name of enclosing function
4221 # exc_vars (string * 3) local exception variables
4223 # excinfo_target is never set by the parser, but can be set by a transform
4224 # in order to extract more extensive information about the exception as a
4225 # sys.exc_info()-style tuple into a target variable
4227 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4230 excinfo_target = None
4232 def analyse_declarations(self, env):
4234 self.target.analyse_target_declaration(env)
4235 if self.excinfo_target is not None:
4236 self.excinfo_target.analyse_target_declaration(env)
4237 self.body.analyse_declarations(env)
4239 def analyse_expressions(self, env):
4241 genv = env.global_scope()
4242 self.function_name = env.qualified_name
4244 self.pattern.analyse_expressions(env)
4245 self.pattern = self.pattern.coerce_to_pyobject(env)
4246 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4247 self.pattern.release_temp(env)
4248 env.release_temp(self.match_flag)
4250 if self.target or self.excinfo_target:
4251 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4253 self.exc_vars = None
4256 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4257 self.exc_value.allocate_temps(env)
4258 self.target.analyse_target_expression(env, self.exc_value)
4259 if self.excinfo_target is not None:
4261 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4262 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4263 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4264 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4266 self.excinfo_tuple.analyse_expressions(env)
4267 self.excinfo_tuple.allocate_temps(env)
4268 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4270 self.body.analyse_expressions(env)
4273 for var in self.exc_vars:
4274 env.release_temp(var)
4276 def generate_handling_code(self, code, end_label):
4277 code.mark_pos(self.pos)
4279 self.pattern.generate_evaluation_code(code)
4281 "%s = PyErr_ExceptionMatches(%s);" % (
4283 self.pattern.py_result()))
4284 self.pattern.generate_disposal_code(code)
4285 self.pattern.free_temps(code)
4290 code.putln("/*except:*/ {")
4293 exc_vars = self.exc_vars
4294 elif not getattr(self.body, 'stats', True):
4295 # most simple case: no exception variable, empty body (pass)
4296 # => reset the exception state, done
4297 code.putln("PyErr_Restore(0,0,0);")
4298 code.put_goto(end_label)
4302 # during type analysis, we didn't know if we need the
4303 # exception value, but apparently, we do
4304 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4308 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4309 # We always have to fetch the exception value even if
4310 # there is no target, because this also normalises the
4311 # exception and stores it in the thread state.
4312 code.globalstate.use_utility_code(get_exception_utility_code)
4313 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4314 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4315 code.error_goto(self.pos)))
4319 self.exc_value.generate_evaluation_code(code)
4320 self.target.generate_assignment_code(self.exc_value, code)
4321 if self.excinfo_target is not None:
4322 self.excinfo_tuple.generate_evaluation_code(code)
4323 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4326 old_break_label, old_continue_label = code.break_label, code.continue_label
4327 code.break_label = code.new_label('except_break')
4328 code.continue_label = code.new_label('except_continue')
4330 old_exc_vars = code.funcstate.exc_vars
4331 code.funcstate.exc_vars = exc_vars
4332 self.body.generate_execution_code(code)
4333 code.funcstate.exc_vars = old_exc_vars
4334 for var in exc_vars:
4335 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4336 code.put_goto(end_label)
4338 if code.label_used(code.break_label):
4339 code.put_label(code.break_label)
4340 for var in exc_vars:
4341 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4342 code.put_goto(old_break_label)
4343 code.break_label = old_break_label
4345 if code.label_used(code.continue_label):
4346 code.put_label(code.continue_label)
4347 for var in exc_vars:
4348 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4349 code.put_goto(old_continue_label)
4350 code.continue_label = old_continue_label
4352 if not self.exc_vars:
4353 # clean up locally allocated temps
4354 for temp in exc_vars:
4355 code.funcstate.release_temp(temp)
4360 def annotate(self, code):
4362 self.pattern.annotate(code)
4364 self.target.annotate(code)
4365 self.body.annotate(code)
4368 class TryFinallyStatNode(StatNode):
4369 # try ... finally statement
4372 # finally_clause StatNode
4374 # cleanup_list [Entry] old_style temps to clean up on error
4376 # The plan is that we funnel all continue, break
4377 # return and error gotos into the beginning of the
4378 # finally block, setting a variable to remember which
4379 # one we're doing. At the end of the finally block, we
4380 # switch on the variable to figure out where to go.
4381 # In addition, if we're doing an error, we save the
4382 # exception on entry to the finally block and restore
4385 child_attrs = ["body", "finally_clause"]
4387 preserve_exception = 1
4389 disallow_continue_in_try_finally = 0
4390 # There doesn't seem to be any point in disallowing
4391 # continue in the try block, since we have no problem
4394 def create_analysed(pos, env, body, finally_clause):
4395 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4396 node.cleanup_list = []
4398 create_analysed = staticmethod(create_analysed)
4400 def analyse_control_flow(self, env):
4401 env.start_branching(self.pos)
4402 self.body.analyse_control_flow(env)
4403 env.next_branch(self.body.end_pos())
4404 env.finish_branching(self.body.end_pos())
4405 self.finally_clause.analyse_control_flow(env)
4407 def analyse_declarations(self, env):
4408 self.body.analyse_declarations(env)
4409 self.finally_clause.analyse_declarations(env)
4411 def analyse_expressions(self, env):
4412 self.body.analyse_expressions(env)
4413 self.cleanup_list = env.free_temp_entries[:]
4414 self.finally_clause.analyse_expressions(env)
4417 gil_message = "Try-finally statement"
4419 def generate_execution_code(self, code):
4420 old_error_label = code.error_label
4421 old_labels = code.all_new_labels()
4422 new_labels = code.get_all_labels()
4423 new_error_label = code.error_label
4424 catch_label = code.new_label()
4427 if self.disallow_continue_in_try_finally:
4428 was_in_try_finally = code.funcstate.in_try_finally
4429 code.funcstate.in_try_finally = 1
4430 self.body.generate_execution_code(code)
4431 if self.disallow_continue_in_try_finally:
4432 code.funcstate.in_try_finally = was_in_try_finally
4435 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4439 error_label_used = 0
4440 for i, new_label in enumerate(new_labels):
4441 if new_label in code.labels_used:
4442 cases_used.append(i)
4443 if new_label == new_error_label:
4444 error_label_used = 1
4445 error_label_case = i
4449 if error_label_used and self.preserve_exception:
4451 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4453 "int %s;" % Naming.exc_lineno_name)
4454 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4455 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4456 code.putln(exc_var_init_zero)
4458 exc_var_init_zero = None
4459 code.use_label(catch_label)
4461 "__pyx_why = 0; goto %s;" % catch_label)
4462 for i in cases_used:
4463 new_label = new_labels[i]
4464 #if new_label and new_label != "<try>":
4465 if new_label == new_error_label and self.preserve_exception:
4466 self.put_error_catcher(code,
4467 new_error_label, i+1, catch_label, temps_to_clean_up)
4469 code.put('%s: ' % new_label)
4470 if exc_var_init_zero:
4471 code.putln(exc_var_init_zero)
4472 code.putln("__pyx_why = %s; goto %s;" % (
4475 code.put_label(catch_label)
4476 code.set_all_labels(old_labels)
4477 if error_label_used:
4478 code.new_error_label()
4479 finally_error_label = code.error_label
4480 self.finally_clause.generate_execution_code(code)
4481 if error_label_used:
4482 if finally_error_label in code.labels_used and self.preserve_exception:
4483 over_label = code.new_label()
4484 code.put_goto(over_label);
4485 code.put_label(finally_error_label)
4486 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4487 for var in Naming.exc_vars:
4488 code.putln("Py_XDECREF(%s);" % var)
4490 code.put_goto(old_error_label)
4491 code.put_label(over_label)
4492 code.error_label = old_error_label
4495 "switch (__pyx_why) {")
4496 for i in cases_used:
4497 old_label = old_labels[i]
4498 if old_label == old_error_label and self.preserve_exception:
4499 self.put_error_uncatcher(code, i+1, old_error_label)
4501 code.use_label(old_label)
4503 "case %s: goto %s;" % (
4511 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4512 code.globalstate.use_utility_code(restore_exception_utility_code)
4519 code.put_var_xdecrefs_clear(self.cleanup_list)
4520 for temp_name, type in temps_to_clean_up:
4521 code.put_xdecref_clear(temp_name, type)
4523 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4527 Naming.exc_lineno_name, Naming.lineno_cname))
4531 code.put_goto(catch_label)
4535 def put_error_uncatcher(self, code, i, error_label):
4536 code.globalstate.use_utility_code(restore_exception_utility_code)
4541 "__Pyx_ErrRestore(%s, %s, %s);" %
4545 Naming.lineno_cname, Naming.exc_lineno_name))
4546 for var in Naming.exc_vars:
4550 code.put_goto(error_label)
4554 def annotate(self, code):
4555 self.body.annotate(code)
4556 self.finally_clause.annotate(code)
4559 class GILStatNode(TryFinallyStatNode):
4560 # 'with gil' or 'with nogil' statement
4562 # state string 'gil' or 'nogil'
4566 preserve_exception = 0
4568 def __init__(self, pos, state, body):
4570 TryFinallyStatNode.__init__(self, pos,
4572 finally_clause = GILExitNode(pos, state = state))
4574 def analyse_expressions(self, env):
4575 env.use_utility_code(force_init_threads_utility_code)
4576 was_nogil = env.nogil
4578 TryFinallyStatNode.analyse_expressions(self, env)
4579 env.nogil = was_nogil
4581 def gil_check(self, env):
4584 def generate_execution_code(self, code):
4585 code.mark_pos(self.pos)
4586 if self.state == 'gil':
4587 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4589 code.putln("{ PyThreadState *_save;")
4590 code.putln("Py_UNBLOCK_THREADS")
4591 TryFinallyStatNode.generate_execution_code(self, code)
4595 class GILExitNode(StatNode):
4596 # Used as the 'finally' block in a GILStatNode
4598 # state string 'gil' or 'nogil'
4602 def analyse_expressions(self, env):
4605 def generate_execution_code(self, code):
4606 if self.state == 'gil':
4607 code.putln("PyGILState_Release();")
4609 code.putln("Py_BLOCK_THREADS")
4612 class CImportStatNode(StatNode):
4615 # module_name string Qualified name of module being imported
4616 # as_name string or None Name specified in "as" clause, if any
4620 def analyse_declarations(self, env):
4621 if not env.is_module_scope:
4622 error(self.pos, "cimport only allowed at module level")
4624 module_scope = env.find_module(self.module_name, self.pos)
4625 if "." in self.module_name:
4626 names = [EncodedString(name) for name in self.module_name.split(".")]
4628 top_module_scope = env.context.find_submodule(top_name)
4629 module_scope = top_module_scope
4630 for name in names[1:]:
4631 submodule_scope = module_scope.find_submodule(name)
4632 module_scope.declare_module(name, submodule_scope, self.pos)
4633 module_scope = submodule_scope
4635 env.declare_module(self.as_name, module_scope, self.pos)
4637 env.declare_module(top_name, top_module_scope, self.pos)
4639 name = self.as_name or self.module_name
4640 env.declare_module(name, module_scope, self.pos)
4642 def analyse_expressions(self, env):
4645 def generate_execution_code(self, code):
4649 class FromCImportStatNode(StatNode):
4650 # from ... cimport statement
4652 # module_name string Qualified name of module
4653 # imported_names [(pos, name, as_name, kind)] Names to be imported
4657 def analyse_declarations(self, env):
4658 if not env.is_module_scope:
4659 error(self.pos, "cimport only allowed at module level")
4661 module_scope = env.find_module(self.module_name, self.pos)
4662 env.add_imported_module(module_scope)
4663 for pos, name, as_name, kind in self.imported_names:
4665 for local_name, entry in module_scope.entries.items():
4666 env.add_imported_entry(local_name, entry, pos)
4668 entry = module_scope.lookup(name)
4670 if kind and not self.declaration_matches(entry, kind):
4671 entry.redeclared(pos)
4673 if kind == 'struct' or kind == 'union':
4674 entry = module_scope.declare_struct_or_union(name,
4675 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4676 elif kind == 'class':
4677 entry = module_scope.declare_c_class(name, pos = pos,
4678 module_name = self.module_name)
4680 error(pos, "Name '%s' not declared in module '%s'"
4681 % (name, self.module_name))
4684 local_name = as_name or name
4685 env.add_imported_entry(local_name, entry, pos)
4687 def declaration_matches(self, entry, kind):
4688 if not entry.is_type:
4692 if not type.is_extension_type:
4695 if not type.is_struct_or_union:
4697 if kind != type.kind:
4701 def analyse_expressions(self, env):
4704 def generate_execution_code(self, code):
4708 class FromImportStatNode(StatNode):
4709 # from ... import statement
4712 # items [(string, NameNode)]
4713 # interned_items [(string, NameNode, ExprNode)]
4714 # item PyTempNode used internally
4715 # import_star boolean used internally
4717 child_attrs = ["module"]
4720 def analyse_declarations(self, env):
4721 for name, target in self.items:
4723 if not env.is_module_scope:
4724 error(self.pos, "import * only allowed at module level")
4726 env.has_import_star = 1
4727 self.import_star = 1
4729 target.analyse_target_declaration(env)
4731 def analyse_expressions(self, env):
4733 self.module.analyse_expressions(env)
4734 self.item = ExprNodes.PyTempNode(self.pos, env)
4735 self.item.allocate_temp(env)
4736 self.interned_items = []
4737 for name, target in self.items:
4739 for _, entry in env.entries.items():
4740 if not entry.is_type and entry.type.is_extension_type:
4741 env.use_utility_code(ExprNodes.type_test_utility_code)
4744 entry = env.lookup(target.name)
4745 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4746 continue # already cimported
4747 target.analyse_target_expression(env, None)
4748 if target.type is py_object_type:
4751 coerced_item = self.item.coerce_to(target.type, env)
4752 self.interned_items.append(
4753 (env.intern_identifier(name), target, coerced_item))
4754 #target.release_target_temp(env) # was release_temp ?!?
4755 self.module.release_temp(env)
4756 self.item.release_temp(env)
4758 def generate_execution_code(self, code):
4759 self.module.generate_evaluation_code(code)
4760 if self.import_star:
4762 'if (%s(%s) < 0) %s;' % (
4764 self.module.py_result(),
4765 code.error_goto(self.pos)))
4766 for cname, target, coerced_item in self.interned_items:
4768 '%s = PyObject_GetAttr(%s, %s); %s' % (
4770 self.module.py_result(),
4772 code.error_goto_if_null(self.item.result(), self.pos)))
4773 code.put_gotref(self.item.py_result())
4774 if coerced_item is None:
4775 target.generate_assignment_code(self.item, code)
4777 coerced_item.allocate_temp_result(code)
4778 coerced_item.generate_result_code(code)
4779 target.generate_assignment_code(coerced_item, code)
4780 if self.item.result() != coerced_item.result():
4781 code.put_decref_clear(self.item.result(), self.item.type)
4782 self.module.generate_disposal_code(code)
4783 self.module.free_temps(code)
4787 #------------------------------------------------------------------------------------
4789 # Runtime support code
4791 #------------------------------------------------------------------------------------
4793 utility_function_predeclarations = \
4796 #define INLINE __inline__
4798 #define INLINE __inline
4803 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4807 static int %(skip_dispatch_cname)s = 0;
4809 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4811 if Options.gcc_branch_hints:
4812 branch_prediction_macros = \
4815 /* Test for GCC > 2.95 */
4816 #if __GNUC__ > 2 || \
4817 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4818 #define likely(x) __builtin_expect(!!(x), 1)
4819 #define unlikely(x) __builtin_expect(!!(x), 0)
4820 #else /* __GNUC__ > 2 ... */
4821 #define likely(x) (x)
4822 #define unlikely(x) (x)
4823 #endif /* __GNUC__ > 2 ... */
4824 #else /* __GNUC__ */
4825 #define likely(x) (x)
4826 #define unlikely(x) (x)
4827 #endif /* __GNUC__ */
4830 branch_prediction_macros = \
4832 #define likely(x) (x)
4833 #define unlikely(x) (x)
4836 #get_name_predeclaration = \
4837 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4839 #get_name_interned_predeclaration = \
4840 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4842 #------------------------------------------------------------------------------------
4844 printing_utility_code = UtilityCode(
4846 static int __Pyx_Print(PyObject *, int); /*proto*/
4847 #if PY_MAJOR_VERSION >= 3
4848 static PyObject* %s = 0;
4849 static PyObject* %s = 0;
4851 """ % (Naming.print_function, Naming.print_function_kwargs),
4853 #if PY_MAJOR_VERSION < 3
4854 static PyObject *__Pyx_GetStdout(void) {
4855 PyObject *f = PySys_GetObject((char *)"stdout");
4857 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4862 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4867 if (!(f = __Pyx_GetStdout()))
4869 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4870 if (PyFile_SoftSpace(f, 1)) {
4871 if (PyFile_WriteString(" ", f) < 0)
4874 v = PyTuple_GET_ITEM(arg_tuple, i);
4875 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4877 if (PyString_Check(v)) {
4878 char *s = PyString_AsString(v);
4879 Py_ssize_t len = PyString_Size(v);
4881 isspace(Py_CHARMASK(s[len-1])) &&
4883 PyFile_SoftSpace(f, 0);
4887 if (PyFile_WriteString("\n", f) < 0)
4889 PyFile_SoftSpace(f, 0);
4894 #else /* Python 3 has a print function */
4896 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4897 PyObject* kwargs = 0;
4898 PyObject* result = 0;
4899 PyObject* end_string;
4900 if (!%(PRINT_FUNCTION)s) {
4901 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4902 if (!%(PRINT_FUNCTION)s)
4906 if (!%(PRINT_KWARGS)s) {
4907 %(PRINT_KWARGS)s = PyDict_New();
4908 if (!%(PRINT_KWARGS)s)
4910 end_string = PyUnicode_FromStringAndSize(" ", 1);
4913 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4914 Py_DECREF(end_string);
4917 Py_DECREF(end_string);
4919 kwargs = %(PRINT_KWARGS)s;
4921 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4929 """ % {'BUILTINS' : Naming.builtins_cname,
4930 'PRINT_FUNCTION' : Naming.print_function,
4931 'PRINT_KWARGS' : Naming.print_function_kwargs}
4935 printing_one_utility_code = UtilityCode(
4937 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4940 #if PY_MAJOR_VERSION < 3
4942 static int __Pyx_PrintOne(PyObject *o) {
4944 if (!(f = __Pyx_GetStdout()))
4946 if (PyFile_SoftSpace(f, 0)) {
4947 if (PyFile_WriteString(" ", f) < 0)
4950 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4952 if (PyFile_WriteString("\n", f) < 0)
4955 /* the line below is just to avoid compiler
4956 * compiler warnings about unused functions */
4957 return __Pyx_Print(NULL, 0);
4960 #else /* Python 3 has a print function */
4962 static int __Pyx_PrintOne(PyObject *o) {
4964 PyObject* arg_tuple = PyTuple_New(1);
4965 if (unlikely(!arg_tuple))
4968 PyTuple_SET_ITEM(arg_tuple, 0, o);
4969 res = __Pyx_Print(arg_tuple, 1);
4970 Py_DECREF(arg_tuple);
4979 #------------------------------------------------------------------------------------
4981 # The following function is based on do_raise() from ceval.c.
4983 raise_utility_code = UtilityCode(
4985 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4988 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4992 /* First, check the traceback argument, replacing None with NULL. */
4993 if (tb == Py_None) {
4997 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4998 PyErr_SetString(PyExc_TypeError,
4999 "raise: arg 3 must be a traceback or None");
5002 /* Next, replace a missing value with None */
5003 if (value == NULL) {
5007 #if PY_VERSION_HEX < 0x02050000
5008 if (!PyClass_Check(type))
5010 if (!PyType_Check(type))
5013 /* Raising an instance. The value should be a dummy. */
5014 if (value != Py_None) {
5015 PyErr_SetString(PyExc_TypeError,
5016 "instance exception may not have a separate value");
5019 /* Normalize to raise <class>, <instance> */
5022 #if PY_VERSION_HEX < 0x02050000
5023 if (PyInstance_Check(type)) {
5024 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5029 PyErr_SetString(PyExc_TypeError,
5030 "raise: exception must be an old-style class or instance");
5034 type = (PyObject*) Py_TYPE(type);
5036 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5037 PyErr_SetString(PyExc_TypeError,
5038 "raise: exception class must be a subclass of BaseException");
5043 __Pyx_ErrRestore(type, value, tb);
5053 #------------------------------------------------------------------------------------
5055 reraise_utility_code = UtilityCode(
5057 static void __Pyx_ReRaise(void); /*proto*/
5060 static void __Pyx_ReRaise(void) {
5061 PyThreadState *tstate = PyThreadState_GET();
5062 PyObject* tmp_type = tstate->curexc_type;
5063 PyObject* tmp_value = tstate->curexc_value;
5064 PyObject* tmp_tb = tstate->curexc_traceback;
5065 tstate->curexc_type = tstate->exc_type;
5066 tstate->curexc_value = tstate->exc_value;
5067 tstate->curexc_traceback = tstate->exc_traceback;
5068 tstate->exc_type = 0;
5069 tstate->exc_value = 0;
5070 tstate->exc_traceback = 0;
5071 Py_XDECREF(tmp_type);
5072 Py_XDECREF(tmp_value);
5077 #------------------------------------------------------------------------------------
5079 arg_type_test_utility_code = UtilityCode(
5081 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5082 const char *name, int exact); /*proto*/
5085 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5086 const char *name, int exact)
5089 PyErr_Format(PyExc_SystemError, "Missing type object");
5092 if (none_allowed && obj == Py_None) return 1;
5094 if (Py_TYPE(obj) == type) return 1;
5097 if (PyObject_TypeCheck(obj, type)) return 1;
5099 PyErr_Format(PyExc_TypeError,
5100 "Argument '%s' has incorrect type (expected %s, got %s)",
5101 name, type->tp_name, Py_TYPE(obj)->tp_name);
5106 #------------------------------------------------------------------------------------
5108 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5109 # many or too few positional arguments were found. This handles
5110 # Py_ssize_t formatting correctly.
5112 raise_argtuple_invalid_utility_code = UtilityCode(
5114 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5115 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5118 static void __Pyx_RaiseArgtupleInvalid(
5119 const char* func_name,
5123 Py_ssize_t num_found)
5125 Py_ssize_t num_expected;
5126 const char *number, *more_or_less;
5128 if (num_found < num_min) {
5129 num_expected = num_min;
5130 more_or_less = "at least";
5132 num_expected = num_max;
5133 more_or_less = "at most";
5136 more_or_less = "exactly";
5138 number = (num_expected == 1) ? "" : "s";
5139 PyErr_Format(PyExc_TypeError,
5140 #if PY_VERSION_HEX < 0x02050000
5141 "%s() takes %s %d positional argument%s (%d given)",
5143 "%s() takes %s %zd positional argument%s (%zd given)",
5145 func_name, more_or_less, num_expected, number, num_found);
5149 raise_keyword_required_utility_code = UtilityCode(
5151 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5154 static INLINE void __Pyx_RaiseKeywordRequired(
5155 const char* func_name,
5158 PyErr_Format(PyExc_TypeError,
5159 #if PY_MAJOR_VERSION >= 3
5160 "%s() needs keyword-only argument %U", func_name, kw_name);
5162 "%s() needs keyword-only argument %s", func_name,
5163 PyString_AS_STRING(kw_name));
5168 raise_double_keywords_utility_code = UtilityCode(
5170 static void __Pyx_RaiseDoubleKeywordsError(
5171 const char* func_name, PyObject* kw_name); /*proto*/
5174 static void __Pyx_RaiseDoubleKeywordsError(
5175 const char* func_name,
5178 PyErr_Format(PyExc_TypeError,
5179 #if PY_MAJOR_VERSION >= 3
5180 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5182 "%s() got multiple values for keyword argument '%s'", func_name,
5183 PyString_AS_STRING(kw_name));
5188 #------------------------------------------------------------------------------------
5190 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5191 # were passed to a function, or if any keywords were passed to a
5192 # function that does not accept them.
5194 keyword_string_check_utility_code = UtilityCode(
5196 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5197 const char* function_name, int kw_allowed); /*proto*/
5200 static INLINE int __Pyx_CheckKeywordStrings(
5202 const char* function_name,
5207 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5208 #if PY_MAJOR_VERSION < 3
5209 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5211 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5213 goto invalid_keyword_type;
5215 if ((!kw_allowed) && unlikely(key))
5216 goto invalid_keyword;
5218 invalid_keyword_type:
5219 PyErr_Format(PyExc_TypeError,
5220 "%s() keywords must be strings", function_name);
5223 PyErr_Format(PyExc_TypeError,
5224 #if PY_MAJOR_VERSION < 3
5225 "%s() got an unexpected keyword argument '%s'",
5226 function_name, PyString_AsString(key));
5228 "%s() got an unexpected keyword argument '%U'",
5229 function_name, key);
5235 #------------------------------------------------------------------------------------
5237 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5238 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5239 # keywords will raise an invalid keyword error.
5241 # Three kinds of errors are checked: 1) non-string keywords, 2)
5242 # unexpected keywords and 3) overlap with positional arguments.
5244 # If num_posargs is greater 0, it denotes the number of positional
5245 # arguments that were passed and that must therefore not appear
5246 # amongst the keywords as well.
5248 # This method does not check for required keyword arguments.
5251 parse_keywords_utility_code = UtilityCode(
5253 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5254 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5255 const char* function_name); /*proto*/
5258 static int __Pyx_ParseOptionalKeywords(
5260 PyObject **argnames[],
5263 Py_ssize_t num_pos_args,
5264 const char* function_name)
5266 PyObject *key = 0, *value = 0;
5269 PyObject*** first_kw_arg = argnames + num_pos_args;
5271 while (PyDict_Next(kwds, &pos, &key, &value)) {
5272 name = first_kw_arg;
5273 while (*name && (**name != key)) name++;
5275 values[name-argnames] = value;
5277 #if PY_MAJOR_VERSION < 3
5278 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5280 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5282 goto invalid_keyword_type;
5284 for (name = first_kw_arg; *name; name++) {
5285 #if PY_MAJOR_VERSION >= 3
5286 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5287 PyUnicode_Compare(**name, key) == 0) break;
5289 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5290 _PyString_Eq(**name, key)) break;
5294 values[name-argnames] = value;
5296 /* unexpected keyword found */
5297 for (name=argnames; name != first_kw_arg; name++) {
5298 if (**name == key) goto arg_passed_twice;
5299 #if PY_MAJOR_VERSION >= 3
5300 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5301 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5303 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5304 _PyString_Eq(**name, key)) goto arg_passed_twice;
5308 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5310 goto invalid_keyword;
5318 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5320 invalid_keyword_type:
5321 PyErr_Format(PyExc_TypeError,
5322 "%s() keywords must be strings", function_name);
5325 PyErr_Format(PyExc_TypeError,
5326 #if PY_MAJOR_VERSION < 3
5327 "%s() got an unexpected keyword argument '%s'",
5328 function_name, PyString_AsString(key));
5330 "%s() got an unexpected keyword argument '%U'",
5331 function_name, key);
5338 #------------------------------------------------------------------------------------
5340 unraisable_exception_utility_code = UtilityCode(
5342 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5345 static void __Pyx_WriteUnraisable(const char *name) {
5346 PyObject *old_exc, *old_val, *old_tb;
5348 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5349 #if PY_MAJOR_VERSION < 3
5350 ctx = PyString_FromString(name);
5352 ctx = PyUnicode_FromString(name);
5354 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5356 PyErr_WriteUnraisable(Py_None);
5358 PyErr_WriteUnraisable(ctx);
5364 #------------------------------------------------------------------------------------
5366 traceback_utility_code = UtilityCode(
5368 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5371 #include "compile.h"
5372 #include "frameobject.h"
5373 #include "traceback.h"
5375 static void __Pyx_AddTraceback(const char *funcname) {
5376 PyObject *py_srcfile = 0;
5377 PyObject *py_funcname = 0;
5378 PyObject *py_globals = 0;
5379 PyObject *empty_string = 0;
5380 PyCodeObject *py_code = 0;
5381 PyFrameObject *py_frame = 0;
5383 #if PY_MAJOR_VERSION < 3
5384 py_srcfile = PyString_FromString(%(FILENAME)s);
5386 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5388 if (!py_srcfile) goto bad;
5390 #if PY_MAJOR_VERSION < 3
5391 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5393 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5397 #if PY_MAJOR_VERSION < 3
5398 py_funcname = PyString_FromString(funcname);
5400 py_funcname = PyUnicode_FromString(funcname);
5403 if (!py_funcname) goto bad;
5404 py_globals = PyModule_GetDict(%(GLOBALS)s);
5405 if (!py_globals) goto bad;
5406 #if PY_MAJOR_VERSION < 3
5407 empty_string = PyString_FromStringAndSize("", 0);
5409 empty_string = PyBytes_FromStringAndSize("", 0);
5411 if (!empty_string) goto bad;
5412 py_code = PyCode_New(
5413 0, /*int argcount,*/
5414 #if PY_MAJOR_VERSION >= 3
5415 0, /*int kwonlyargcount,*/
5418 0, /*int stacksize,*/
5420 empty_string, /*PyObject *code,*/
5421 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5422 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5423 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5424 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5425 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5426 py_srcfile, /*PyObject *filename,*/
5427 py_funcname, /*PyObject *name,*/
5428 %(LINENO)s, /*int firstlineno,*/
5429 empty_string /*PyObject *lnotab*/
5431 if (!py_code) goto bad;
5432 py_frame = PyFrame_New(
5433 PyThreadState_GET(), /*PyThreadState *tstate,*/
5434 py_code, /*PyCodeObject *code,*/
5435 py_globals, /*PyObject *globals,*/
5436 0 /*PyObject *locals*/
5438 if (!py_frame) goto bad;
5439 py_frame->f_lineno = %(LINENO)s;
5440 PyTraceBack_Here(py_frame);
5442 Py_XDECREF(py_srcfile);
5443 Py_XDECREF(py_funcname);
5444 Py_XDECREF(empty_string);
5445 Py_XDECREF(py_code);
5446 Py_XDECREF(py_frame);
5449 'FILENAME': Naming.filename_cname,
5450 'LINENO': Naming.lineno_cname,
5451 'CFILENAME': Naming.cfilenm_cname,
5452 'CLINENO': Naming.clineno_cname,
5453 'GLOBALS': Naming.module_cname,
5454 'EMPTY_TUPLE' : Naming.empty_tuple,
5457 restore_exception_utility_code = UtilityCode(
5459 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5460 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5463 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5464 PyObject *tmp_type, *tmp_value, *tmp_tb;
5465 PyThreadState *tstate = PyThreadState_GET();
5467 #if PY_MAJOR_VERSION >= 3
5468 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5469 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5470 tmp_type = tstate->exc_type;
5471 tmp_value = tstate->exc_value;
5472 tmp_tb = tstate->exc_traceback;
5473 PyErr_NormalizeException(&type, &value, &tb);
5474 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5475 tstate->exc_type = 0;
5476 tstate->exc_value = 0;
5477 tstate->exc_traceback = 0;
5478 PyException_SetContext(value, tmp_value);
5479 Py_DECREF(tmp_type);
5484 tmp_type = tstate->curexc_type;
5485 tmp_value = tstate->curexc_value;
5486 tmp_tb = tstate->curexc_traceback;
5487 tstate->curexc_type = type;
5488 tstate->curexc_value = value;
5489 tstate->curexc_traceback = tb;
5490 Py_XDECREF(tmp_type);
5491 Py_XDECREF(tmp_value);
5495 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5496 PyThreadState *tstate = PyThreadState_GET();
5497 *type = tstate->curexc_type;
5498 *value = tstate->curexc_value;
5499 *tb = tstate->curexc_traceback;
5501 tstate->curexc_type = 0;
5502 tstate->curexc_value = 0;
5503 tstate->curexc_traceback = 0;
5508 #------------------------------------------------------------------------------------
5510 set_vtable_utility_code = UtilityCode(
5512 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5515 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5516 PyObject *pycobj = 0;
5519 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5522 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5535 #------------------------------------------------------------------------------------
5537 get_vtable_utility_code = UtilityCode(
5539 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5542 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5546 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5549 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5550 if (!*(void **)vtabptr)
5563 #------------------------------------------------------------------------------------
5565 init_string_tab_utility_code = UtilityCode(
5567 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5570 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5572 #if PY_MAJOR_VERSION < 3
5573 if (t->is_unicode && (!t->is_identifier)) {
5574 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5575 } else if (t->intern) {
5576 *t->p = PyString_InternFromString(t->s);
5578 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5580 #else /* Python 3+ has unicode identifiers */
5581 if (t->is_identifier || (t->is_unicode && t->intern)) {
5582 *t->p = PyUnicode_InternFromString(t->s);
5583 } else if (t->is_unicode) {
5584 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5586 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5597 #------------------------------------------------------------------------------------
5599 get_exception_utility_code = UtilityCode(
5601 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5604 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5605 PyObject *tmp_type, *tmp_value, *tmp_tb;
5606 PyThreadState *tstate = PyThreadState_GET();
5607 *type = tstate->curexc_type;
5608 *value = tstate->curexc_value;
5609 *tb = tstate->curexc_traceback;
5610 tstate->curexc_type = 0;
5611 tstate->curexc_value = 0;
5612 tstate->curexc_traceback = 0;
5613 PyErr_NormalizeException(type, value, tb);
5614 if (PyErr_Occurred())
5619 tmp_type = tstate->exc_type;
5620 tmp_value = tstate->exc_value;
5621 tmp_tb = tstate->exc_traceback;
5622 tstate->exc_type = *type;
5623 tstate->exc_value = *value;
5624 tstate->exc_traceback = *tb;
5625 /* Make sure tstate is in a consistent state when we XDECREF
5626 these objects (XDECREF may run arbitrary code). */
5627 Py_XDECREF(tmp_type);
5628 Py_XDECREF(tmp_value);
5640 #------------------------------------------------------------------------------------
5642 reset_exception_utility_code = UtilityCode(
5644 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5645 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5648 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5649 PyThreadState *tstate = PyThreadState_GET();
5650 *type = tstate->exc_type;
5651 *value = tstate->exc_value;
5652 *tb = tstate->exc_traceback;
5658 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5659 PyObject *tmp_type, *tmp_value, *tmp_tb;
5660 PyThreadState *tstate = PyThreadState_GET();
5661 tmp_type = tstate->exc_type;
5662 tmp_value = tstate->exc_value;
5663 tmp_tb = tstate->exc_traceback;
5664 tstate->exc_type = type;
5665 tstate->exc_value = value;
5666 tstate->exc_traceback = tb;
5667 Py_XDECREF(tmp_type);
5668 Py_XDECREF(tmp_value);
5673 #------------------------------------------------------------------------------------
5675 force_init_threads_utility_code = UtilityCode(
5677 #ifndef __PYX_FORCE_INIT_THREADS
5678 #if PY_VERSION_HEX < 0x02040200
5679 #define __PYX_FORCE_INIT_THREADS 1
5681 #define __PYX_FORCE_INIT_THREADS 0
5686 #------------------------------------------------------------------------------------