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 scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
553 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
554 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
555 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
556 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
561 cname = struct_cname)
562 self.op_args_struct.defined_in_pxd = 1
563 self.op_args_struct.used = 1
567 if return_type.is_pyobject \
568 and (self.exception_value or self.exception_check) \
569 and self.exception_check != '+':
571 "Exception clause not allowed for function returning Python object")
573 if self.exception_value:
574 self.exception_value.analyse_const_expression(env)
575 if self.exception_check == '+':
576 exc_val_type = self.exception_value.type
577 if not exc_val_type.is_error and \
578 not exc_val_type.is_pyobject and \
579 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
580 error(self.exception_value.pos,
581 "Exception value must be a Python exception or cdef function with no arguments.")
582 exc_val = self.exception_value
584 exc_val = self.exception_value.result()
585 if not return_type.assignable_from(self.exception_value.type):
586 error(self.exception_value.pos,
587 "Exception value incompatible with function return type")
588 exc_check = self.exception_check
589 if return_type.is_array:
591 "Function cannot return an array")
592 if return_type.is_cfunction:
594 "Function cannot return a function")
595 func_type = PyrexTypes.CFuncType(
596 return_type, func_type_args, self.has_varargs,
597 optional_arg_count = self.optional_arg_count,
598 exception_value = exc_val, exception_check = exc_check,
599 calling_convention = self.base.calling_convention,
600 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
601 if self.optional_arg_count:
602 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
603 return self.base.analyse(func_type, env)
606 class CArgDeclNode(Node):
607 # Item in a function declaration argument list.
609 # base_type CBaseTypeNode
610 # declarator CDeclaratorNode
611 # not_none boolean Tagged with 'not None'
612 # default ExprNode or None
613 # default_entry Symtab.Entry Entry for the variable holding the default value
614 # default_result_code string cname or code fragment for default value
615 # is_self_arg boolean Is the "self" arg of an extension type method
616 # is_kw_only boolean Is a keyword-only argument
618 child_attrs = ["base_type", "declarator", "default"]
623 name_declarator = None
625 def analyse(self, env, nonempty = 0):
626 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
627 if self.type is None:
628 # The parser may missinterpret names as types...
630 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
632 self.declarator.name = self.base_type.name
633 self.base_type.name = None
634 self.base_type.is_basic_c_type = False
637 could_be_name = False
638 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
639 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
640 self.declarator.name = self.base_type.arg_name
641 return self.declarator.analyse(base_type, env, nonempty = nonempty)
643 return self.name_declarator, self.type
645 def annotate(self, code):
647 self.default.annotate(code)
650 class CBaseTypeNode(Node):
651 # Abstract base class for C base type nodes.
653 # Processing during analyse_declarations phase:
660 class CAnalysedBaseTypeNode(Node):
665 def analyse(self, env, could_be_name = False):
668 class CSimpleBaseTypeNode(CBaseTypeNode):
670 # module_path [string] Qualifying name components
671 # is_basic_c_type boolean
674 # is_self_arg boolean Is self argument of C method
677 arg_name = None # in case the argument name was interpreted as a type
679 def analyse(self, env, could_be_name = False):
680 # Return type descriptor.
681 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
683 if self.is_basic_c_type:
684 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
686 error(self.pos, "Unrecognised type modifier combination")
687 elif self.name == "object" and not self.module_path:
688 type = py_object_type
689 elif self.name is None:
690 if self.is_self_arg and env.is_c_class_scope:
691 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
692 type = env.parent_type
694 type = py_object_type
697 scope = env.find_imported_module(self.module_path, self.pos)
701 if scope.is_c_class_scope:
702 scope = scope.global_scope()
703 entry = scope.lookup(self.name)
704 if entry and entry.is_type:
707 if self.is_self_arg and env.is_c_class_scope:
708 type = env.parent_type
710 type = py_object_type
711 self.arg_name = self.name
713 error(self.pos, "'%s' is not a type identifier" % self.name)
717 return PyrexTypes.error_type
719 class CBufferAccessTypeNode(CBaseTypeNode):
721 # positional_args [ExprNode] List of positional arguments
722 # keyword_args DictNode Keyword arguments
723 # base_type_node CBaseTypeNode
726 # type PyrexType.BufferType ...containing the right options
729 child_attrs = ["base_type_node", "positional_args",
730 "keyword_args", "dtype_node"]
736 def analyse(self, env, could_be_name = False):
737 base_type = self.base_type_node.analyse(env)
738 if base_type.is_error: return base_type
741 options = Buffer.analyse_buffer_options(
744 self.positional_args,
746 base_type.buffer_defaults)
748 self.type = PyrexTypes.BufferType(base_type, **options)
751 class CComplexBaseTypeNode(CBaseTypeNode):
752 # base_type CBaseTypeNode
753 # declarator CDeclaratorNode
755 child_attrs = ["base_type", "declarator"]
757 def analyse(self, env, could_be_name = False):
758 base = self.base_type.analyse(env, could_be_name)
759 _, type = self.declarator.analyse(base, env)
763 class CVarDefNode(StatNode):
764 # C variable definition or forward/extern function declaration.
766 # visibility 'private' or 'public' or 'extern'
767 # base_type CBaseTypeNode
768 # declarators [CDeclaratorNode]
771 # need_properties [entry]
773 # decorators [cython.locals(...)] or None
774 # directive_locals { string : NameNode } locals defined by cython.locals(...)
776 child_attrs = ["base_type", "declarators"]
780 directive_locals = {}
782 def analyse_declarations(self, env, dest_scope = None):
785 self.dest_scope = dest_scope
786 base_type = self.base_type.analyse(env)
787 if (dest_scope.is_c_class_scope
788 and self.visibility == 'public'
789 and base_type.is_pyobject
790 and (base_type.is_builtin_type or base_type.is_extension_type)):
791 self.need_properties = []
793 visibility = 'private'
795 need_property = False
796 visibility = self.visibility
798 for declarator in self.declarators:
799 name_declarator, type = declarator.analyse(base_type, env)
800 if not type.is_complete():
801 if not (self.visibility == 'extern' and type.is_array):
802 error(declarator.pos,
803 "Variable type '%s' is incomplete" % type)
804 if self.visibility == 'extern' and type.is_pyobject:
805 error(declarator.pos,
806 "Python object cannot be declared extern")
807 name = name_declarator.name
808 cname = name_declarator.cname
810 error(declarator.pos, "Missing name in declaration.")
812 if type.is_cfunction:
813 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
814 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
816 if entry is not None:
817 entry.directive_locals = self.directive_locals
819 if self.directive_locals:
820 s.error("Decorators can only be followed by functions")
821 if self.in_pxd and self.visibility != 'extern':
823 "Only 'extern' C variable declaration allowed in .pxd file")
824 entry = dest_scope.declare_var(name, type, declarator.pos,
825 cname = cname, visibility = visibility, is_cdef = 1)
827 self.need_properties.append(entry)
828 entry.needs_property = 1
831 class CStructOrUnionDefNode(StatNode):
833 # cname string or None
834 # kind "struct" or "union"
835 # typedef_flag boolean
836 # visibility "public" or "private"
838 # attributes [CVarDefNode] or None
841 child_attrs = ["attributes"]
843 def analyse_declarations(self, env):
845 if self.attributes is not None:
846 scope = StructOrUnionScope(self.name)
847 self.entry = env.declare_struct_or_union(
848 self.name, self.kind, scope, self.typedef_flag, self.pos,
849 self.cname, visibility = self.visibility)
850 if self.attributes is not None:
851 if self.in_pxd and not env.in_cinclude:
852 self.entry.defined_in_pxd = 1
853 for attr in self.attributes:
854 attr.analyse_declarations(env, scope)
855 if self.visibility != 'extern':
856 need_typedef_indirection = False
857 for attr in scope.var_entries:
860 type = type.base_type
861 if type == self.entry.type:
862 error(attr.pos, "Struct cannot contain itself as a member.")
863 if self.typedef_flag:
865 type = type.base_type
866 if type == self.entry.type:
867 need_typedef_indirection = True
868 if need_typedef_indirection:
869 # C can't handle typedef structs that refer to themselves.
870 struct_entry = self.entry
871 cname = env.new_const_cname()
872 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
873 struct_entry.type.typedef_flag = False
874 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
876 def analyse_expressions(self, env):
879 def generate_execution_code(self, code):
883 class CEnumDefNode(StatNode):
884 # name string or None
885 # cname string or None
886 # items [CEnumDefItemNode]
887 # typedef_flag boolean
888 # visibility "public" or "private"
892 child_attrs = ["items"]
894 def analyse_declarations(self, env):
895 self.entry = env.declare_enum(self.name, self.pos,
896 cname = self.cname, typedef_flag = self.typedef_flag,
897 visibility = self.visibility)
898 if self.items is not None:
899 if self.in_pxd and not env.in_cinclude:
900 self.entry.defined_in_pxd = 1
901 for item in self.items:
902 item.analyse_declarations(env, self.entry)
904 def analyse_expressions(self, env):
905 if self.visibility == 'public':
906 self.temp = env.allocate_temp_pyobject()
907 env.release_temp(self.temp)
909 def generate_execution_code(self, code):
910 if self.visibility == 'public':
911 for item in self.entry.enum_values:
912 code.putln("%s = PyInt_FromLong(%s); %s" % (
915 code.error_goto_if_null(self.temp, item.pos)))
916 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
920 code.error_goto(item.pos)))
921 code.putln("%s = 0;" % self.temp)
924 class CEnumDefItemNode(StatNode):
926 # cname string or None
927 # value ExprNode or None
929 child_attrs = ["value"]
931 def analyse_declarations(self, env, enum_entry):
933 self.value.analyse_const_expression(env)
934 if not self.value.type.is_int:
935 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
936 self.value.analyse_const_expression(env)
937 value = self.value.result()
940 entry = env.declare_const(self.name, enum_entry.type,
941 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
942 enum_entry.enum_values.append(entry)
945 class CTypeDefNode(StatNode):
946 # base_type CBaseTypeNode
947 # declarator CDeclaratorNode
948 # visibility "public" or "private"
951 child_attrs = ["base_type", "declarator"]
953 def analyse_declarations(self, env):
954 base = self.base_type.analyse(env)
955 name_declarator, type = self.declarator.analyse(base, env)
956 name = name_declarator.name
957 cname = name_declarator.cname
958 entry = env.declare_typedef(name, type, self.pos,
959 cname = cname, visibility = self.visibility)
960 if self.in_pxd and not env.in_cinclude:
961 entry.defined_in_pxd = 1
963 def analyse_expressions(self, env):
965 def generate_execution_code(self, code):
969 class FuncDefNode(StatNode, BlockNode):
970 # Base class for function definition nodes.
972 # return_type PyrexType
973 # #filename string C name of filename string const
975 # needs_closure boolean Whether or not this function has inner functions/classes/yield
976 # directive_locals { string : NameNode } locals defined by cython.locals(...)
980 needs_closure = False
982 def analyse_default_values(self, env):
983 genv = env.global_scope()
984 for arg in self.args:
987 if not hasattr(arg, 'default_entry'):
988 arg.default.analyse_types(env)
989 arg.default = arg.default.coerce_to(arg.type, genv)
990 if arg.default.is_literal:
991 arg.default_entry = arg.default
992 arg.default_result_code = arg.default.calculate_result_code()
993 if arg.default.type != arg.type and not arg.type.is_int:
994 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
996 arg.default.allocate_temps(genv)
997 arg.default_entry = genv.add_default_value(arg.type)
998 if arg.type.is_pyobject:
999 arg.default_entry.init = 0
1000 arg.default_entry.used = 1
1001 arg.default_result_code = arg.default_entry.cname
1004 "This argument cannot have a default value")
1007 def need_gil_acquisition(self, lenv):
1010 def create_local_scope(self, env):
1012 while env.is_py_class_scope or env.is_c_class_scope:
1013 env = env.outer_scope
1014 if self.needs_closure:
1015 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1017 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1018 lenv.return_type = self.return_type
1019 type = self.entry.type
1020 if type.is_cfunction:
1021 lenv.nogil = type.nogil and not type.with_gil
1022 self.local_scope = lenv
1025 def generate_function_definitions(self, env, code):
1028 lenv = self.local_scope
1030 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1031 self.entry.scope.is_c_class_scope)
1033 # Generate C code for header and body of function
1034 code.enter_cfunc_scope()
1035 code.return_from_error_cleanup_label = code.new_label()
1037 # ----- Top-level constants used by this function
1038 code.mark_pos(self.pos)
1039 self.generate_interned_num_decls(lenv, code)
1040 self.generate_interned_string_decls(lenv, code)
1041 self.generate_py_string_decls(lenv, code)
1042 self.generate_cached_builtins_decls(lenv, code)
1044 #code.put_var_declarations(lenv.const_entries, static = 1)
1045 self.generate_const_definitions(lenv, code)
1046 # ----- Function header
1049 self.py_func.generate_function_header(code,
1050 with_pymethdef = env.is_py_class_scope,
1052 self.generate_function_header(code,
1053 with_pymethdef = env.is_py_class_scope)
1054 # ----- Local variable declarations
1055 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1056 self.generate_argument_declarations(lenv, code)
1057 if self.needs_closure:
1058 code.putln("/* TODO: declare and create scope object */")
1059 code.put_var_declarations(lenv.var_entries)
1061 if not self.return_type.is_void:
1062 if self.return_type.is_pyobject:
1066 (self.return_type.declaration_code(
1067 Naming.retval_cname),
1069 tempvardecl_code = code.insertion_point()
1070 self.generate_keyword_list(code)
1071 # ----- Extern library function declarations
1072 lenv.generate_library_function_declarations(code)
1073 # ----- GIL acquisition
1074 acquire_gil = self.need_gil_acquisition(lenv)
1076 env.use_utility_code(force_init_threads_utility_code)
1077 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1078 # ----- Automatic lead-ins for certain special functions
1080 code.put_setup_refcount_context(self.entry.name)
1081 if is_getbuffer_slot:
1082 self.getbuffer_init(code)
1083 # ----- Fetch arguments
1084 self.generate_argument_parsing_code(env, code)
1085 # If an argument is assigned to in the body, we must
1086 # incref it to properly keep track of refcounts.
1087 for entry in lenv.arg_entries:
1088 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1089 code.put_var_incref(entry)
1090 # ----- Initialise local variables
1091 for entry in lenv.var_entries:
1092 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1093 code.put_init_var_to_py_none(entry)
1094 # ----- Initialise local buffer auxiliary variables
1095 for entry in lenv.var_entries + lenv.arg_entries:
1096 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1097 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1098 # ----- Check and convert arguments
1099 self.generate_argument_type_tests(code)
1100 # ----- Acquire buffer arguments
1101 for entry in lenv.arg_entries:
1102 if entry.type.is_buffer:
1103 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1104 # ----- Function body
1105 self.body.generate_execution_code(code)
1106 # ----- Default return value
1108 if self.return_type.is_pyobject:
1109 #if self.return_type.is_extension_type:
1110 # lhs = "(PyObject *)%s" % Naming.retval_cname
1112 lhs = Naming.retval_cname
1113 code.put_init_to_py_none(lhs, self.return_type)
1115 val = self.return_type.default_value
1117 code.putln("%s = %s;" % (Naming.retval_cname, val))
1118 # ----- Error cleanup
1119 if code.error_label in code.labels_used:
1120 code.put_goto(code.return_label)
1121 code.put_label(code.error_label)
1122 # cleanup temps the old way
1123 code.put_var_xdecrefs(lenv.temp_entries)
1124 # cleanup temps the new way
1125 for cname, type in code.funcstate.all_managed_temps():
1126 code.put_xdecref(cname, type)
1128 # Clean up buffers -- this calls a Python function
1129 # so need to save and restore error state
1130 buffers_present = len(lenv.buffer_entries) > 0
1132 code.globalstate.use_utility_code(restore_exception_utility_code)
1133 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1134 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1135 for entry in lenv.buffer_entries:
1136 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1137 #code.putln("%s = 0;" % entry.cname)
1138 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1140 err_val = self.error_value()
1141 exc_check = self.caller_will_check_exceptions()
1142 if err_val is not None or exc_check:
1143 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1145 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1146 % self.entry.qualified_name, 0)
1148 '__Pyx_WriteUnraisable("%s");' %
1149 self.entry.qualified_name)
1150 env.use_utility_code(unraisable_exception_utility_code)
1151 env.use_utility_code(restore_exception_utility_code)
1152 default_retval = self.return_type.default_value
1153 if err_val is None and default_retval:
1154 err_val = default_retval
1155 if err_val is not None:
1158 Naming.retval_cname,
1161 if is_getbuffer_slot:
1162 self.getbuffer_error_cleanup(code)
1164 # If we are using the non-error cleanup section we should
1165 # jump past it if we have an error. The if-test below determine
1166 # whether this section is used.
1167 if buffers_present or is_getbuffer_slot:
1168 code.put_goto(code.return_from_error_cleanup_label)
1171 # ----- Non-error return cleanup
1172 # If you add anything here, remember to add a condition to the
1173 # if-test above in the error block (so that it can jump past this
1175 code.put_label(code.return_label)
1176 for entry in lenv.buffer_entries:
1178 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1179 if is_getbuffer_slot:
1180 self.getbuffer_normal_cleanup(code)
1181 # ----- Return cleanup for both error and no-error return
1182 code.put_label(code.return_from_error_cleanup_label)
1183 if not Options.init_local_none:
1184 for entry in lenv.var_entries:
1185 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1186 entry.xdecref_cleanup = 1
1187 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1188 # Decref any increfed args
1189 for entry in lenv.arg_entries:
1190 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1191 code.put_var_decref(entry)
1193 # code.putln("/* TODO: decref scope object */")
1195 # This code is duplicated in ModuleNode.generate_module_init_func
1197 default_retval = self.return_type.default_value
1198 err_val = self.error_value()
1199 if err_val is None and default_retval:
1200 err_val = default_retval
1201 if self.return_type.is_pyobject:
1202 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1204 code.put_finish_refcount_context()
1207 code.putln("PyGILState_Release(_save);")
1209 if not self.return_type.is_void:
1210 code.putln("return %s;" % Naming.retval_cname)
1213 # ----- Go back and insert temp variable declarations
1214 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1215 tempvardecl_code.put_temp_declarations(code.funcstate)
1216 # ----- Python version
1217 code.exit_cfunc_scope()
1219 self.py_func.generate_function_definitions(env, code)
1220 self.generate_wrapper_functions(code)
1222 def declare_argument(self, env, arg):
1223 if arg.type.is_void:
1224 error(arg.pos, "Invalid use of 'void'")
1225 elif not arg.type.is_complete() and not arg.type.is_array:
1227 "Argument type '%s' is incomplete" % arg.type)
1228 return env.declare_arg(arg.name, arg.type, arg.pos)
1230 def generate_wrapper_functions(self, code):
1233 def generate_execution_code(self, code):
1234 # Evaluate and store argument default values
1235 for arg in self.args:
1236 default = arg.default
1238 if not default.is_literal:
1239 default.generate_evaluation_code(code)
1240 default.make_owned_reference(code)
1243 arg.default_entry.cname,
1244 default.result_as(arg.default_entry.type)))
1245 if default.is_temp and default.type.is_pyobject:
1246 code.putln("%s = 0;" % default.result())
1247 default.free_temps(code)
1248 code.put_var_giveref(arg.default_entry)
1249 # For Python class methods, create and store function object
1251 self.assmt.generate_execution_code(code)
1254 # Special code for the __getbuffer__ function
1256 def getbuffer_init(self, code):
1257 info = self.local_scope.arg_entries[1].cname
1258 # Python 3.0 betas have a bug in memoryview which makes it call
1259 # getbuffer with a NULL parameter. For now we work around this;
1260 # the following line should be removed when this bug is fixed.
1261 code.putln("if (%s == NULL) return 0;" % info)
1262 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1263 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1265 def getbuffer_error_cleanup(self, code):
1266 info = self.local_scope.arg_entries[1].cname
1267 code.put_gotref("%s->obj" % info)
1268 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1271 def getbuffer_normal_cleanup(self, code):
1272 info = self.local_scope.arg_entries[1].cname
1273 code.putln("if (%s->obj == Py_None) {" % info)
1274 code.put_gotref("Py_None")
1275 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1278 class CFuncDefNode(FuncDefNode):
1279 # C function definition.
1281 # modifiers ['inline']
1282 # visibility 'private' or 'public' or 'extern'
1283 # base_type CBaseTypeNode
1284 # declarator CDeclaratorNode
1287 # decorators [DecoratorNode] list of decorators
1289 # with_gil boolean Acquire GIL around body
1291 # py_func wrapper for calling from Python
1292 # overridable whether or not this is a cpdef function
1293 # inline_in_pxd whether this is an inline function in a pxd file
1295 child_attrs = ["base_type", "declarator", "body", "py_func"]
1297 inline_in_pxd = False
1299 directive_locals = {}
1301 def unqualified_name(self):
1302 return self.entry.name
1304 def analyse_declarations(self, env):
1305 if 'locals' in env.directives and env.directives['locals']:
1306 self.directive_locals = env.directives['locals']
1307 directive_locals = self.directive_locals
1308 base_type = self.base_type.analyse(env)
1309 # The 2 here is because we need both function and argument names.
1310 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1311 if not type.is_cfunction:
1313 "Suite attached to non-function declaration")
1314 # Remember the actual type according to the function header
1315 # written here, because the type in the symbol table entry
1316 # may be different if we're overriding a C method inherited
1317 # from the base type of an extension type.
1319 type.is_overridable = self.overridable
1320 declarator = self.declarator
1321 while not hasattr(declarator, 'args'):
1322 declarator = declarator.base
1323 self.args = declarator.args
1324 for formal_arg, type_arg in zip(self.args, type.args):
1325 formal_arg.type = type_arg.type
1326 formal_arg.name = type_arg.name
1327 formal_arg.cname = type_arg.cname
1328 name = name_declarator.name
1329 cname = name_declarator.cname
1330 self.entry = env.declare_cfunction(
1331 name, type, self.pos,
1332 cname = cname, visibility = self.visibility,
1333 defining = self.body is not None,
1334 api = self.api, modifiers = self.modifiers)
1335 self.entry.inline_func_in_pxd = self.inline_in_pxd
1336 self.return_type = type.return_type
1338 if self.overridable and not env.is_module_scope:
1339 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1340 # An error will be produced in the cdef function
1341 self.overridable = False
1343 if self.overridable:
1345 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1346 self.py_func = DefNode(pos = self.pos,
1347 name = self.entry.name,
1350 starstar_arg = None,
1352 body = py_func_body,
1354 self.py_func.is_module_scope = env.is_module_scope
1355 self.py_func.analyse_declarations(env)
1356 self.entry.as_variable = self.py_func.entry
1357 # Reset scope entry the above cfunction
1358 env.entries[name] = self.entry
1359 self.py_func.interned_attr_cname = env.intern_identifier(
1360 self.py_func.entry.name)
1361 if not env.is_module_scope or Options.lookup_module_cpdef:
1362 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1363 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1365 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1367 args = self.type.args
1368 if omit_optional_args:
1369 args = args[:len(args) - self.type.optional_arg_count]
1370 arg_names = [arg.name for arg in args]
1372 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1374 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1375 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1376 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1377 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)
1378 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1380 def declare_arguments(self, env):
1381 for arg in self.type.args:
1383 error(arg.pos, "Missing argument name")
1384 self.declare_argument(env, arg)
1386 def need_gil_acquisition(self, lenv):
1388 with_gil = self.type.with_gil
1389 if type.nogil and not with_gil:
1390 if type.return_type.is_pyobject:
1392 "Function with Python return type cannot be declared nogil")
1393 for entry in lenv.var_entries + lenv.temp_entries:
1394 if entry.type.is_pyobject:
1395 error(self.pos, "Function declared nogil has Python locals or temporaries")
1398 def analyse_expressions(self, env):
1399 self.analyse_default_values(env)
1400 if self.py_func is not None:
1401 self.py_func.analyse_expressions(env)
1403 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1406 visibility = self.entry.visibility
1407 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1408 arg_decls.append(arg.declaration_code())
1409 if with_dispatch and self.overridable:
1410 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1411 if type.optional_arg_count and with_opt_args:
1412 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1413 if type.has_varargs:
1414 arg_decls.append("...")
1416 arg_decls = ["void"]
1418 cname = self.entry.func_cname
1419 entity = type.function_header_code(cname, ', '.join(arg_decls))
1420 if visibility == 'public':
1421 dll_linkage = "DL_EXPORT"
1424 header = self.return_type.declaration_code(entity,
1425 dll_linkage = dll_linkage)
1426 if visibility == 'extern':
1427 storage_class = "%s " % Naming.extern_c_macro
1428 elif visibility == 'public':
1431 storage_class = "static "
1432 code.putln("%s%s %s {" % (
1434 ' '.join(self.modifiers).upper(), # macro forms
1437 def generate_argument_declarations(self, env, code):
1438 for arg in self.args:
1440 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1442 def generate_keyword_list(self, code):
1445 def generate_argument_parsing_code(self, env, code):
1447 if self.type.optional_arg_count:
1448 code.putln('if (%s) {' % Naming.optional_args_cname)
1449 for arg in self.args:
1451 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1452 declarator = arg.declarator
1453 while not hasattr(declarator, 'name'):
1454 declarator = declarator.base
1455 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1457 for _ in range(self.type.optional_arg_count):
1461 def generate_argument_conversion_code(self, code):
1464 def generate_argument_type_tests(self, code):
1465 # Generate type tests for args whose type in a parent
1466 # class is a supertype of the declared type.
1467 for arg in self.type.args:
1468 if arg.needs_type_test:
1469 self.generate_arg_type_test(arg, code)
1471 def generate_arg_type_test(self, arg, code):
1472 # Generate type test for one argument.
1473 if arg.type.typeobj_is_available():
1474 typeptr_cname = arg.type.typeptr_cname
1475 arg_code = "((PyObject *)%s)" % arg.cname
1477 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1482 type.is_builtin_type,
1483 code.error_goto(arg.pos)))
1485 error(arg.pos, "Cannot test type of extern C class "
1486 "without type object name specification")
1488 def error_value(self):
1489 if self.return_type.is_pyobject:
1493 return self.entry.type.exception_value
1495 def caller_will_check_exceptions(self):
1496 return self.entry.type.exception_check
1498 def generate_wrapper_functions(self, code):
1499 # If the C signature of a function has changed, we need to generate
1500 # wrappers to put in the slots here.
1503 func_type = entry.type
1504 while entry.prev_entry is not None:
1506 entry = entry.prev_entry
1507 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1509 self.generate_function_header(code,
1511 with_dispatch = entry.type.is_overridable,
1512 with_opt_args = entry.type.optional_arg_count,
1513 cname = entry.func_cname)
1514 if not self.return_type.is_void:
1516 args = self.type.args
1517 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1518 if entry.type.is_overridable:
1519 arglist.append(Naming.skip_dispatch_cname)
1520 elif func_type.is_overridable:
1522 if entry.type.optional_arg_count:
1523 arglist.append(Naming.optional_args_cname)
1524 elif func_type.optional_arg_count:
1525 arglist.append('NULL')
1526 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1530 class PyArgDeclNode(Node):
1531 # Argument which must be a Python object (used
1532 # for * and ** arguments).
1535 # entry Symtab.Entry
1539 class DecoratorNode(Node):
1542 # decorator NameNode or CallNode
1543 child_attrs = ['decorator']
1546 class DefNode(FuncDefNode):
1547 # A Python function definition.
1549 # name string the Python name of the function
1550 # decorators [DecoratorNode] list of decorators
1551 # args [CArgDeclNode] formal arguments
1552 # star_arg PyArgDeclNode or None * argument
1553 # starstar_arg PyArgDeclNode or None ** argument
1554 # doc EncodedString or None
1557 # The following subnode is constructed internally
1558 # when the def statement is inside a Python class definition.
1560 # assmt AssignmentNode Function construction/assignment
1562 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1566 num_required_kw_args = 0
1567 reqd_kw_flags_cname = "0"
1573 def __init__(self, pos, **kwds):
1574 FuncDefNode.__init__(self, pos, **kwds)
1576 for arg in self.args:
1583 self.num_kwonly_args = k
1584 self.num_required_kw_args = rk
1585 self.num_required_args = r
1587 def as_cfunction(self, cfunc=None, scope=None):
1589 error(self.star_arg.pos, "cdef function cannot have star argument")
1590 if self.starstar_arg:
1591 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1594 for formal_arg in self.args:
1595 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1596 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1598 type = py_object_type,
1599 pos = formal_arg.pos))
1600 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1602 has_varargs = False,
1603 exception_value = None,
1604 exception_check = False,
1607 is_overridable = True)
1608 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1610 cfunc_type = cfunc.type
1611 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1612 error(self.pos, "wrong number of arguments")
1613 error(declarator.pos, "previous declaration here")
1614 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1615 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1616 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1617 formal_arg.type = type_arg.type
1618 formal_arg.name_declarator = name_declarator
1620 if cfunc_type.exception_value is None:
1621 exception_value = None
1623 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1624 declarator = CFuncDeclaratorNode(self.pos,
1625 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1627 has_varargs = False,
1628 exception_check = cfunc_type.exception_check,
1629 exception_value = exception_value,
1630 with_gil = cfunc_type.with_gil,
1631 nogil = cfunc_type.nogil)
1632 return CFuncDefNode(self.pos,
1634 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1635 declarator = declarator,
1638 overridable = cfunc_type.is_overridable,
1640 with_gil = cfunc_type.with_gil,
1641 nogil = cfunc_type.nogil,
1642 visibility = 'private',
1644 directive_locals = cfunc.directive_locals)
1646 def analyse_declarations(self, env):
1647 if 'locals' in env.directives:
1648 directive_locals = env.directives['locals']
1650 directive_locals = {}
1651 self.directive_locals = directive_locals
1652 for arg in self.args:
1653 if hasattr(arg, 'name'):
1655 name_declarator = None
1657 base_type = arg.base_type.analyse(env)
1658 name_declarator, type = \
1659 arg.declarator.analyse(base_type, env)
1660 arg.name = name_declarator.name
1661 if arg.name in directive_locals:
1662 type_node = directive_locals[arg.name]
1663 other_type = type_node.analyse_as_type(env)
1664 if other_type is None:
1665 error(type_node.pos, "Not a type")
1666 elif (type is not PyrexTypes.py_object_type
1667 and not type.same_as(other_type)):
1668 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1669 error(type_node.pos, "Previous declaration here")
1672 if name_declarator and name_declarator.cname:
1674 "Python function argument cannot have C name specification")
1675 arg.type = type.as_argument_type()
1677 arg.needs_conversion = 0
1678 arg.needs_type_test = 0
1680 if arg.not_none and not arg.type.is_extension_type:
1682 "Only extension type arguments can have 'not None'")
1683 self.declare_pyfunction(env)
1684 self.analyse_signature(env)
1685 self.return_type = self.entry.signature.return_type()
1687 def analyse_signature(self, env):
1688 any_type_tests_needed = 0
1689 # Use the simpler calling signature for zero- and one-argument functions.
1690 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1691 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1692 if len(self.args) == 0:
1693 self.entry.signature = TypeSlots.pyfunction_noargs
1694 elif len(self.args) == 1:
1695 if self.args[0].default is None and not self.args[0].kw_only:
1696 self.entry.signature = TypeSlots.pyfunction_onearg
1697 elif self.entry.signature is TypeSlots.pymethod_signature:
1698 if len(self.args) == 1:
1699 self.entry.signature = TypeSlots.unaryfunc
1700 elif len(self.args) == 2:
1701 if self.args[1].default is None and not self.args[1].kw_only:
1702 self.entry.signature = TypeSlots.ibinaryfunc
1703 elif self.entry.is_special:
1704 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1705 sig = self.entry.signature
1706 nfixed = sig.num_fixed_args()
1707 for i in range(nfixed):
1708 if i < len(self.args):
1711 if sig.is_self_arg(i):
1713 arg.hdr_type = arg.type = env.parent_type
1714 arg.needs_conversion = 0
1716 arg.hdr_type = sig.fixed_arg_type(i)
1717 if not arg.type.same_as(arg.hdr_type):
1718 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1719 arg.needs_type_test = 1
1720 any_type_tests_needed = 1
1722 arg.needs_conversion = 1
1723 if arg.needs_conversion:
1724 arg.hdr_cname = Naming.arg_prefix + arg.name
1726 arg.hdr_cname = Naming.var_prefix + arg.name
1728 self.bad_signature()
1730 if nfixed < len(self.args):
1731 if not sig.has_generic_args:
1732 self.bad_signature()
1733 for arg in self.args:
1734 if arg.is_generic and \
1735 (arg.type.is_extension_type or arg.type.is_builtin_type):
1736 arg.needs_type_test = 1
1737 any_type_tests_needed = 1
1738 if any_type_tests_needed:
1739 env.use_utility_code(arg_type_test_utility_code)
1741 def bad_signature(self):
1742 sig = self.entry.signature
1743 expected_str = "%d" % sig.num_fixed_args()
1744 if sig.has_generic_args:
1745 expected_str = expected_str + " or more"
1747 if name.startswith("__") and name.endswith("__"):
1748 desc = "Special method"
1752 "%s %s has wrong number of arguments "
1753 "(%d declared, %s expected)" % (
1754 desc, self.name, len(self.args), expected_str))
1756 def signature_has_nongeneric_args(self):
1757 argcount = len(self.args)
1758 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1762 def signature_has_generic_args(self):
1763 return self.entry.signature.has_generic_args
1765 def declare_pyfunction(self, env):
1766 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1768 entry = env.lookup_here(self.name)
1769 if entry and entry.type.is_cfunction and not self.is_wrapper:
1770 warning(self.pos, "Overriding cdef method with def method.", 5)
1771 entry = env.declare_pyfunction(self.name, self.pos)
1773 prefix = env.scope_prefix
1774 entry.func_cname = \
1775 Naming.pyfunc_prefix + prefix + name
1776 entry.pymethdef_cname = \
1777 Naming.pymethdef_prefix + prefix + name
1778 if Options.docstrings:
1779 entry.doc = embed_position(self.pos, self.doc)
1781 Naming.funcdoc_prefix + prefix + name
1785 def declare_arguments(self, env):
1786 for arg in self.args:
1788 error(arg.pos, "Missing argument name")
1789 if arg.needs_conversion:
1790 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1791 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1792 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1793 if arg.type.is_pyobject:
1794 arg.entry.init = "0"
1795 arg.entry.init_to_none = 0
1797 arg.entry = self.declare_argument(env, arg)
1799 arg.entry.is_self_arg = arg.is_self_arg
1800 if not arg.is_self_arg:
1801 arg.name_entry = env.get_string_const(
1802 arg.name, identifier = True)
1803 env.add_py_string(arg.name_entry, identifier = True)
1805 if arg.is_self_arg or \
1806 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1807 arg.entry.is_declared_generic = 1
1808 self.declare_python_arg(env, self.star_arg)
1809 self.declare_python_arg(env, self.starstar_arg)
1811 def declare_python_arg(self, env, arg):
1813 entry = env.declare_var(arg.name,
1814 PyrexTypes.py_object_type, arg.pos)
1817 entry.init_to_none = 0
1818 entry.xdecref_cleanup = 1
1820 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1822 def analyse_expressions(self, env):
1823 self.analyse_default_values(env)
1824 if env.is_py_class_scope:
1825 self.synthesize_assignment_node(env)
1827 def synthesize_assignment_node(self, env):
1829 self.assmt = SingleAssignmentNode(self.pos,
1830 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1831 rhs = ExprNodes.UnboundMethodNode(self.pos,
1832 class_cname = env.class_obj_cname,
1833 function = ExprNodes.PyCFunctionNode(self.pos,
1834 pymethdef_cname = self.entry.pymethdef_cname)))
1835 self.assmt.analyse_declarations(env)
1836 self.assmt.analyse_expressions(env)
1838 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1840 sig = self.entry.signature
1841 if sig.has_dummy_arg:
1842 arg_code_list.append(
1843 "PyObject *%s" % Naming.self_cname)
1844 for arg in self.args:
1845 if not arg.is_generic:
1847 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1849 arg_code_list.append(
1850 arg.hdr_type.declaration_code(arg.hdr_cname))
1851 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1852 arg_code_list.append("PyObject *unused")
1853 if sig.has_generic_args:
1854 arg_code_list.append(
1855 "PyObject *%s, PyObject *%s"
1856 % (Naming.args_cname, Naming.kwds_cname))
1857 arg_code = ", ".join(arg_code_list)
1858 dc = self.return_type.declaration_code(self.entry.func_cname)
1859 header = "static %s(%s)" % (dc, arg_code)
1860 code.putln("%s; /*proto*/" % header)
1863 if self.entry.doc and Options.docstrings:
1864 docstr = self.entry.doc
1865 if not isinstance(docstr, str):
1866 docstr = docstr.utf8encode()
1868 'static char %s[] = "%s";' % (
1869 self.entry.doc_cname,
1870 split_docstring(escape_byte_string(docstr))))
1873 "static PyMethodDef %s = " %
1874 self.entry.pymethdef_cname)
1875 code.put_pymethoddef(self.entry, ";")
1876 code.putln("%s {" % header)
1878 def generate_argument_declarations(self, env, code):
1879 for arg in self.args:
1880 if arg.is_generic: # or arg.needs_conversion:
1881 if arg.needs_conversion:
1882 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1884 code.put_var_declaration(arg.entry)
1886 def generate_keyword_list(self, code):
1887 if self.signature_has_generic_args() and \
1888 self.signature_has_nongeneric_args():
1890 "static PyObject **%s[] = {" %
1891 Naming.pykwdlist_cname)
1892 for arg in self.args:
1894 code.put('&%s,' % arg.name_entry.pystring_cname)
1897 def generate_argument_parsing_code(self, env, code):
1898 # Generate PyArg_ParseTuple call for generic
1899 # arguments, if any.
1900 if self.entry.signature.has_dummy_arg:
1901 # get rid of unused argument warning
1902 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1904 old_error_label = code.new_error_label()
1905 our_error_label = code.error_label
1906 end_label = code.new_label("argument_unpacking_done")
1908 has_kwonly_args = self.num_kwonly_args > 0
1909 has_star_or_kw_args = self.star_arg is not None \
1910 or self.starstar_arg is not None or has_kwonly_args
1912 if not self.signature_has_generic_args():
1913 if has_star_or_kw_args:
1914 error(self.pos, "This method cannot have * or keyword arguments")
1915 self.generate_argument_conversion_code(code)
1917 elif not self.signature_has_nongeneric_args():
1918 # func(*args) or func(**kw) or func(*args, **kw)
1919 self.generate_stararg_copy_code(code)
1922 positional_args = []
1925 for arg in self.args:
1926 arg_entry = arg.entry
1930 if not arg.is_self_arg:
1932 kw_only_args.append(arg)
1934 positional_args.append(arg)
1936 kw_only_args.append(arg)
1939 error(arg.pos, "Non-default argument following default argument")
1940 elif not arg.is_self_arg:
1941 positional_args.append(arg)
1943 self.generate_tuple_and_keyword_parsing_code(
1944 positional_args, kw_only_args, end_label, code)
1946 code.error_label = old_error_label
1947 if code.label_used(our_error_label):
1948 if not code.label_used(end_label):
1949 code.put_goto(end_label)
1950 code.put_label(our_error_label)
1951 if has_star_or_kw_args:
1952 self.generate_arg_decref(self.star_arg, code)
1953 if self.starstar_arg:
1954 if self.starstar_arg.entry.xdecref_cleanup:
1955 code.put_var_xdecref(self.starstar_arg.entry)
1957 code.put_var_decref(self.starstar_arg.entry)
1958 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1959 code.putln("return %s;" % self.error_value())
1960 if code.label_used(end_label):
1961 code.put_label(end_label)
1963 def generate_arg_assignment(self, arg, item, code):
1964 if arg.type.is_pyobject:
1966 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1967 code.putln("%s = %s;" % (arg.entry.cname, item))
1969 func = arg.type.from_py_function
1971 code.putln("%s = %s(%s); %s" % (
1975 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1977 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1979 def generate_arg_xdecref(self, arg, code):
1981 code.put_var_xdecref(arg.entry)
1983 def generate_arg_decref(self, arg, code):
1985 code.put_var_decref(arg.entry)
1987 def generate_stararg_copy_code(self, code):
1988 if not self.star_arg:
1989 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1990 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1992 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1993 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1996 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1998 if self.starstar_arg:
2000 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2002 kwarg_check = "%s" % Naming.kwds_cname
2004 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2005 Naming.kwds_cname, Naming.kwds_cname)
2007 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2008 kwarg_check, Naming.kwds_cname, self.name,
2009 bool(self.starstar_arg), self.error_value()))
2011 if self.starstar_arg:
2012 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2013 self.starstar_arg.entry.cname,
2016 code.putln("if (unlikely(!%s)) return %s;" % (
2017 self.starstar_arg.entry.cname, self.error_value()))
2018 self.starstar_arg.entry.xdecref_cleanup = 0
2019 code.put_gotref(self.starstar_arg.entry.cname)
2023 code.put_incref(Naming.args_cname, py_object_type)
2024 code.putln("%s = %s;" % (
2025 self.star_arg.entry.cname,
2027 self.star_arg.entry.xdecref_cleanup = 0
2029 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2030 kw_only_args, success_label, code):
2031 argtuple_error_label = code.new_label("argtuple_error")
2033 min_positional_args = self.num_required_args - self.num_required_kw_args
2034 if len(self.args) > 0 and self.args[0].is_self_arg:
2035 min_positional_args -= 1
2036 max_positional_args = len(positional_args)
2037 has_fixed_positional_count = not self.star_arg and \
2038 min_positional_args == max_positional_args
2040 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2041 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2042 if self.num_required_kw_args:
2043 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2045 if self.starstar_arg or self.star_arg:
2046 self.generate_stararg_init_code(max_positional_args, code)
2048 # --- optimised code when we receive keyword arguments
2049 if self.num_required_kw_args:
2050 likely_hint = "likely"
2052 likely_hint = "unlikely"
2053 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2054 self.generate_keyword_unpacking_code(
2055 min_positional_args, max_positional_args,
2056 has_fixed_positional_count,
2057 positional_args, kw_only_args, argtuple_error_label, code)
2059 # --- optimised code when we do not receive any keyword arguments
2060 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2061 # Python raises arg tuple related errors first, so we must
2062 # check the length here
2063 if min_positional_args == max_positional_args and not self.star_arg:
2067 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2068 Naming.args_cname, compare, min_positional_args))
2069 code.put_goto(argtuple_error_label)
2071 if self.num_required_kw_args:
2072 # pure error case: keywords required but not passed
2073 if max_positional_args > min_positional_args and not self.star_arg:
2074 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2075 Naming.args_cname, max_positional_args))
2076 code.put_goto(argtuple_error_label)
2077 code.putln('} else {')
2078 for i, arg in enumerate(kw_only_args):
2080 # required keyword-only argument missing
2081 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2082 self.name.utf8encode(),
2083 arg.name_entry.pystring_cname))
2084 code.putln(code.error_goto(self.pos))
2087 elif min_positional_args == max_positional_args:
2088 # parse the exact number of positional arguments from the
2090 code.putln('} else {')
2091 for i, arg in enumerate(positional_args):
2092 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2093 self.generate_arg_assignment(arg, item, code)
2094 self.generate_arg_default_assignments(code)
2097 # parse the positional arguments from the variable length
2099 code.putln('} else {')
2100 self.generate_arg_default_assignments(code)
2101 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2103 code.putln('default:')
2104 reversed_args = list(enumerate(positional_args))[::-1]
2105 for i, arg in reversed_args:
2106 if i >= min_positional_args-1:
2107 if min_positional_args > 1:
2108 code.putln('case %2d:' % (i+1)) # pure code beautification
2110 code.put('case %2d: ' % (i+1))
2111 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2112 self.generate_arg_assignment(arg, item, code)
2113 if min_positional_args == 0:
2114 code.put('case 0: ')
2115 code.putln('break;')
2117 if min_positional_args:
2118 for i in range(min_positional_args-1, -1, -1):
2119 code.putln('case %2d:' % i)
2120 code.put_goto(argtuple_error_label)
2122 code.put('default: ')
2123 code.put_goto(argtuple_error_label)
2128 if code.label_used(argtuple_error_label):
2129 code.put_goto(success_label)
2130 code.put_label(argtuple_error_label)
2131 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2132 self.name.utf8encode(), has_fixed_positional_count,
2133 min_positional_args, max_positional_args,
2135 code.putln(code.error_goto(self.pos))
2137 def generate_arg_default_assignments(self, code):
2138 for arg in self.args:
2139 if arg.is_generic and arg.default:
2143 arg.default_result_code))
2145 def generate_stararg_init_code(self, max_positional_args, code):
2146 if self.starstar_arg:
2147 self.starstar_arg.entry.xdecref_cleanup = 0
2148 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2149 self.starstar_arg.entry.cname,
2150 self.starstar_arg.entry.cname,
2151 self.error_value()))
2152 code.put_gotref(self.starstar_arg.entry.cname)
2154 self.star_arg.entry.xdecref_cleanup = 0
2155 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2157 max_positional_args))
2158 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2159 self.star_arg.entry.cname, Naming.args_cname,
2160 max_positional_args, Naming.args_cname))
2161 code.put_gotref(self.star_arg.entry.cname)
2162 if self.starstar_arg:
2164 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2165 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2166 code.putln('return %s;' % self.error_value())
2169 code.putln("if (unlikely(!%s)) return %s;" % (
2170 self.star_arg.entry.cname, self.error_value()))
2171 code.putln('} else {')
2172 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2173 code.put_incref(Naming.empty_tuple, py_object_type)
2176 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2177 has_fixed_positional_count, positional_args,
2178 kw_only_args, argtuple_error_label, code):
2179 all_args = tuple(positional_args) + tuple(kw_only_args)
2180 max_args = len(all_args)
2183 for i, arg in enumerate(all_args):
2184 if arg.default and arg.type.is_pyobject:
2185 default_value = arg.default_result_code
2186 if arg.type is not PyrexTypes.py_object_type:
2187 default_value = "(PyObject*)"+default_value
2188 default_args.append((i, default_value))
2190 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2192 # it looks funny to separate the init-to-0 from setting the
2193 # default value, but C89 needs this
2194 code.putln("PyObject* values[%d] = {%s};" % (
2195 max_args, ','.join(['0']*max_args)))
2196 for i, default_value in default_args:
2197 code.putln('values[%d] = %s;' % (i, default_value))
2199 # parse the tuple and check that it's not too long
2200 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2202 code.putln('default:')
2203 for i in range(max_positional_args-1, -1, -1):
2204 code.put('case %2d: ' % (i+1))
2205 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2206 i, Naming.args_cname, i))
2207 code.putln('case 0: break;')
2208 if not self.star_arg:
2209 code.put('default: ') # more arguments than allowed
2210 code.put_goto(argtuple_error_label)
2213 # now fill up the positional/required arguments with values
2215 if self.num_required_args or max_positional_args > 0:
2216 last_required_arg = -1
2217 for i, arg in enumerate(all_args):
2219 last_required_arg = i
2220 if last_required_arg < max_positional_args:
2221 last_required_arg = max_positional_args-1
2222 num_required_args = self.num_required_args
2223 if max_positional_args > 0:
2224 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2225 for i, arg in enumerate(all_args[:last_required_arg+1]):
2226 if max_positional_args > 0 and i <= max_positional_args:
2227 if self.star_arg and i == max_positional_args:
2228 code.putln('default:')
2230 code.putln('case %2d:' % i)
2233 # handled separately below
2235 code.putln('if (kw_args > %d) {' % num_required_args)
2236 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2237 Naming.kwds_cname, arg.name_entry.pystring_cname))
2238 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2241 num_required_args -= 1
2242 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2243 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2244 code.putln('if (likely(values[%d])) kw_args--;' % i);
2245 if i < min_positional_args:
2247 # special case: we know arg 0 is missing
2249 code.put_goto(argtuple_error_label)
2251 # print the correct number of values (args or
2252 # kwargs) that were passed into positional
2253 # arguments up to this point
2254 code.putln('else {')
2255 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2256 self.name.utf8encode(), has_fixed_positional_count,
2257 min_positional_args, max_positional_args, i))
2258 code.putln(code.error_goto(self.pos))
2261 code.putln('else {')
2262 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2263 self.name.utf8encode(), arg.name_entry.pystring_cname))
2264 code.putln(code.error_goto(self.pos))
2266 if max_positional_args > 0:
2269 if kw_only_args and not self.starstar_arg:
2270 # unpack optional keyword-only arguments
2271 # checking for interned strings in a dict is faster than iterating
2272 # but it's too likely that we must iterate if we expect **kwargs
2274 for i, arg in enumerate(all_args[max_positional_args:]):
2275 if not arg.kw_only or not arg.default:
2277 optional_args.append((i+max_positional_args, arg))
2279 # this mimics an unrolled loop so that we can "break" out of it
2280 code.putln('while (kw_args > 0) {')
2281 code.putln('PyObject* value;')
2282 for i, arg in optional_args:
2284 'value = PyDict_GetItem(%s, %s);' % (
2285 Naming.kwds_cname, arg.name_entry.pystring_cname))
2287 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2288 code.putln('break;')
2291 code.putln('if (unlikely(kw_args > 0)) {')
2292 # non-positional/-required kw args left in dict: default args,
2293 # kw-only args, **kwargs or error
2295 # This is sort of a catch-all: except for checking required
2296 # arguments, this will always do the right thing for unpacking
2297 # keyword arguments, so that we can concentrate on optimising
2298 # common cases above.
2299 if max_positional_args == 0:
2302 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2303 Naming.args_cname, max_positional_args,
2304 Naming.args_cname, max_positional_args))
2305 pos_arg_count = "used_pos_args"
2307 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2308 code.globalstate.use_utility_code(parse_keywords_utility_code)
2310 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2312 Naming.pykwdlist_cname,
2313 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2315 self.name.utf8encode()))
2316 code.putln(code.error_goto(self.pos))
2319 # convert arg values to their final type and assign them
2320 for i, arg in enumerate(all_args):
2321 if arg.default and not arg.type.is_pyobject:
2322 code.putln("if (values[%d]) {" % i)
2323 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2324 if arg.default and not arg.type.is_pyobject:
2325 code.putln('} else {')
2329 arg.default_result_code))
2332 def generate_argument_conversion_code(self, code):
2333 # Generate code to convert arguments from
2334 # signature type to declared type, if needed.
2335 for arg in self.args:
2336 if arg.needs_conversion:
2337 self.generate_arg_conversion(arg, code)
2339 def generate_arg_conversion(self, arg, code):
2340 # Generate conversion code for one argument.
2341 old_type = arg.hdr_type
2343 if old_type.is_pyobject:
2345 code.putln("if (%s) {" % arg.hdr_cname)
2347 code.putln("assert(%s); {" % arg.hdr_cname)
2348 self.generate_arg_conversion_from_pyobject(arg, code)
2350 elif new_type.is_pyobject:
2351 self.generate_arg_conversion_to_pyobject(arg, code)
2353 if new_type.assignable_from(old_type):
2355 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2358 "Cannot convert 1 argument from '%s' to '%s'" %
2359 (old_type, new_type))
2361 def generate_arg_conversion_from_pyobject(self, arg, code):
2363 func = new_type.from_py_function
2364 # copied from CoerceFromPyTypeNode
2366 code.putln("%s = %s(%s); %s" % (
2370 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2373 "Cannot convert Python object argument to type '%s'"
2376 def generate_arg_conversion_to_pyobject(self, arg, code):
2377 old_type = arg.hdr_type
2378 func = old_type.to_py_function
2380 code.putln("%s = %s(%s); %s" % (
2384 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2385 code.put_var_gotref(arg.entry)
2388 "Cannot convert argument of type '%s' to Python object"
2391 def generate_argument_type_tests(self, code):
2392 # Generate type tests for args whose signature
2393 # type is PyObject * and whose declared type is
2394 # a subtype thereof.
2395 for arg in self.args:
2396 if arg.needs_type_test:
2397 self.generate_arg_type_test(arg, code)
2399 def generate_arg_type_test(self, arg, code):
2400 # Generate type test for one argument.
2401 if arg.type.typeobj_is_available():
2402 typeptr_cname = arg.type.typeptr_cname
2403 arg_code = "((PyObject *)%s)" % arg.entry.cname
2405 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2410 arg.type.is_builtin_type,
2411 code.error_goto(arg.pos)))
2413 error(arg.pos, "Cannot test type of extern C class "
2414 "without type object name specification")
2416 def error_value(self):
2417 return self.entry.signature.error_value
2419 def caller_will_check_exceptions(self):
2422 class OverrideCheckNode(StatNode):
2423 # A Node for dispatching to the def method if it
2432 child_attrs = ['body']
2436 def analyse_expressions(self, env):
2437 self.args = env.arg_entries
2438 if self.py_func.is_module_scope:
2443 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2444 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2445 call_node = ExprNodes.SimpleCallNode(self.pos,
2446 function=self.func_node,
2447 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2448 self.body = ReturnStatNode(self.pos, value=call_node)
2449 self.body.analyse_expressions(env)
2451 def generate_execution_code(self, code):
2452 # Check to see if we are an extension type
2453 if self.py_func.is_module_scope:
2454 self_arg = "((PyObject *)%s)" % Naming.module_cname
2456 self_arg = "((PyObject *)%s)" % self.args[0].cname
2457 code.putln("/* Check if called by wrapper */")
2458 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2459 code.putln("/* Check if overriden in Python */")
2460 if self.py_func.is_module_scope:
2461 code.putln("else {")
2463 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2464 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2465 # need to get attribute manually--scope would return cdef method
2466 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2467 code.put_gotref(self.func_node.py_result())
2468 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2469 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2470 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2471 self.body.generate_execution_code(code)
2473 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2476 class ClassDefNode(StatNode, BlockNode):
2479 class PyClassDefNode(ClassDefNode):
2480 # A Python class definition.
2482 # name EncodedString Name of the class
2483 # doc string or None
2484 # body StatNode Attribute definition code
2485 # entry Symtab.Entry
2486 # scope PyClassScope
2488 # The following subnodes are constructed internally:
2490 # dict DictNode Class dictionary
2491 # classobj ClassNode Class object
2492 # target NameNode Variable to assign class object to
2494 child_attrs = ["body", "dict", "classobj", "target"]
2496 def __init__(self, pos, name, bases, doc, body):
2497 StatNode.__init__(self, pos)
2502 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2503 if self.doc and Options.docstrings:
2504 doc = embed_position(self.pos, self.doc)
2505 doc_node = ExprNodes.StringNode(pos, value = doc)
2508 self.classobj = ExprNodes.ClassNode(pos, name = name,
2509 bases = bases, dict = self.dict, doc = doc_node)
2510 self.target = ExprNodes.NameNode(pos, name = name)
2512 def as_cclass(self):
2514 Return this node as if it were declared as an extension class
2516 bases = self.classobj.bases.args
2518 base_class_name = None
2519 base_class_module = None
2520 elif len(bases) == 1:
2523 from ExprNodes import AttributeNode, NameNode
2524 while isinstance(base, AttributeNode):
2525 path.insert(0, base.attribute)
2527 if isinstance(base, NameNode):
2528 path.insert(0, base.name)
2529 base_class_name = path[-1]
2531 base_class_module = u'.'.join(path[:-1])
2533 base_class_module = None
2535 error(self.classobj.bases.args.pos, "Invalid base class")
2537 error(self.classobj.bases.args.pos, "C class may only have one base class")
2540 return CClassDefNode(self.pos,
2541 visibility = 'private',
2543 class_name = self.name,
2544 base_class_module = base_class_module,
2545 base_class_name = base_class_name,
2550 def create_scope(self, env):
2552 while env.is_py_class_scope or env.is_c_class_scope:
2553 env = env.outer_scope
2554 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2557 def analyse_declarations(self, env):
2558 self.target.analyse_target_declaration(env)
2559 cenv = self.create_scope(env)
2560 cenv.class_obj_cname = self.target.entry.cname
2561 self.body.analyse_declarations(cenv)
2563 def analyse_expressions(self, env):
2564 self.dict.analyse_expressions(env)
2565 self.classobj.analyse_expressions(env)
2566 genv = env.global_scope()
2568 cenv.class_dict_cname = self.dict.result()
2569 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2570 self.body.analyse_expressions(cenv)
2571 self.target.analyse_target_expression(env, self.classobj)
2572 self.dict.release_temp(env)
2573 #self.classobj.release_temp(env)
2574 #self.target.release_target_temp(env)
2576 def generate_function_definitions(self, env, code):
2577 self.generate_py_string_decls(self.scope, code)
2578 self.body.generate_function_definitions(self.scope, code)
2580 def generate_execution_code(self, code):
2581 self.dict.generate_evaluation_code(code)
2582 self.classobj.generate_evaluation_code(code)
2583 self.body.generate_execution_code(code)
2584 self.target.generate_assignment_code(self.classobj, code)
2585 self.dict.generate_disposal_code(code)
2586 self.dict.free_temps(code)
2589 class CClassDefNode(ClassDefNode):
2590 # An extension type definition.
2592 # visibility 'private' or 'public' or 'extern'
2593 # typedef_flag boolean
2595 # module_name string or None For import of extern type objects
2596 # class_name string Unqualified name of class
2597 # as_name string or None Name to declare as in this scope
2598 # base_class_module string or None Module containing the base class
2599 # base_class_name string or None Name of the base class
2600 # objstruct_name string or None Specified C name of object struct
2601 # typeobj_name string or None Specified C name of type object
2602 # in_pxd boolean Is in a .pxd file
2603 # doc string or None
2604 # body StatNode or None
2605 # entry Symtab.Entry
2606 # base_type PyExtensionType or None
2607 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2608 # buffer_defaults_pos
2610 child_attrs = ["body"]
2611 buffer_defaults_node = None
2612 buffer_defaults_pos = None
2613 typedef_flag = False
2615 objstruct_name = None
2618 def analyse_declarations(self, env):
2619 #print "CClassDefNode.analyse_declarations:", self.class_name
2620 #print "...visibility =", self.visibility
2621 #print "...module_name =", self.module_name
2624 if self.buffer_defaults_node:
2625 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2626 env, [], self.buffer_defaults_node,
2627 need_complete=False)
2629 buffer_defaults = None
2631 if env.in_cinclude and not self.objstruct_name:
2632 error(self.pos, "Object struct name specification required for "
2633 "C class defined in 'extern from' block")
2634 self.base_type = None
2635 # Now that module imports are cached, we need to
2636 # import the modules for extern classes.
2637 if self.module_name:
2639 for module in env.cimported_modules:
2640 if module.name == self.module_name:
2641 self.module = module
2642 if self.module is None:
2643 self.module = ModuleScope(self.module_name, None, env.context)
2644 self.module.has_extern_class = 1
2645 env.add_imported_module(self.module)
2647 if self.base_class_name:
2648 if self.base_class_module:
2649 base_class_scope = env.find_module(self.base_class_module, self.pos)
2651 base_class_scope = env
2652 if self.base_class_name == 'object':
2653 # extension classes are special and don't need to inherit from object
2654 if base_class_scope is None or base_class_scope.lookup('object') is None:
2655 self.base_class_name = None
2656 self.base_class_module = None
2657 base_class_scope = None
2658 if base_class_scope:
2659 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2660 if base_class_entry:
2661 if not base_class_entry.is_type:
2662 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2663 elif not base_class_entry.type.is_extension_type:
2664 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2665 elif not base_class_entry.type.is_complete():
2666 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2668 self.base_type = base_class_entry.type
2669 has_body = self.body is not None
2670 if self.module_name and self.visibility != 'extern':
2671 module_path = self.module_name.split(".")
2672 home_scope = env.find_imported_module(module_path, self.pos)
2678 if self.visibility == 'extern':
2679 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2680 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2682 self.entry = home_scope.declare_c_class(
2683 name = self.class_name,
2685 defining = has_body and self.in_pxd,
2686 implementing = has_body and not self.in_pxd,
2687 module_name = self.module_name,
2688 base_type = self.base_type,
2689 objstruct_cname = self.objstruct_name,
2690 typeobj_cname = self.typeobj_name,
2691 visibility = self.visibility,
2692 typedef_flag = self.typedef_flag,
2694 buffer_defaults = buffer_defaults)
2695 if home_scope is not env and self.visibility == 'extern':
2696 env.add_imported_entry(self.class_name, self.entry, pos)
2697 scope = self.entry.type.scope
2699 if self.doc and Options.docstrings:
2700 scope.doc = embed_position(self.pos, self.doc)
2703 self.body.analyse_declarations(scope)
2707 scope.implemented = 1
2708 env.allocate_vtable_names(self.entry)
2710 def analyse_expressions(self, env):
2712 scope = self.entry.type.scope
2713 self.body.analyse_expressions(scope)
2715 def generate_function_definitions(self, env, code):
2716 self.generate_py_string_decls(self.entry.type.scope, code)
2718 self.body.generate_function_definitions(
2719 self.entry.type.scope, code)
2721 def generate_execution_code(self, code):
2722 # This is needed to generate evaluation code for
2723 # default values of method arguments.
2725 self.body.generate_execution_code(code)
2727 def annotate(self, code):
2729 self.body.annotate(code)
2732 class PropertyNode(StatNode):
2733 # Definition of a property in an extension type.
2736 # doc EncodedString or None Doc string
2739 child_attrs = ["body"]
2741 def analyse_declarations(self, env):
2742 entry = env.declare_property(self.name, self.doc, self.pos)
2744 if self.doc and Options.docstrings:
2745 doc_entry = env.get_string_const(
2746 self.doc, identifier = False)
2747 entry.doc_cname = doc_entry.cname
2748 self.body.analyse_declarations(entry.scope)
2750 def analyse_expressions(self, env):
2751 self.body.analyse_expressions(env)
2753 def generate_function_definitions(self, env, code):
2754 self.body.generate_function_definitions(env, code)
2756 def generate_execution_code(self, code):
2759 def annotate(self, code):
2760 self.body.annotate(code)
2763 class GlobalNode(StatNode):
2764 # Global variable declaration.
2770 def analyse_declarations(self, env):
2771 for name in self.names:
2772 env.declare_global(name, self.pos)
2774 def analyse_expressions(self, env):
2777 def generate_execution_code(self, code):
2781 class ExprStatNode(StatNode):
2782 # Expression used as a statement.
2786 child_attrs = ["expr"]
2788 def analyse_declarations(self, env):
2790 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2791 func = self.expr.function.as_cython_attribute()
2792 if func == u'declare':
2793 args, kwds = self.expr.explicit_args_kwds()
2795 error(self.expr.pos, "Variable names must be specified.")
2796 for var, type_node in kwds.key_value_pairs:
2797 type = type_node.analyse_as_type(env)
2799 error(type_node.pos, "Unknown type")
2801 env.declare_var(var.value, type, var.pos, is_cdef = True)
2802 self.__class__ = PassStatNode
2804 def analyse_expressions(self, env):
2805 self.expr.analyse_expressions(env)
2806 self.expr.release_temp(env)
2808 def generate_execution_code(self, code):
2809 self.expr.generate_evaluation_code(code)
2810 if not self.expr.is_temp and self.expr.result():
2811 code.putln("%s;" % self.expr.result())
2812 self.expr.generate_disposal_code(code)
2813 self.expr.free_temps(code)
2815 def annotate(self, code):
2816 self.expr.annotate(code)
2819 class AssignmentNode(StatNode):
2820 # Abstract base class for assignment nodes.
2822 # The analyse_expressions and generate_execution_code
2823 # phases of assignments are split into two sub-phases
2824 # each, to enable all the right hand sides of a
2825 # parallel assignment to be evaluated before assigning
2826 # to any of the left hand sides.
2828 def analyse_expressions(self, env):
2829 self.analyse_types(env)
2830 self.allocate_rhs_temps(env)
2831 self.allocate_lhs_temps(env)
2833 # def analyse_expressions(self, env):
2834 # self.analyse_expressions_1(env)
2835 # self.analyse_expressions_2(env)
2837 def generate_execution_code(self, code):
2838 self.generate_rhs_evaluation_code(code)
2839 self.generate_assignment_code(code)
2842 class SingleAssignmentNode(AssignmentNode):
2843 # The simplest case:
2847 # lhs ExprNode Left hand side
2848 # rhs ExprNode Right hand side
2849 # first bool Is this guaranteed the first assignment to lhs?
2851 child_attrs = ["lhs", "rhs"]
2853 declaration_only = False
2855 def analyse_declarations(self, env):
2858 # handle declarations of the form x = cython.foo()
2859 if isinstance(self.rhs, ExprNodes.CallNode):
2860 func_name = self.rhs.function.as_cython_attribute()
2862 args, kwds = self.rhs.explicit_args_kwds()
2864 if func_name in ['declare', 'typedef']:
2865 if len(args) > 2 or kwds is not None:
2866 error(rhs.pos, "Can only declare one type at a time.")
2868 type = args[0].analyse_as_type(env)
2870 error(args[0].pos, "Unknown type")
2873 if func_name == 'declare':
2874 if isinstance(lhs, ExprNodes.NameNode):
2875 vars = [(lhs.name, lhs.pos)]
2876 elif isinstance(lhs, ExprNodes.TupleNode):
2877 vars = [(var.name, var.pos) for var in lhs.args]
2879 error(lhs.pos, "Invalid declaration")
2881 for var, pos in vars:
2882 env.declare_var(var, type, pos, is_cdef = True)
2887 self.declaration_only = True
2889 self.declaration_only = True
2890 if not isinstance(lhs, ExprNodes.NameNode):
2891 error(lhs.pos, "Invalid declaration.")
2892 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2894 elif func_name in ['struct', 'union']:
2895 self.declaration_only = True
2896 if len(args) > 0 or kwds is None:
2897 error(rhs.pos, "Struct or union members must be given by name.")
2900 for member, type_node in kwds.key_value_pairs:
2901 type = type_node.analyse_as_type(env)
2903 error(type_node.pos, "Unknown type")
2905 members.append((member.value, type, member.pos))
2906 if len(members) < len(kwds.key_value_pairs):
2908 if not isinstance(self.lhs, ExprNodes.NameNode):
2909 error(self.lhs.pos, "Invalid declaration.")
2910 name = self.lhs.name
2911 scope = StructOrUnionScope(name)
2912 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2913 for member, type, pos in members:
2914 scope.declare_var(member, type, pos)
2916 if self.declaration_only:
2919 self.lhs.analyse_target_declaration(env)
2921 def analyse_types(self, env, use_temp = 0):
2922 self.rhs.analyse_types(env)
2923 self.lhs.analyse_target_types(env)
2924 self.lhs.gil_assignment_check(env)
2925 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2927 self.rhs = self.rhs.coerce_to_temp(env)
2929 def allocate_rhs_temps(self, env):
2930 self.rhs.allocate_temps(env)
2932 def allocate_lhs_temps(self, env):
2933 self.lhs.allocate_target_temps(env, self.rhs)
2934 #self.lhs.release_target_temp(env)
2935 #self.rhs.release_temp(env)
2937 def generate_rhs_evaluation_code(self, code):
2938 self.rhs.generate_evaluation_code(code)
2940 def generate_assignment_code(self, code):
2941 self.lhs.generate_assignment_code(self.rhs, code)
2943 def annotate(self, code):
2944 self.lhs.annotate(code)
2945 self.rhs.annotate(code)
2948 class CascadedAssignmentNode(AssignmentNode):
2949 # An assignment with multiple left hand sides:
2953 # lhs_list [ExprNode] Left hand sides
2954 # rhs ExprNode Right hand sides
2958 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2960 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2961 coerced_rhs_list = None
2963 def analyse_declarations(self, env):
2964 for lhs in self.lhs_list:
2965 lhs.analyse_target_declaration(env)
2967 def analyse_types(self, env, use_temp = 0):
2968 self.rhs.analyse_types(env)
2970 self.rhs = self.rhs.coerce_to_temp(env)
2972 self.rhs = self.rhs.coerce_to_simple(env)
2973 from ExprNodes import CloneNode
2974 self.coerced_rhs_list = []
2975 for lhs in self.lhs_list:
2976 lhs.analyse_target_types(env)
2977 lhs.gil_assignment_check(env)
2978 rhs = CloneNode(self.rhs)
2979 rhs = rhs.coerce_to(lhs.type, env)
2980 self.coerced_rhs_list.append(rhs)
2982 def allocate_rhs_temps(self, env):
2983 self.rhs.allocate_temps(env)
2985 def allocate_lhs_temps(self, env):
2986 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2987 rhs.allocate_temps(env)
2988 lhs.allocate_target_temps(env, rhs)
2989 #lhs.release_target_temp(env)
2990 #rhs.release_temp(env)
2991 self.rhs.release_temp(env)
2993 def generate_rhs_evaluation_code(self, code):
2994 self.rhs.generate_evaluation_code(code)
2996 def generate_assignment_code(self, code):
2997 for i in range(len(self.lhs_list)):
2998 lhs = self.lhs_list[i]
2999 rhs = self.coerced_rhs_list[i]
3000 rhs.generate_evaluation_code(code)
3001 lhs.generate_assignment_code(rhs, code)
3002 # Assignment has disposed of the cloned RHS
3003 self.rhs.generate_disposal_code(code)
3004 self.rhs.free_temps(code)
3006 def annotate(self, code):
3007 for i in range(len(self.lhs_list)):
3008 lhs = self.lhs_list[i].annotate(code)
3009 rhs = self.coerced_rhs_list[i].annotate(code)
3010 self.rhs.annotate(code)
3013 class ParallelAssignmentNode(AssignmentNode):
3014 # A combined packing/unpacking assignment:
3018 # This has been rearranged by the parser into
3020 # a = d ; b = e ; c = f
3022 # but we must evaluate all the right hand sides
3023 # before assigning to any of the left hand sides.
3025 # stats [AssignmentNode] The constituent assignments
3027 child_attrs = ["stats"]
3029 def analyse_declarations(self, env):
3030 for stat in self.stats:
3031 stat.analyse_declarations(env)
3033 def analyse_expressions(self, env):
3034 for stat in self.stats:
3035 stat.analyse_types(env, use_temp = 1)
3036 stat.allocate_rhs_temps(env)
3037 for stat in self.stats:
3038 stat.allocate_lhs_temps(env)
3040 # def analyse_expressions(self, env):
3041 # for stat in self.stats:
3042 # stat.analyse_expressions_1(env, use_temp = 1)
3043 # for stat in self.stats:
3044 # stat.analyse_expressions_2(env)
3046 def generate_execution_code(self, code):
3047 for stat in self.stats:
3048 stat.generate_rhs_evaluation_code(code)
3049 for stat in self.stats:
3050 stat.generate_assignment_code(code)
3052 def annotate(self, code):
3053 for stat in self.stats:
3057 class InPlaceAssignmentNode(AssignmentNode):
3058 # An in place arithmatic operand:
3064 # lhs ExprNode Left hand side
3065 # rhs ExprNode Right hand side
3066 # op char one of "+-*/%^&|"
3067 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3069 # This code is a bit tricky because in order to obey Python
3070 # semantics the sub-expressions (e.g. indices) of the lhs must
3071 # not be evaluated twice. So we must re-use the values calculated
3072 # in evaluation phase for the assignment phase as well.
3073 # Fortunately, the type of the lhs node is fairly constrained
3074 # (it must be a NameNode, AttributeNode, or IndexNode).
3076 child_attrs = ["lhs", "rhs"]
3079 def analyse_declarations(self, env):
3080 self.lhs.analyse_target_declaration(env)
3082 def analyse_types(self, env):
3083 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3084 self.rhs.analyse_types(env)
3085 self.lhs.analyse_target_types(env)
3086 if Options.incref_local_binop and self.dup.type.is_pyobject:
3087 self.dup = self.dup.coerce_to_temp(env)
3089 def allocate_rhs_temps(self, env):
3091 if self.lhs.type.is_pyobject:
3092 self.rhs = self.rhs.coerce_to_pyobject(env)
3093 elif self.rhs.type.is_pyobject:
3094 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3095 if self.lhs.type.is_pyobject:
3096 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3097 self.result_value.allocate_temps(env)
3099 # self.rhs = self.rhs.coerce_to_temp(env)
3100 self.rhs.allocate_temps(env)
3101 self.dup.allocate_subexpr_temps(env)
3102 self.dup.allocate_temp(env)
3104 def allocate_lhs_temps(self, env):
3105 self.lhs.allocate_target_temps(env, self.rhs)
3106 # self.lhs.release_target_temp(env)
3107 self.dup.release_temp(env)
3108 if self.dup.is_temp:
3109 self.dup.release_subexpr_temps(env)
3110 # self.rhs.release_temp(env)
3111 if self.lhs.type.is_pyobject:
3112 self.result_value.release_temp(env)
3114 def generate_execution_code(self, code):
3116 self.rhs.generate_evaluation_code(code)
3117 self.dup.generate_subexpr_evaluation_code(code)
3118 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3119 # This is because we're manually messing with subexpr nodes
3120 if self.dup.is_temp:
3121 self.dup.allocate_temp_result(code)
3122 # self.dup.generate_result_code is run only if it is not buffer access
3123 if self.operator == "**":
3127 if self.lhs.type.is_pyobject:
3128 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3129 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3130 self.dup.generate_result_code(code)
3132 "%s = %s(%s, %s%s); %s" % (
3133 self.result_value.result(),
3134 self.py_operation_function(),
3135 self.dup.py_result(),
3136 self.rhs.py_result(),
3138 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3139 code.put_gotref(self.result_value.py_result())
3140 self.result_value.generate_evaluation_code(code) # May be a type check...
3141 self.rhs.generate_disposal_code(code)
3142 self.rhs.free_temps(code)
3143 self.dup.generate_disposal_code(code)
3144 self.dup.free_temps(code)
3145 self.lhs.generate_assignment_code(self.result_value, code)
3147 c_op = self.operator
3151 if self.lhs.type.is_int and self.rhs.type.is_int:
3152 error(self.pos, "** with two C int types is ambiguous")
3154 error(self.pos, "No C inplace power operator")
3155 # have to do assignment directly to avoid side-effects
3156 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3157 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3159 self.dup.generate_result_code(code)
3160 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3161 self.rhs.generate_disposal_code(code)
3162 self.rhs.free_temps(code)
3163 if self.dup.is_temp:
3164 self.dup.generate_subexpr_disposal_code(code)
3165 self.dup.free_subexpr_temps(code)
3167 def create_dup_node(self, env):
3170 self.dup.analyse_types(env)
3171 if isinstance(self.lhs, ExprNodes.NameNode):
3172 target_lhs = ExprNodes.NameNode(self.dup.pos,
3173 name = self.dup.name,
3174 is_temp = self.dup.is_temp,
3175 entry = self.dup.entry)
3176 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3177 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3178 obj = ExprNodes.CloneNode(self.lhs.obj),
3179 attribute = self.dup.attribute,
3180 is_temp = self.dup.is_temp)
3181 elif isinstance(self.lhs, ExprNodes.IndexNode):
3183 index = ExprNodes.CloneNode(self.lhs.index)
3186 if self.lhs.indices:
3187 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3190 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3191 base = ExprNodes.CloneNode(self.dup.base),
3194 is_temp = self.dup.is_temp)
3197 self.lhs = target_lhs
3200 def py_operation_function(self):
3201 return self.py_functions[self.operator]
3204 "|": "PyNumber_InPlaceOr",
3205 "^": "PyNumber_InPlaceXor",
3206 "&": "PyNumber_InPlaceAnd",
3207 "+": "PyNumber_InPlaceAdd",
3208 "-": "PyNumber_InPlaceSubtract",
3209 "*": "PyNumber_InPlaceMultiply",
3210 "/": "PyNumber_InPlaceDivide",
3211 "%": "PyNumber_InPlaceRemainder",
3212 "<<": "PyNumber_InPlaceLshift",
3213 ">>": "PyNumber_InPlaceRshift",
3214 "**": "PyNumber_InPlacePower",
3215 "//": "PyNumber_InPlaceFloorDivide",
3218 def annotate(self, code):
3219 self.lhs.annotate(code)
3220 self.rhs.annotate(code)
3221 self.dup.annotate(code)
3224 class PrintStatNode(StatNode):
3227 # arg_tuple TupleNode
3228 # append_newline boolean
3230 child_attrs = ["arg_tuple"]
3232 def analyse_expressions(self, env):
3233 self.arg_tuple.analyse_expressions(env)
3234 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3235 self.arg_tuple.release_temp(env)
3236 env.use_utility_code(printing_utility_code)
3237 if len(self.arg_tuple.args) == 1 and self.append_newline:
3238 env.use_utility_code(printing_one_utility_code)
3241 gil_message = "Python print statement"
3243 def generate_execution_code(self, code):
3244 if len(self.arg_tuple.args) == 1 and self.append_newline:
3245 arg = self.arg_tuple.args[0]
3246 arg.generate_evaluation_code(code)
3249 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3251 code.error_goto(self.pos)))
3252 arg.generate_disposal_code(code)
3253 arg.free_temps(code)
3255 self.arg_tuple.generate_evaluation_code(code)
3257 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3258 self.arg_tuple.py_result(),
3259 self.append_newline,
3260 code.error_goto(self.pos)))
3261 self.arg_tuple.generate_disposal_code(code)
3262 self.arg_tuple.free_temps(code)
3264 def annotate(self, code):
3265 self.arg_tuple.annotate(code)
3268 class ExecStatNode(StatNode):
3273 child_attrs = ["args"]
3275 def analyse_expressions(self, env):
3276 for i, arg in enumerate(self.args):
3277 arg.analyse_expressions(env)
3278 arg = arg.coerce_to_pyobject(env)
3279 arg.release_temp(env)
3281 self.temp_result = env.allocate_temp_pyobject()
3282 env.release_temp(self.temp_result)
3283 env.use_utility_code(Builtin.pyexec_utility_code)
3286 gil_message = "Python exec statement"
3288 def generate_execution_code(self, code):
3290 for arg in self.args:
3291 arg.generate_evaluation_code(code)
3292 args.append( arg.py_result() )
3293 args = tuple(args + ['0', '0'][:3-len(args)])
3294 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3295 (self.temp_result,) + args))
3296 for arg in self.args:
3297 arg.generate_disposal_code(code)
3298 arg.free_temps(code)
3300 code.error_goto_if_null(self.temp_result, self.pos))
3301 code.put_gotref(self.temp_result)
3302 code.put_decref_clear(self.temp_result, py_object_type)
3304 def annotate(self, code):
3305 for arg in self.args:
3309 class DelStatNode(StatNode):
3314 child_attrs = ["args"]
3316 def analyse_declarations(self, env):
3317 for arg in self.args:
3318 arg.analyse_target_declaration(env)
3320 def analyse_expressions(self, env):
3321 for arg in self.args:
3322 arg.analyse_target_expression(env, None)
3323 if arg.type.is_pyobject:
3326 error(arg.pos, "Deletion of non-Python object")
3327 #arg.release_target_temp(env)
3329 gil_message = "Deleting Python object"
3331 def generate_execution_code(self, code):
3332 for arg in self.args:
3333 if arg.type.is_pyobject:
3334 arg.generate_deletion_code(code)
3335 # else error reported earlier
3337 def annotate(self, code):
3338 for arg in self.args:
3342 class PassStatNode(StatNode):
3347 def analyse_expressions(self, env):
3350 def generate_execution_code(self, code):
3354 class BreakStatNode(StatNode):
3358 def analyse_expressions(self, env):
3361 def generate_execution_code(self, code):
3362 if not code.break_label:
3363 error(self.pos, "break statement not inside loop")
3365 code.put_goto(code.break_label)
3368 class ContinueStatNode(StatNode):
3372 def analyse_expressions(self, env):
3375 def generate_execution_code(self, code):
3376 if code.funcstate.in_try_finally:
3377 error(self.pos, "continue statement inside try of try...finally")
3378 elif not code.continue_label:
3379 error(self.pos, "continue statement not inside loop")
3381 code.put_goto(code.continue_label)
3384 class ReturnStatNode(StatNode):
3387 # value ExprNode or None
3388 # return_type PyrexType
3389 # temps_in_use [Entry] Temps in use at time of return
3391 child_attrs = ["value"]
3393 def analyse_expressions(self, env):
3394 return_type = env.return_type
3395 self.return_type = return_type
3396 self.temps_in_use = env.temps_in_use()
3398 error(self.pos, "Return not inside a function body")
3401 self.value.analyse_types(env)
3402 if return_type.is_void or return_type.is_returncode:
3403 error(self.value.pos,
3404 "Return with value in void function")
3406 self.value = self.value.coerce_to(env.return_type, env)
3407 self.value.allocate_temps(env)
3408 self.value.release_temp(env)
3410 if (not return_type.is_void
3411 and not return_type.is_pyobject
3412 and not return_type.is_returncode):
3413 error(self.pos, "Return value required")
3414 if return_type.is_pyobject:
3417 gil_message = "Returning Python object"
3419 def generate_execution_code(self, code):
3420 code.mark_pos(self.pos)
3421 if not self.return_type:
3422 # error reported earlier
3424 if self.return_type.is_pyobject:
3425 code.put_xdecref(Naming.retval_cname,
3428 self.value.generate_evaluation_code(code)
3429 self.value.make_owned_reference(code)
3432 Naming.retval_cname,
3433 self.value.result_as(self.return_type)))
3434 self.value.generate_post_assignment_code(code)
3435 self.value.free_temps(code)
3437 if self.return_type.is_pyobject:
3438 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3439 elif self.return_type.is_returncode:
3442 Naming.retval_cname,
3443 self.return_type.default_value))
3444 # free temps the old way
3445 for entry in self.temps_in_use:
3446 code.put_var_decref_clear(entry)
3447 # free temps the new way
3448 for cname, type in code.funcstate.temps_holding_reference():
3449 code.put_decref_clear(cname, type)
3452 # code.return_label)
3453 code.put_goto(code.return_label)
3455 def annotate(self, code):
3457 self.value.annotate(code)
3460 class RaiseStatNode(StatNode):
3463 # exc_type ExprNode or None
3464 # exc_value ExprNode or None
3465 # exc_tb ExprNode or None
3467 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3469 def analyse_expressions(self, env):
3471 self.exc_type.analyse_types(env)
3472 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3473 self.exc_type.allocate_temps(env)
3475 self.exc_value.analyse_types(env)
3476 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3477 self.exc_value.allocate_temps(env)
3479 self.exc_tb.analyse_types(env)
3480 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3481 self.exc_tb.allocate_temps(env)
3483 self.exc_type.release_temp(env)
3485 self.exc_value.release_temp(env)
3487 self.exc_tb.release_temp(env)
3488 env.use_utility_code(raise_utility_code)
3489 env.use_utility_code(restore_exception_utility_code)
3492 gil_message = "Raising exception"
3494 def generate_execution_code(self, code):
3496 self.exc_type.generate_evaluation_code(code)
3497 type_code = self.exc_type.py_result()
3501 self.exc_value.generate_evaluation_code(code)
3502 value_code = self.exc_value.py_result()
3506 self.exc_tb.generate_evaluation_code(code)
3507 tb_code = self.exc_tb.py_result()
3510 if self.exc_type or self.exc_value or self.exc_tb:
3512 "__Pyx_Raise(%s, %s, %s);" % (
3519 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3521 obj.generate_disposal_code(code)
3522 obj.free_temps(code)
3524 code.error_goto(self.pos))
3526 def annotate(self, code):
3528 self.exc_type.annotate(code)
3530 self.exc_value.annotate(code)
3532 self.exc_tb.annotate(code)
3535 class ReraiseStatNode(StatNode):
3539 def analyse_expressions(self, env):
3541 env.use_utility_code(raise_utility_code)
3542 env.use_utility_code(restore_exception_utility_code)
3544 gil_message = "Raising exception"
3546 def generate_execution_code(self, code):
3547 vars = code.funcstate.exc_vars
3549 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3550 code.putln(code.error_goto(self.pos))
3552 error(self.pos, "Reraise not inside except clause")
3555 class AssertStatNode(StatNode):
3559 # value ExprNode or None
3561 child_attrs = ["cond", "value"]
3563 def analyse_expressions(self, env):
3564 self.cond = self.cond.analyse_boolean_expression(env)
3566 self.value.analyse_types(env)
3567 self.value = self.value.coerce_to_pyobject(env)
3568 self.value.allocate_temps(env)
3569 self.cond.release_temp(env)
3571 self.value.release_temp(env)
3573 #env.recycle_pending_temps() # TEMPORARY
3575 gil_message = "Raising exception"
3577 def generate_execution_code(self, code):
3578 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3579 self.cond.generate_evaluation_code(code)
3581 "if (unlikely(!%s)) {" %
3584 self.value.generate_evaluation_code(code)
3586 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3587 self.value.py_result())
3588 self.value.generate_disposal_code(code)
3589 self.value.free_temps(code)
3592 "PyErr_SetNone(PyExc_AssertionError);")
3594 code.error_goto(self.pos))
3597 self.cond.generate_disposal_code(code)
3598 self.cond.free_temps(code)
3599 code.putln("#endif")
3601 def annotate(self, code):
3602 self.cond.annotate(code)
3604 self.value.annotate(code)
3607 class IfStatNode(StatNode):
3610 # if_clauses [IfClauseNode]
3611 # else_clause StatNode or None
3613 child_attrs = ["if_clauses", "else_clause"]
3615 def analyse_control_flow(self, env):
3616 env.start_branching(self.pos)
3617 for if_clause in self.if_clauses:
3618 if_clause.analyse_control_flow(env)
3619 env.next_branch(if_clause.end_pos())
3620 if self.else_clause:
3621 self.else_clause.analyse_control_flow(env)
3622 env.finish_branching(self.end_pos())
3624 def analyse_declarations(self, env):
3625 for if_clause in self.if_clauses:
3626 if_clause.analyse_declarations(env)
3627 if self.else_clause:
3628 self.else_clause.analyse_declarations(env)
3630 def analyse_expressions(self, env):
3631 for if_clause in self.if_clauses:
3632 if_clause.analyse_expressions(env)
3633 if self.else_clause:
3634 self.else_clause.analyse_expressions(env)
3636 def generate_execution_code(self, code):
3637 code.mark_pos(self.pos)
3638 end_label = code.new_label()
3639 for if_clause in self.if_clauses:
3640 if_clause.generate_execution_code(code, end_label)
3641 if self.else_clause:
3642 code.putln("/*else*/ {")
3643 self.else_clause.generate_execution_code(code)
3645 code.put_label(end_label)
3647 def annotate(self, code):
3648 for if_clause in self.if_clauses:
3649 if_clause.annotate(code)
3650 if self.else_clause:
3651 self.else_clause.annotate(code)
3654 class IfClauseNode(Node):
3655 # if or elif clause in an if statement
3657 # condition ExprNode
3660 child_attrs = ["condition", "body"]
3662 def analyse_control_flow(self, env):
3663 self.body.analyse_control_flow(env)
3665 def analyse_declarations(self, env):
3666 self.condition.analyse_declarations(env)
3667 self.body.analyse_declarations(env)
3669 def analyse_expressions(self, env):
3671 self.condition.analyse_temp_boolean_expression(env)
3672 self.condition.release_temp(env)
3673 self.body.analyse_expressions(env)
3675 def generate_execution_code(self, code, end_label):
3676 self.condition.generate_evaluation_code(code)
3679 self.condition.result())
3680 self.condition.generate_disposal_code(code)
3681 self.condition.free_temps(code)
3682 self.body.generate_execution_code(code)
3686 code.put_goto(end_label)
3689 def annotate(self, code):
3690 self.condition.annotate(code)
3691 self.body.annotate(code)
3694 class SwitchCaseNode(StatNode):
3695 # Generated in the optimization of an if-elif-else node
3697 # conditions [ExprNode]
3700 child_attrs = ['conditions', 'body']
3702 def generate_execution_code(self, code):
3703 for cond in self.conditions:
3704 code.mark_pos(cond.pos)
3705 code.putln("case %s:" % cond.calculate_result_code())
3706 self.body.generate_execution_code(code)
3707 code.putln("break;")
3709 def annotate(self, code):
3710 for cond in self.conditions:
3712 self.body.annotate(code)
3714 class SwitchStatNode(StatNode):
3715 # Generated in the optimization of an if-elif-else node
3718 # cases [SwitchCaseNode]
3719 # else_clause StatNode or None
3721 child_attrs = ['test', 'cases', 'else_clause']
3723 def generate_execution_code(self, code):
3724 code.putln("switch (%s) {" % self.test.calculate_result_code())
3725 for case in self.cases:
3726 case.generate_execution_code(code)
3727 if self.else_clause is not None:
3728 code.putln("default:")
3729 self.else_clause.generate_execution_code(code)
3730 code.putln("break;")
3733 def annotate(self, code):
3734 self.test.annotate(code)
3735 for case in self.cases:
3737 if self.else_clause is not None:
3738 self.else_clause.annotate(code)
3740 class LoopNode(object):
3742 def analyse_control_flow(self, env):
3743 env.start_branching(self.pos)
3744 self.body.analyse_control_flow(env)
3745 env.next_branch(self.body.end_pos())
3746 if self.else_clause:
3747 self.else_clause.analyse_control_flow(env)
3748 env.finish_branching(self.end_pos())
3751 class WhileStatNode(LoopNode, StatNode):
3754 # condition ExprNode
3756 # else_clause StatNode
3758 child_attrs = ["condition", "body", "else_clause"]
3760 def analyse_declarations(self, env):
3761 self.body.analyse_declarations(env)
3762 if self.else_clause:
3763 self.else_clause.analyse_declarations(env)
3765 def analyse_expressions(self, env):
3767 self.condition.analyse_temp_boolean_expression(env)
3768 self.condition.release_temp(env)
3769 #env.recycle_pending_temps() # TEMPORARY
3770 self.body.analyse_expressions(env)
3771 if self.else_clause:
3772 self.else_clause.analyse_expressions(env)
3774 def generate_execution_code(self, code):
3775 old_loop_labels = code.new_loop_labels()
3778 self.condition.generate_evaluation_code(code)
3779 self.condition.generate_disposal_code(code)
3782 self.condition.result())
3783 self.condition.free_temps(code)
3784 self.body.generate_execution_code(code)
3785 code.put_label(code.continue_label)
3787 break_label = code.break_label
3788 code.set_loop_labels(old_loop_labels)
3789 if self.else_clause:
3790 code.putln("/*else*/ {")
3791 self.else_clause.generate_execution_code(code)
3793 code.put_label(break_label)
3795 def annotate(self, code):
3796 self.condition.annotate(code)
3797 self.body.annotate(code)
3798 if self.else_clause:
3799 self.else_clause.annotate(code)
3802 def ForStatNode(pos, **kw):
3803 if 'iterator' in kw:
3804 return ForInStatNode(pos, **kw)
3806 return ForFromStatNode(pos, **kw)
3808 class ForInStatNode(LoopNode, StatNode):
3812 # iterator IteratorNode
3814 # else_clause StatNode
3815 # item NextNode used internally
3817 child_attrs = ["target", "iterator", "body", "else_clause"]
3820 def analyse_declarations(self, env):
3821 self.target.analyse_target_declaration(env)
3822 self.body.analyse_declarations(env)
3823 if self.else_clause:
3824 self.else_clause.analyse_declarations(env)
3826 def analyse_expressions(self, env):
3828 self.target.analyse_target_types(env)
3829 self.iterator.analyse_expressions(env)
3830 self.item = ExprNodes.NextNode(self.iterator, env)
3831 self.item = self.item.coerce_to(self.target.type, env)
3832 self.item.allocate_temps(env)
3833 self.target.allocate_target_temps(env, self.item)
3834 #self.item.release_temp(env)
3835 #self.target.release_target_temp(env)
3836 self.body.analyse_expressions(env)
3837 if self.else_clause:
3838 self.else_clause.analyse_expressions(env)
3839 self.iterator.release_temp(env)
3841 def generate_execution_code(self, code):
3842 old_loop_labels = code.new_loop_labels()
3843 self.iterator.allocate_counter_temp(code)
3844 self.iterator.generate_evaluation_code(code)
3847 self.item.generate_evaluation_code(code)
3848 self.target.generate_assignment_code(self.item, code)
3849 self.body.generate_execution_code(code)
3850 code.put_label(code.continue_label)
3853 break_label = code.break_label
3854 code.set_loop_labels(old_loop_labels)
3855 if self.else_clause:
3856 code.putln("/*else*/ {")
3857 self.else_clause.generate_execution_code(code)
3859 code.put_label(break_label)
3860 self.iterator.release_counter_temp(code)
3861 self.iterator.generate_disposal_code(code)
3862 self.iterator.free_temps(code)
3864 def annotate(self, code):
3865 self.target.annotate(code)
3866 self.iterator.annotate(code)
3867 self.body.annotate(code)
3868 if self.else_clause:
3869 self.else_clause.annotate(code)
3870 self.item.annotate(code)
3873 class ForFromStatNode(LoopNode, StatNode):
3874 # for name from expr rel name rel expr
3881 # step ExprNode or None
3883 # else_clause StatNode or None
3888 # loopvar_node ExprNode (usually a NameNode or temp node)
3889 # py_loopvar_node PyTempNode or None
3890 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3892 is_py_target = False
3894 py_loopvar_node = None
3896 def analyse_declarations(self, env):
3897 self.target.analyse_target_declaration(env)
3898 self.body.analyse_declarations(env)
3899 if self.else_clause:
3900 self.else_clause.analyse_declarations(env)
3902 def analyse_expressions(self, env):
3904 self.target.analyse_target_types(env)
3905 self.bound1.analyse_types(env)
3906 self.bound2.analyse_types(env)
3907 if self.target.type.is_numeric:
3908 self.bound1 = self.bound1.coerce_to(self.target.type, env)
3909 self.bound2 = self.bound2.coerce_to(self.target.type, env)
3911 self.bound1 = self.bound1.coerce_to_integer(env)
3912 self.bound2 = self.bound2.coerce_to_integer(env)
3913 if self.step is not None:
3914 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3915 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3916 self.step.analyse_types(env)
3917 self.step = self.step.coerce_to_integer(env)
3918 if not (self.bound2.is_name or self.bound2.is_literal):
3919 self.bound2 = self.bound2.coerce_to_temp(env)
3920 target_type = self.target.type
3921 if not (target_type.is_pyobject or target_type.is_numeric):
3922 error(self.target.pos,
3923 "Integer for-loop variable must be of type int or Python object")
3924 #if not (target_type.is_pyobject
3925 # or target_type.assignable_from(PyrexTypes.c_int_type)):
3926 # error(self.target.pos,
3927 # "Cannot assign integer to variable of type '%s'" % target_type)
3928 if target_type.is_numeric:
3929 self.is_py_target = 0
3930 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3931 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3932 self.loopvar_node = self.target
3933 self.py_loopvar_node = None
3935 self.is_py_target = 1
3936 c_loopvar_node = ExprNodes.TempNode(self.pos,
3937 PyrexTypes.c_long_type, env)
3938 c_loopvar_node.allocate_temps(env)
3939 self.loopvar_node = c_loopvar_node
3940 self.py_loopvar_node = \
3941 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3942 self.bound1.allocate_temps(env)
3943 self.bound2.allocate_temps(env)
3944 if self.step is not None:
3945 self.step.allocate_temps(env)
3946 if self.is_py_target:
3947 self.py_loopvar_node.allocate_temps(env)
3948 self.target.allocate_target_temps(env, self.py_loopvar_node)
3949 #self.target.release_target_temp(env)
3950 #self.py_loopvar_node.release_temp(env)
3951 self.body.analyse_expressions(env)
3952 if self.is_py_target:
3953 c_loopvar_node.release_temp(env)
3954 if self.else_clause:
3955 self.else_clause.analyse_expressions(env)
3956 self.bound1.release_temp(env)
3957 self.bound2.release_temp(env)
3958 if self.step is not None:
3959 self.step.release_temp(env)
3961 def generate_execution_code(self, code):
3962 old_loop_labels = code.new_loop_labels()
3963 from_range = getattr(self, "from_range", False)
3964 self.bound1.generate_evaluation_code(code)
3965 self.bound2.generate_evaluation_code(code)
3966 offset, incop = self.relation_table[self.relation1]
3971 if self.step is not None:
3972 self.step.generate_evaluation_code(code)
3973 step = self.step.result()
3974 incop = "%s=%s" % (incop[0], step)
3975 decop = "%s=%s" % (decop[0], step)
3976 loopvar_name = self.loopvar_node.result()
3978 range_bound = code.funcstate.allocate_temp(self.bound2.type, manage_ref=False)
3979 code.putln("%s = %s;" % (range_bound, self.bound2.result()))
3980 # Skip the loop entirely (and avoid assigning to the loopvar) if
3981 # the loop is empty:
3982 code.putln("if (%s%s %s %s) {" % (
3983 self.bound1.result(), offset, self.relation2, range_bound
3986 range_bound = self.bound2.result()
3988 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3990 self.bound1.result(), offset,
3991 loopvar_name, self.relation2, range_bound,
3992 loopvar_name, incop))
3993 if self.py_loopvar_node:
3994 self.py_loopvar_node.generate_evaluation_code(code)
3995 self.target.generate_assignment_code(self.py_loopvar_node, code)
3996 self.body.generate_execution_code(code)
3997 code.put_label(code.continue_label)
3999 # Undo last increment to maintain Python semantics:
4000 code.putln("} %s%s;" % (loopvar_name, decop))
4001 # End the outer if statement:
4002 code.putln("} /* end if */")
4003 code.funcstate.release_temp(range_bound)
4006 break_label = code.break_label
4007 code.set_loop_labels(old_loop_labels)
4008 if self.else_clause:
4009 code.putln("/*else*/ {")
4010 self.else_clause.generate_execution_code(code)
4012 code.put_label(break_label)
4013 self.bound1.generate_disposal_code(code)
4014 self.bound1.free_temps(code)
4015 self.bound2.generate_disposal_code(code)
4016 self.bound2.free_temps(code)
4017 if self.step is not None:
4018 self.step.generate_disposal_code(code)
4019 self.step.free_temps(code)
4022 # {relop : (initial offset, increment op)}
4029 def annotate(self, code):
4030 self.target.annotate(code)
4031 self.bound1.annotate(code)
4032 self.bound2.annotate(code)
4034 self.bound2.annotate(code)
4035 self.body.annotate(code)
4036 if self.else_clause:
4037 self.else_clause.annotate(code)
4040 class WithStatNode(StatNode):
4042 Represents a Python with statement.
4044 This is only used at parse tree level; and is not present in
4045 analysis or generation phases.
4047 # manager The with statement manager object
4048 # target Node (lhs expression)
4050 child_attrs = ["manager", "target", "body"]
4052 class TryExceptStatNode(StatNode):
4053 # try .. except statement
4056 # except_clauses [ExceptClauseNode]
4057 # else_clause StatNode or None
4058 # cleanup_list [Entry] old style temps to clean up on error
4060 child_attrs = ["body", "except_clauses", "else_clause"]
4062 def analyse_control_flow(self, env):
4063 env.start_branching(self.pos)
4064 self.body.analyse_control_flow(env)
4065 successful_try = env.control_flow # grab this for later
4066 env.next_branch(self.body.end_pos())
4067 env.finish_branching(self.body.end_pos())
4069 env.start_branching(self.except_clauses[0].pos)
4070 for except_clause in self.except_clauses:
4071 except_clause.analyse_control_flow(env)
4072 env.next_branch(except_clause.end_pos())
4074 # the else cause it executed only when the try clause finishes
4075 env.control_flow.incoming = successful_try
4076 if self.else_clause:
4077 self.else_clause.analyse_control_flow(env)
4078 env.finish_branching(self.end_pos())
4080 def analyse_declarations(self, env):
4081 self.body.analyse_declarations(env)
4082 for except_clause in self.except_clauses:
4083 except_clause.analyse_declarations(env)
4084 if self.else_clause:
4085 self.else_clause.analyse_declarations(env)
4087 env.use_utility_code(reset_exception_utility_code)
4089 def analyse_expressions(self, env):
4090 self.body.analyse_expressions(env)
4091 self.cleanup_list = env.free_temp_entries[:]
4092 default_clause_seen = 0
4093 for except_clause in self.except_clauses:
4094 except_clause.analyse_expressions(env)
4095 if default_clause_seen:
4096 error(except_clause.pos, "default 'except:' must be last")
4097 if not except_clause.pattern:
4098 default_clause_seen = 1
4099 self.has_default_clause = default_clause_seen
4100 if self.else_clause:
4101 self.else_clause.analyse_expressions(env)
4104 gil_message = "Try-except statement"
4106 def generate_execution_code(self, code):
4107 old_return_label = code.return_label
4108 old_break_label = code.break_label
4109 old_continue_label = code.continue_label
4110 old_error_label = code.new_error_label()
4111 our_error_label = code.error_label
4112 except_end_label = code.new_label('exception_handled')
4113 except_error_label = code.new_label('except_error')
4114 except_return_label = code.new_label('except_return')
4115 try_return_label = code.new_label('try_return')
4116 try_break_label = code.new_label('try_break')
4117 try_continue_label = code.new_label('try_continue')
4118 try_end_label = code.new_label('try_end')
4121 code.putln("PyObject %s;" %
4122 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4123 code.putln("__Pyx_ExceptionSave(%s);" %
4124 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4125 for var in Naming.exc_save_vars:
4126 code.put_xgotref(var)
4129 code.return_label = try_return_label
4130 code.break_label = try_break_label
4131 code.continue_label = try_continue_label
4132 self.body.generate_execution_code(code)
4135 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4136 code.error_label = except_error_label
4137 code.return_label = except_return_label
4138 if self.else_clause:
4141 self.else_clause.generate_execution_code(code)
4144 for var in Naming.exc_save_vars:
4145 code.put_xdecref_clear(var, py_object_type)
4146 code.put_goto(try_end_label)
4147 if code.label_used(try_return_label):
4148 code.put_label(try_return_label)
4149 for var in Naming.exc_save_vars:
4150 code.put_xdecref_clear(var, py_object_type)
4151 code.put_goto(old_return_label)
4152 code.put_label(our_error_label)
4153 code.put_var_xdecrefs_clear(self.cleanup_list)
4154 for temp_name, type in temps_to_clean_up:
4155 code.put_xdecref_clear(temp_name, type)
4156 for except_clause in self.except_clauses:
4157 except_clause.generate_handling_code(code, except_end_label)
4159 error_label_used = code.label_used(except_error_label)
4160 if error_label_used or not self.has_default_clause:
4161 if error_label_used:
4162 code.put_label(except_error_label)
4163 for var in Naming.exc_save_vars:
4164 code.put_xdecref(var, py_object_type)
4165 code.put_goto(old_error_label)
4167 if code.label_used(try_break_label):
4168 code.put_label(try_break_label)
4169 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4170 code.putln("__Pyx_ExceptionReset(%s);" %
4171 ', '.join(Naming.exc_save_vars))
4172 code.put_goto(old_break_label)
4174 if code.label_used(try_continue_label):
4175 code.put_label(try_continue_label)
4176 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4177 code.putln("__Pyx_ExceptionReset(%s);" %
4178 ', '.join(Naming.exc_save_vars))
4179 code.put_goto(old_continue_label)
4181 if code.label_used(except_return_label):
4182 code.put_label(except_return_label)
4183 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4184 code.putln("__Pyx_ExceptionReset(%s);" %
4185 ', '.join(Naming.exc_save_vars))
4186 code.put_goto(old_return_label)
4188 if code.label_used(except_end_label):
4189 code.put_label(except_end_label)
4190 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4191 code.putln("__Pyx_ExceptionReset(%s);" %
4192 ', '.join(Naming.exc_save_vars))
4193 code.put_label(try_end_label)
4196 code.return_label = old_return_label
4197 code.break_label = old_break_label
4198 code.continue_label = old_continue_label
4199 code.error_label = old_error_label
4201 def annotate(self, code):
4202 self.body.annotate(code)
4203 for except_node in self.except_clauses:
4204 except_node.annotate(code)
4205 if self.else_clause:
4206 self.else_clause.annotate(code)
4209 class ExceptClauseNode(Node):
4210 # Part of try ... except statement.
4213 # target ExprNode or None
4215 # excinfo_target NameNode or None optional target for exception info
4216 # match_flag string result of exception match
4217 # exc_value ExcValueNode used internally
4218 # function_name string qualified name of enclosing function
4219 # exc_vars (string * 3) local exception variables
4221 # excinfo_target is never set by the parser, but can be set by a transform
4222 # in order to extract more extensive information about the exception as a
4223 # sys.exc_info()-style tuple into a target variable
4225 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4228 excinfo_target = None
4230 def analyse_declarations(self, env):
4232 self.target.analyse_target_declaration(env)
4233 if self.excinfo_target is not None:
4234 self.excinfo_target.analyse_target_declaration(env)
4235 self.body.analyse_declarations(env)
4237 def analyse_expressions(self, env):
4239 genv = env.global_scope()
4240 self.function_name = env.qualified_name
4242 self.pattern.analyse_expressions(env)
4243 self.pattern = self.pattern.coerce_to_pyobject(env)
4244 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4245 self.pattern.release_temp(env)
4246 env.release_temp(self.match_flag)
4248 if self.target or self.excinfo_target:
4249 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4251 self.exc_vars = None
4254 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4255 self.exc_value.allocate_temps(env)
4256 self.target.analyse_target_expression(env, self.exc_value)
4257 if self.excinfo_target is not None:
4259 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4260 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4261 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4262 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4264 self.excinfo_tuple.analyse_expressions(env)
4265 self.excinfo_tuple.allocate_temps(env)
4266 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4268 self.body.analyse_expressions(env)
4271 for var in self.exc_vars:
4272 env.release_temp(var)
4274 def generate_handling_code(self, code, end_label):
4275 code.mark_pos(self.pos)
4277 self.pattern.generate_evaluation_code(code)
4279 "%s = PyErr_ExceptionMatches(%s);" % (
4281 self.pattern.py_result()))
4282 self.pattern.generate_disposal_code(code)
4283 self.pattern.free_temps(code)
4288 code.putln("/*except:*/ {")
4291 exc_vars = self.exc_vars
4292 elif not getattr(self.body, 'stats', True):
4293 # most simple case: no exception variable, empty body (pass)
4294 # => reset the exception state, done
4295 code.putln("PyErr_Restore(0,0,0);")
4296 code.put_goto(end_label)
4300 # during type analysis, we didn't know if we need the
4301 # exception value, but apparently, we do
4302 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4306 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4307 # We always have to fetch the exception value even if
4308 # there is no target, because this also normalises the
4309 # exception and stores it in the thread state.
4310 code.globalstate.use_utility_code(get_exception_utility_code)
4311 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4312 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4313 code.error_goto(self.pos)))
4317 self.exc_value.generate_evaluation_code(code)
4318 self.target.generate_assignment_code(self.exc_value, code)
4319 if self.excinfo_target is not None:
4320 self.excinfo_tuple.generate_evaluation_code(code)
4321 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4324 old_break_label, old_continue_label = code.break_label, code.continue_label
4325 code.break_label = code.new_label('except_break')
4326 code.continue_label = code.new_label('except_continue')
4328 old_exc_vars = code.funcstate.exc_vars
4329 code.funcstate.exc_vars = exc_vars
4330 self.body.generate_execution_code(code)
4331 code.funcstate.exc_vars = old_exc_vars
4332 for var in exc_vars:
4333 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4334 code.put_goto(end_label)
4336 if code.label_used(code.break_label):
4337 code.put_label(code.break_label)
4338 for var in exc_vars:
4339 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4340 code.put_goto(old_break_label)
4341 code.break_label = old_break_label
4343 if code.label_used(code.continue_label):
4344 code.put_label(code.continue_label)
4345 for var in exc_vars:
4346 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4347 code.put_goto(old_continue_label)
4348 code.continue_label = old_continue_label
4350 if not self.exc_vars:
4351 # clean up locally allocated temps
4352 for temp in exc_vars:
4353 code.funcstate.release_temp(temp)
4358 def annotate(self, code):
4360 self.pattern.annotate(code)
4362 self.target.annotate(code)
4363 self.body.annotate(code)
4366 class TryFinallyStatNode(StatNode):
4367 # try ... finally statement
4370 # finally_clause StatNode
4372 # cleanup_list [Entry] old_style temps to clean up on error
4374 # The plan is that we funnel all continue, break
4375 # return and error gotos into the beginning of the
4376 # finally block, setting a variable to remember which
4377 # one we're doing. At the end of the finally block, we
4378 # switch on the variable to figure out where to go.
4379 # In addition, if we're doing an error, we save the
4380 # exception on entry to the finally block and restore
4383 child_attrs = ["body", "finally_clause"]
4385 preserve_exception = 1
4387 disallow_continue_in_try_finally = 0
4388 # There doesn't seem to be any point in disallowing
4389 # continue in the try block, since we have no problem
4392 def create_analysed(pos, env, body, finally_clause):
4393 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4394 node.cleanup_list = []
4396 create_analysed = staticmethod(create_analysed)
4398 def analyse_control_flow(self, env):
4399 env.start_branching(self.pos)
4400 self.body.analyse_control_flow(env)
4401 env.next_branch(self.body.end_pos())
4402 env.finish_branching(self.body.end_pos())
4403 self.finally_clause.analyse_control_flow(env)
4405 def analyse_declarations(self, env):
4406 self.body.analyse_declarations(env)
4407 self.finally_clause.analyse_declarations(env)
4409 def analyse_expressions(self, env):
4410 self.body.analyse_expressions(env)
4411 self.cleanup_list = env.free_temp_entries[:]
4412 self.finally_clause.analyse_expressions(env)
4415 gil_message = "Try-finally statement"
4417 def generate_execution_code(self, code):
4418 old_error_label = code.error_label
4419 old_labels = code.all_new_labels()
4420 new_labels = code.get_all_labels()
4421 new_error_label = code.error_label
4422 catch_label = code.new_label()
4425 if self.disallow_continue_in_try_finally:
4426 was_in_try_finally = code.funcstate.in_try_finally
4427 code.funcstate.in_try_finally = 1
4428 self.body.generate_execution_code(code)
4429 if self.disallow_continue_in_try_finally:
4430 code.funcstate.in_try_finally = was_in_try_finally
4433 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4437 error_label_used = 0
4438 for i, new_label in enumerate(new_labels):
4439 if new_label in code.labels_used:
4440 cases_used.append(i)
4441 if new_label == new_error_label:
4442 error_label_used = 1
4443 error_label_case = i
4447 if error_label_used and self.preserve_exception:
4449 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4451 "int %s;" % Naming.exc_lineno_name)
4452 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4453 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4454 code.putln(exc_var_init_zero)
4456 exc_var_init_zero = None
4457 code.use_label(catch_label)
4459 "__pyx_why = 0; goto %s;" % catch_label)
4460 for i in cases_used:
4461 new_label = new_labels[i]
4462 #if new_label and new_label != "<try>":
4463 if new_label == new_error_label and self.preserve_exception:
4464 self.put_error_catcher(code,
4465 new_error_label, i+1, catch_label, temps_to_clean_up)
4467 code.put('%s: ' % new_label)
4468 if exc_var_init_zero:
4469 code.putln(exc_var_init_zero)
4470 code.putln("__pyx_why = %s; goto %s;" % (
4473 code.put_label(catch_label)
4474 code.set_all_labels(old_labels)
4475 if error_label_used:
4476 code.new_error_label()
4477 finally_error_label = code.error_label
4478 self.finally_clause.generate_execution_code(code)
4479 if error_label_used:
4480 if finally_error_label in code.labels_used and self.preserve_exception:
4481 over_label = code.new_label()
4482 code.put_goto(over_label);
4483 code.put_label(finally_error_label)
4484 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4485 for var in Naming.exc_vars:
4486 code.putln("Py_XDECREF(%s);" % var)
4488 code.put_goto(old_error_label)
4489 code.put_label(over_label)
4490 code.error_label = old_error_label
4493 "switch (__pyx_why) {")
4494 for i in cases_used:
4495 old_label = old_labels[i]
4496 if old_label == old_error_label and self.preserve_exception:
4497 self.put_error_uncatcher(code, i+1, old_error_label)
4499 code.use_label(old_label)
4501 "case %s: goto %s;" % (
4509 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4510 code.globalstate.use_utility_code(restore_exception_utility_code)
4517 code.put_var_xdecrefs_clear(self.cleanup_list)
4518 for temp_name, type in temps_to_clean_up:
4519 code.put_xdecref_clear(temp_name, type)
4521 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4525 Naming.exc_lineno_name, Naming.lineno_cname))
4529 code.put_goto(catch_label)
4533 def put_error_uncatcher(self, code, i, error_label):
4534 code.globalstate.use_utility_code(restore_exception_utility_code)
4539 "__Pyx_ErrRestore(%s, %s, %s);" %
4543 Naming.lineno_cname, Naming.exc_lineno_name))
4544 for var in Naming.exc_vars:
4548 code.put_goto(error_label)
4552 def annotate(self, code):
4553 self.body.annotate(code)
4554 self.finally_clause.annotate(code)
4557 class GILStatNode(TryFinallyStatNode):
4558 # 'with gil' or 'with nogil' statement
4560 # state string 'gil' or 'nogil'
4564 preserve_exception = 0
4566 def __init__(self, pos, state, body):
4568 TryFinallyStatNode.__init__(self, pos,
4570 finally_clause = GILExitNode(pos, state = state))
4572 def analyse_expressions(self, env):
4573 env.use_utility_code(force_init_threads_utility_code)
4574 was_nogil = env.nogil
4576 TryFinallyStatNode.analyse_expressions(self, env)
4577 env.nogil = was_nogil
4579 def gil_check(self, env):
4582 def generate_execution_code(self, code):
4583 code.mark_pos(self.pos)
4584 if self.state == 'gil':
4585 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4587 code.putln("{ PyThreadState *_save;")
4588 code.putln("Py_UNBLOCK_THREADS")
4589 TryFinallyStatNode.generate_execution_code(self, code)
4593 class GILExitNode(StatNode):
4594 # Used as the 'finally' block in a GILStatNode
4596 # state string 'gil' or 'nogil'
4600 def analyse_expressions(self, env):
4603 def generate_execution_code(self, code):
4604 if self.state == 'gil':
4605 code.putln("PyGILState_Release();")
4607 code.putln("Py_BLOCK_THREADS")
4610 class CImportStatNode(StatNode):
4613 # module_name string Qualified name of module being imported
4614 # as_name string or None Name specified in "as" clause, if any
4618 def analyse_declarations(self, env):
4619 if not env.is_module_scope:
4620 error(self.pos, "cimport only allowed at module level")
4622 module_scope = env.find_module(self.module_name, self.pos)
4623 if "." in self.module_name:
4624 names = [EncodedString(name) for name in self.module_name.split(".")]
4626 top_module_scope = env.context.find_submodule(top_name)
4627 module_scope = top_module_scope
4628 for name in names[1:]:
4629 submodule_scope = module_scope.find_submodule(name)
4630 module_scope.declare_module(name, submodule_scope, self.pos)
4631 module_scope = submodule_scope
4633 env.declare_module(self.as_name, module_scope, self.pos)
4635 env.declare_module(top_name, top_module_scope, self.pos)
4637 name = self.as_name or self.module_name
4638 env.declare_module(name, module_scope, self.pos)
4640 def analyse_expressions(self, env):
4643 def generate_execution_code(self, code):
4647 class FromCImportStatNode(StatNode):
4648 # from ... cimport statement
4650 # module_name string Qualified name of module
4651 # imported_names [(pos, name, as_name, kind)] Names to be imported
4655 def analyse_declarations(self, env):
4656 if not env.is_module_scope:
4657 error(self.pos, "cimport only allowed at module level")
4659 module_scope = env.find_module(self.module_name, self.pos)
4660 env.add_imported_module(module_scope)
4661 for pos, name, as_name, kind in self.imported_names:
4663 for local_name, entry in module_scope.entries.items():
4664 env.add_imported_entry(local_name, entry, pos)
4666 entry = module_scope.lookup(name)
4668 if kind and not self.declaration_matches(entry, kind):
4669 entry.redeclared(pos)
4671 if kind == 'struct' or kind == 'union':
4672 entry = module_scope.declare_struct_or_union(name,
4673 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4674 elif kind == 'class':
4675 entry = module_scope.declare_c_class(name, pos = pos,
4676 module_name = self.module_name)
4678 error(pos, "Name '%s' not declared in module '%s'"
4679 % (name, self.module_name))
4682 local_name = as_name or name
4683 env.add_imported_entry(local_name, entry, pos)
4685 def declaration_matches(self, entry, kind):
4686 if not entry.is_type:
4690 if not type.is_extension_type:
4693 if not type.is_struct_or_union:
4695 if kind != type.kind:
4699 def analyse_expressions(self, env):
4702 def generate_execution_code(self, code):
4706 class FromImportStatNode(StatNode):
4707 # from ... import statement
4710 # items [(string, NameNode)]
4711 # interned_items [(string, NameNode, ExprNode)]
4712 # item PyTempNode used internally
4713 # import_star boolean used internally
4715 child_attrs = ["module"]
4718 def analyse_declarations(self, env):
4719 for name, target in self.items:
4721 if not env.is_module_scope:
4722 error(self.pos, "import * only allowed at module level")
4724 env.has_import_star = 1
4725 self.import_star = 1
4727 target.analyse_target_declaration(env)
4729 def analyse_expressions(self, env):
4731 self.module.analyse_expressions(env)
4732 self.item = ExprNodes.PyTempNode(self.pos, env)
4733 self.item.allocate_temp(env)
4734 self.interned_items = []
4735 for name, target in self.items:
4737 for _, entry in env.entries.items():
4738 if not entry.is_type and entry.type.is_extension_type:
4739 env.use_utility_code(ExprNodes.type_test_utility_code)
4742 entry = env.lookup(target.name)
4743 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4744 continue # already cimported
4745 target.analyse_target_expression(env, None)
4746 if target.type is py_object_type:
4749 coerced_item = self.item.coerce_to(target.type, env)
4750 self.interned_items.append(
4751 (env.intern_identifier(name), target, coerced_item))
4752 #target.release_target_temp(env) # was release_temp ?!?
4753 self.module.release_temp(env)
4754 self.item.release_temp(env)
4756 def generate_execution_code(self, code):
4757 self.module.generate_evaluation_code(code)
4758 if self.import_star:
4760 'if (%s(%s) < 0) %s;' % (
4762 self.module.py_result(),
4763 code.error_goto(self.pos)))
4764 for cname, target, coerced_item in self.interned_items:
4766 '%s = PyObject_GetAttr(%s, %s); %s' % (
4768 self.module.py_result(),
4770 code.error_goto_if_null(self.item.result(), self.pos)))
4771 code.put_gotref(self.item.py_result())
4772 if coerced_item is None:
4773 target.generate_assignment_code(self.item, code)
4775 coerced_item.allocate_temp_result(code)
4776 coerced_item.generate_result_code(code)
4777 target.generate_assignment_code(coerced_item, code)
4778 if self.item.result() != coerced_item.result():
4779 code.put_decref_clear(self.item.result(), self.item.type)
4780 self.module.generate_disposal_code(code)
4781 self.module.free_temps(code)
4785 #------------------------------------------------------------------------------------
4787 # Runtime support code
4789 #------------------------------------------------------------------------------------
4791 utility_function_predeclarations = \
4794 #define INLINE __inline__
4796 #define INLINE __inline
4801 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4805 static int %(skip_dispatch_cname)s = 0;
4807 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4809 if Options.gcc_branch_hints:
4810 branch_prediction_macros = \
4813 /* Test for GCC > 2.95 */
4814 #if __GNUC__ > 2 || \
4815 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4816 #define likely(x) __builtin_expect(!!(x), 1)
4817 #define unlikely(x) __builtin_expect(!!(x), 0)
4818 #else /* __GNUC__ > 2 ... */
4819 #define likely(x) (x)
4820 #define unlikely(x) (x)
4821 #endif /* __GNUC__ > 2 ... */
4822 #else /* __GNUC__ */
4823 #define likely(x) (x)
4824 #define unlikely(x) (x)
4825 #endif /* __GNUC__ */
4828 branch_prediction_macros = \
4830 #define likely(x) (x)
4831 #define unlikely(x) (x)
4834 #get_name_predeclaration = \
4835 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4837 #get_name_interned_predeclaration = \
4838 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4840 #------------------------------------------------------------------------------------
4842 printing_utility_code = UtilityCode(
4844 static int __Pyx_Print(PyObject *, int); /*proto*/
4845 #if PY_MAJOR_VERSION >= 3
4846 static PyObject* %s = 0;
4847 static PyObject* %s = 0;
4849 """ % (Naming.print_function, Naming.print_function_kwargs),
4851 #if PY_MAJOR_VERSION < 3
4852 static PyObject *__Pyx_GetStdout(void) {
4853 PyObject *f = PySys_GetObject((char *)"stdout");
4855 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4860 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4865 if (!(f = __Pyx_GetStdout()))
4867 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4868 if (PyFile_SoftSpace(f, 1)) {
4869 if (PyFile_WriteString(" ", f) < 0)
4872 v = PyTuple_GET_ITEM(arg_tuple, i);
4873 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4875 if (PyString_Check(v)) {
4876 char *s = PyString_AsString(v);
4877 Py_ssize_t len = PyString_Size(v);
4879 isspace(Py_CHARMASK(s[len-1])) &&
4881 PyFile_SoftSpace(f, 0);
4885 if (PyFile_WriteString("\n", f) < 0)
4887 PyFile_SoftSpace(f, 0);
4892 #else /* Python 3 has a print function */
4894 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4895 PyObject* kwargs = 0;
4896 PyObject* result = 0;
4897 PyObject* end_string;
4898 if (!%(PRINT_FUNCTION)s) {
4899 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4900 if (!%(PRINT_FUNCTION)s)
4904 if (!%(PRINT_KWARGS)s) {
4905 %(PRINT_KWARGS)s = PyDict_New();
4906 if (!%(PRINT_KWARGS)s)
4908 end_string = PyUnicode_FromStringAndSize(" ", 1);
4911 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4912 Py_DECREF(end_string);
4915 Py_DECREF(end_string);
4917 kwargs = %(PRINT_KWARGS)s;
4919 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4927 """ % {'BUILTINS' : Naming.builtins_cname,
4928 'PRINT_FUNCTION' : Naming.print_function,
4929 'PRINT_KWARGS' : Naming.print_function_kwargs}
4933 printing_one_utility_code = UtilityCode(
4935 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4938 #if PY_MAJOR_VERSION < 3
4940 static int __Pyx_PrintOne(PyObject *o) {
4942 if (!(f = __Pyx_GetStdout()))
4944 if (PyFile_SoftSpace(f, 0)) {
4945 if (PyFile_WriteString(" ", f) < 0)
4948 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4950 if (PyFile_WriteString("\n", f) < 0)
4953 /* the line below is just to avoid compiler
4954 * compiler warnings about unused functions */
4955 return __Pyx_Print(NULL, 0);
4958 #else /* Python 3 has a print function */
4960 static int __Pyx_PrintOne(PyObject *o) {
4962 PyObject* arg_tuple = PyTuple_New(1);
4963 if (unlikely(!arg_tuple))
4966 PyTuple_SET_ITEM(arg_tuple, 0, o);
4967 res = __Pyx_Print(arg_tuple, 1);
4968 Py_DECREF(arg_tuple);
4977 #------------------------------------------------------------------------------------
4979 # The following function is based on do_raise() from ceval.c.
4981 raise_utility_code = UtilityCode(
4983 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4986 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4990 /* First, check the traceback argument, replacing None with NULL. */
4991 if (tb == Py_None) {
4995 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4996 PyErr_SetString(PyExc_TypeError,
4997 "raise: arg 3 must be a traceback or None");
5000 /* Next, replace a missing value with None */
5001 if (value == NULL) {
5005 #if PY_VERSION_HEX < 0x02050000
5006 if (!PyClass_Check(type))
5008 if (!PyType_Check(type))
5011 /* Raising an instance. The value should be a dummy. */
5012 if (value != Py_None) {
5013 PyErr_SetString(PyExc_TypeError,
5014 "instance exception may not have a separate value");
5017 /* Normalize to raise <class>, <instance> */
5020 #if PY_VERSION_HEX < 0x02050000
5021 if (PyInstance_Check(type)) {
5022 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5027 PyErr_SetString(PyExc_TypeError,
5028 "raise: exception must be an old-style class or instance");
5032 type = (PyObject*) Py_TYPE(type);
5034 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5035 PyErr_SetString(PyExc_TypeError,
5036 "raise: exception class must be a subclass of BaseException");
5041 __Pyx_ErrRestore(type, value, tb);
5051 #------------------------------------------------------------------------------------
5053 reraise_utility_code = UtilityCode(
5055 static void __Pyx_ReRaise(void); /*proto*/
5058 static void __Pyx_ReRaise(void) {
5059 PyThreadState *tstate = PyThreadState_GET();
5060 PyObject* tmp_type = tstate->curexc_type;
5061 PyObject* tmp_value = tstate->curexc_value;
5062 PyObject* tmp_tb = tstate->curexc_traceback;
5063 tstate->curexc_type = tstate->exc_type;
5064 tstate->curexc_value = tstate->exc_value;
5065 tstate->curexc_traceback = tstate->exc_traceback;
5066 tstate->exc_type = 0;
5067 tstate->exc_value = 0;
5068 tstate->exc_traceback = 0;
5069 Py_XDECREF(tmp_type);
5070 Py_XDECREF(tmp_value);
5075 #------------------------------------------------------------------------------------
5077 arg_type_test_utility_code = UtilityCode(
5079 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5080 const char *name, int exact); /*proto*/
5083 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5084 const char *name, int exact)
5087 PyErr_Format(PyExc_SystemError, "Missing type object");
5090 if (none_allowed && obj == Py_None) return 1;
5092 if (Py_TYPE(obj) == type) return 1;
5095 if (PyObject_TypeCheck(obj, type)) return 1;
5097 PyErr_Format(PyExc_TypeError,
5098 "Argument '%s' has incorrect type (expected %s, got %s)",
5099 name, type->tp_name, Py_TYPE(obj)->tp_name);
5104 #------------------------------------------------------------------------------------
5106 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5107 # many or too few positional arguments were found. This handles
5108 # Py_ssize_t formatting correctly.
5110 raise_argtuple_invalid_utility_code = UtilityCode(
5112 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5113 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5116 static void __Pyx_RaiseArgtupleInvalid(
5117 const char* func_name,
5121 Py_ssize_t num_found)
5123 Py_ssize_t num_expected;
5124 const char *number, *more_or_less;
5126 if (num_found < num_min) {
5127 num_expected = num_min;
5128 more_or_less = "at least";
5130 num_expected = num_max;
5131 more_or_less = "at most";
5134 more_or_less = "exactly";
5136 number = (num_expected == 1) ? "" : "s";
5137 PyErr_Format(PyExc_TypeError,
5138 #if PY_VERSION_HEX < 0x02050000
5139 "%s() takes %s %d positional argument%s (%d given)",
5141 "%s() takes %s %zd positional argument%s (%zd given)",
5143 func_name, more_or_less, num_expected, number, num_found);
5147 raise_keyword_required_utility_code = UtilityCode(
5149 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5152 static INLINE void __Pyx_RaiseKeywordRequired(
5153 const char* func_name,
5156 PyErr_Format(PyExc_TypeError,
5157 #if PY_MAJOR_VERSION >= 3
5158 "%s() needs keyword-only argument %U", func_name, kw_name);
5160 "%s() needs keyword-only argument %s", func_name,
5161 PyString_AS_STRING(kw_name));
5166 raise_double_keywords_utility_code = UtilityCode(
5168 static void __Pyx_RaiseDoubleKeywordsError(
5169 const char* func_name, PyObject* kw_name); /*proto*/
5172 static void __Pyx_RaiseDoubleKeywordsError(
5173 const char* func_name,
5176 PyErr_Format(PyExc_TypeError,
5177 #if PY_MAJOR_VERSION >= 3
5178 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5180 "%s() got multiple values for keyword argument '%s'", func_name,
5181 PyString_AS_STRING(kw_name));
5186 #------------------------------------------------------------------------------------
5188 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5189 # were passed to a function, or if any keywords were passed to a
5190 # function that does not accept them.
5192 keyword_string_check_utility_code = UtilityCode(
5194 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5195 const char* function_name, int kw_allowed); /*proto*/
5198 static INLINE int __Pyx_CheckKeywordStrings(
5200 const char* function_name,
5205 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5206 #if PY_MAJOR_VERSION < 3
5207 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5209 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5211 goto invalid_keyword_type;
5213 if ((!kw_allowed) && unlikely(key))
5214 goto invalid_keyword;
5216 invalid_keyword_type:
5217 PyErr_Format(PyExc_TypeError,
5218 "%s() keywords must be strings", function_name);
5221 PyErr_Format(PyExc_TypeError,
5222 #if PY_MAJOR_VERSION < 3
5223 "%s() got an unexpected keyword argument '%s'",
5224 function_name, PyString_AsString(key));
5226 "%s() got an unexpected keyword argument '%U'",
5227 function_name, key);
5233 #------------------------------------------------------------------------------------
5235 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5236 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5237 # keywords will raise an invalid keyword error.
5239 # Three kinds of errors are checked: 1) non-string keywords, 2)
5240 # unexpected keywords and 3) overlap with positional arguments.
5242 # If num_posargs is greater 0, it denotes the number of positional
5243 # arguments that were passed and that must therefore not appear
5244 # amongst the keywords as well.
5246 # This method does not check for required keyword arguments.
5249 parse_keywords_utility_code = UtilityCode(
5251 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5252 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5253 const char* function_name); /*proto*/
5256 static int __Pyx_ParseOptionalKeywords(
5258 PyObject **argnames[],
5261 Py_ssize_t num_pos_args,
5262 const char* function_name)
5264 PyObject *key = 0, *value = 0;
5267 PyObject*** first_kw_arg = argnames + num_pos_args;
5269 while (PyDict_Next(kwds, &pos, &key, &value)) {
5270 name = first_kw_arg;
5271 while (*name && (**name != key)) name++;
5273 values[name-argnames] = value;
5275 #if PY_MAJOR_VERSION < 3
5276 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5278 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5280 goto invalid_keyword_type;
5282 for (name = first_kw_arg; *name; name++) {
5283 #if PY_MAJOR_VERSION >= 3
5284 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5285 PyUnicode_Compare(**name, key) == 0) break;
5287 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5288 _PyString_Eq(**name, key)) break;
5292 values[name-argnames] = value;
5294 /* unexpected keyword found */
5295 for (name=argnames; name != first_kw_arg; name++) {
5296 if (**name == key) goto arg_passed_twice;
5297 #if PY_MAJOR_VERSION >= 3
5298 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5299 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5301 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5302 _PyString_Eq(**name, key)) goto arg_passed_twice;
5306 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5308 goto invalid_keyword;
5316 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5318 invalid_keyword_type:
5319 PyErr_Format(PyExc_TypeError,
5320 "%s() keywords must be strings", function_name);
5323 PyErr_Format(PyExc_TypeError,
5324 #if PY_MAJOR_VERSION < 3
5325 "%s() got an unexpected keyword argument '%s'",
5326 function_name, PyString_AsString(key));
5328 "%s() got an unexpected keyword argument '%U'",
5329 function_name, key);
5336 #------------------------------------------------------------------------------------
5338 unraisable_exception_utility_code = UtilityCode(
5340 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5343 static void __Pyx_WriteUnraisable(const char *name) {
5344 PyObject *old_exc, *old_val, *old_tb;
5346 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5347 #if PY_MAJOR_VERSION < 3
5348 ctx = PyString_FromString(name);
5350 ctx = PyUnicode_FromString(name);
5352 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5354 PyErr_WriteUnraisable(Py_None);
5356 PyErr_WriteUnraisable(ctx);
5362 #------------------------------------------------------------------------------------
5364 traceback_utility_code = UtilityCode(
5366 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5369 #include "compile.h"
5370 #include "frameobject.h"
5371 #include "traceback.h"
5373 static void __Pyx_AddTraceback(const char *funcname) {
5374 PyObject *py_srcfile = 0;
5375 PyObject *py_funcname = 0;
5376 PyObject *py_globals = 0;
5377 PyObject *empty_string = 0;
5378 PyCodeObject *py_code = 0;
5379 PyFrameObject *py_frame = 0;
5381 #if PY_MAJOR_VERSION < 3
5382 py_srcfile = PyString_FromString(%(FILENAME)s);
5384 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5386 if (!py_srcfile) goto bad;
5388 #if PY_MAJOR_VERSION < 3
5389 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5391 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5395 #if PY_MAJOR_VERSION < 3
5396 py_funcname = PyString_FromString(funcname);
5398 py_funcname = PyUnicode_FromString(funcname);
5401 if (!py_funcname) goto bad;
5402 py_globals = PyModule_GetDict(%(GLOBALS)s);
5403 if (!py_globals) goto bad;
5404 #if PY_MAJOR_VERSION < 3
5405 empty_string = PyString_FromStringAndSize("", 0);
5407 empty_string = PyBytes_FromStringAndSize("", 0);
5409 if (!empty_string) goto bad;
5410 py_code = PyCode_New(
5411 0, /*int argcount,*/
5412 #if PY_MAJOR_VERSION >= 3
5413 0, /*int kwonlyargcount,*/
5416 0, /*int stacksize,*/
5418 empty_string, /*PyObject *code,*/
5419 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5420 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5421 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5422 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5423 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5424 py_srcfile, /*PyObject *filename,*/
5425 py_funcname, /*PyObject *name,*/
5426 %(LINENO)s, /*int firstlineno,*/
5427 empty_string /*PyObject *lnotab*/
5429 if (!py_code) goto bad;
5430 py_frame = PyFrame_New(
5431 PyThreadState_GET(), /*PyThreadState *tstate,*/
5432 py_code, /*PyCodeObject *code,*/
5433 py_globals, /*PyObject *globals,*/
5434 0 /*PyObject *locals*/
5436 if (!py_frame) goto bad;
5437 py_frame->f_lineno = %(LINENO)s;
5438 PyTraceBack_Here(py_frame);
5440 Py_XDECREF(py_srcfile);
5441 Py_XDECREF(py_funcname);
5442 Py_XDECREF(empty_string);
5443 Py_XDECREF(py_code);
5444 Py_XDECREF(py_frame);
5447 'FILENAME': Naming.filename_cname,
5448 'LINENO': Naming.lineno_cname,
5449 'CFILENAME': Naming.cfilenm_cname,
5450 'CLINENO': Naming.clineno_cname,
5451 'GLOBALS': Naming.module_cname,
5452 'EMPTY_TUPLE' : Naming.empty_tuple,
5455 restore_exception_utility_code = UtilityCode(
5457 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5458 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5461 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5462 PyObject *tmp_type, *tmp_value, *tmp_tb;
5463 PyThreadState *tstate = PyThreadState_GET();
5465 #if PY_MAJOR_VERSION >= 3
5466 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5467 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5468 tmp_type = tstate->exc_type;
5469 tmp_value = tstate->exc_value;
5470 tmp_tb = tstate->exc_traceback;
5471 PyErr_NormalizeException(&type, &value, &tb);
5472 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5473 tstate->exc_type = 0;
5474 tstate->exc_value = 0;
5475 tstate->exc_traceback = 0;
5476 PyException_SetContext(value, tmp_value);
5477 Py_DECREF(tmp_type);
5482 tmp_type = tstate->curexc_type;
5483 tmp_value = tstate->curexc_value;
5484 tmp_tb = tstate->curexc_traceback;
5485 tstate->curexc_type = type;
5486 tstate->curexc_value = value;
5487 tstate->curexc_traceback = tb;
5488 Py_XDECREF(tmp_type);
5489 Py_XDECREF(tmp_value);
5493 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5494 PyThreadState *tstate = PyThreadState_GET();
5495 *type = tstate->curexc_type;
5496 *value = tstate->curexc_value;
5497 *tb = tstate->curexc_traceback;
5499 tstate->curexc_type = 0;
5500 tstate->curexc_value = 0;
5501 tstate->curexc_traceback = 0;
5506 #------------------------------------------------------------------------------------
5508 set_vtable_utility_code = UtilityCode(
5510 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5513 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5514 PyObject *pycobj = 0;
5517 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5520 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5533 #------------------------------------------------------------------------------------
5535 get_vtable_utility_code = UtilityCode(
5537 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5540 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5544 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5547 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5548 if (!*(void **)vtabptr)
5561 #------------------------------------------------------------------------------------
5563 init_string_tab_utility_code = UtilityCode(
5565 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5568 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5570 #if PY_MAJOR_VERSION < 3
5571 if (t->is_unicode && (!t->is_identifier)) {
5572 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5573 } else if (t->intern) {
5574 *t->p = PyString_InternFromString(t->s);
5576 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5578 #else /* Python 3+ has unicode identifiers */
5579 if (t->is_identifier || (t->is_unicode && t->intern)) {
5580 *t->p = PyUnicode_InternFromString(t->s);
5581 } else if (t->is_unicode) {
5582 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5584 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5595 #------------------------------------------------------------------------------------
5597 get_exception_utility_code = UtilityCode(
5599 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5602 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5603 PyObject *tmp_type, *tmp_value, *tmp_tb;
5604 PyThreadState *tstate = PyThreadState_GET();
5605 *type = tstate->curexc_type;
5606 *value = tstate->curexc_value;
5607 *tb = tstate->curexc_traceback;
5608 tstate->curexc_type = 0;
5609 tstate->curexc_value = 0;
5610 tstate->curexc_traceback = 0;
5611 PyErr_NormalizeException(type, value, tb);
5612 if (PyErr_Occurred())
5617 tmp_type = tstate->exc_type;
5618 tmp_value = tstate->exc_value;
5619 tmp_tb = tstate->exc_traceback;
5620 tstate->exc_type = *type;
5621 tstate->exc_value = *value;
5622 tstate->exc_traceback = *tb;
5623 /* Make sure tstate is in a consistent state when we XDECREF
5624 these objects (XDECREF may run arbitrary code). */
5625 Py_XDECREF(tmp_type);
5626 Py_XDECREF(tmp_value);
5638 #------------------------------------------------------------------------------------
5640 reset_exception_utility_code = UtilityCode(
5642 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5643 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5646 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5647 PyThreadState *tstate = PyThreadState_GET();
5648 *type = tstate->exc_type;
5649 *value = tstate->exc_value;
5650 *tb = tstate->exc_traceback;
5656 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5657 PyObject *tmp_type, *tmp_value, *tmp_tb;
5658 PyThreadState *tstate = PyThreadState_GET();
5659 tmp_type = tstate->exc_type;
5660 tmp_value = tstate->exc_value;
5661 tmp_tb = tstate->exc_traceback;
5662 tstate->exc_type = type;
5663 tstate->exc_value = value;
5664 tstate->exc_traceback = tb;
5665 Py_XDECREF(tmp_type);
5666 Py_XDECREF(tmp_value);
5671 #------------------------------------------------------------------------------------
5673 force_init_threads_utility_code = UtilityCode(
5675 #ifndef __PYX_FORCE_INIT_THREADS
5676 #if PY_VERSION_HEX < 0x02040200
5677 #define __PYX_FORCE_INIT_THREADS 1
5679 #define __PYX_FORCE_INIT_THREADS 0
5684 #------------------------------------------------------------------------------------