2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
135 def gil_check(self, env):
140 error(self.pos, "%s not allowed without gil" % self.gil_message)
142 def clone_node(self):
143 """Clone the node. This is defined as a shallow copy, except for member lists
144 amongst the child attributes (from get_child_accessors) which are also
145 copied. Lists containing child nodes are thus seen as a way for the node
146 to hold multiple children directly; the list is not treated as a seperate
147 level in the tree."""
148 result = copy.copy(self)
149 for attrname in result.child_attrs:
150 value = getattr(result, attrname)
151 if isinstance(value, list):
152 setattr(result, attrname, [x for x in value])
157 # There are 4 phases of parse tree processing, applied in order to
158 # all the statements in a given scope-block:
160 # (0) analyse_control_flow
161 # Create the control flow tree into which state can be asserted and
164 # (1) analyse_declarations
165 # Make symbol table entries for all declarations at the current
166 # level, both explicit (def, cdef, etc.) and implicit (assignment
167 # to an otherwise undeclared name).
169 # (2) analyse_expressions
170 # Determine the result types of expressions and fill in the
171 # 'type' attribute of each ExprNode. Insert coercion nodes into the
172 # tree where needed to convert to and from Python objects.
173 # Allocate temporary locals for intermediate results. Fill
174 # in the 'result_code' attribute of each ExprNode with a C code
178 # Emit C code for all declarations, statements and expressions.
179 # Recursively applies the 3 processing phases to the bodies of
183 def analyse_control_flow(self, env):
186 def analyse_declarations(self, env):
189 def analyse_expressions(self, env):
190 raise InternalError("analyse_expressions not implemented for %s" % \
191 self.__class__.__name__)
193 def generate_code(self, code):
194 raise InternalError("generate_code not implemented for %s" % \
195 self.__class__.__name__)
197 def annotate(self, code):
198 # mro does the wrong thing
199 if isinstance(self, BlockNode):
200 self.body.annotate(code)
205 except AttributeError:
207 if not self.child_attrs:
210 for attr in self.child_attrs:
211 child = getattr(self, attr)
212 # Sometimes lists, sometimes nodes
215 elif isinstance(child, list):
217 pos = max(pos, c.end_pos())
219 pos = max(pos, child.end_pos())
223 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
225 return "<...nesting level cutoff...>"
226 if encountered is None:
228 if id(self) in encountered:
229 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
230 encountered.add(id(self))
232 def dump_child(x, level):
233 if isinstance(x, Node):
234 return x.dump(level, filter_out, cutoff-1, encountered)
235 elif isinstance(x, list):
236 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
241 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
243 return "<%s (%d)>" % (self.__class__.__name__, id(self))
246 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
247 for key, value in attrs:
248 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
249 res += "%s>" % indent
252 class CompilerDirectivesNode(Node):
254 Sets compiler directives for the children nodes
256 # directives {string:value} A dictionary holding the right value for
257 # *all* possible directives.
259 child_attrs = ["body"]
261 def analyse_control_flow(self, env):
263 env.directives = self.directives
264 self.body.analyse_control_flow(env)
267 def analyse_declarations(self, env):
269 env.directives = self.directives
270 self.body.analyse_declarations(env)
273 def analyse_expressions(self, env):
275 env.directives = self.directives
276 self.body.analyse_expressions(env)
279 def generate_function_definitions(self, env, code):
280 env_old = env.directives
281 code_old = code.globalstate.directives
282 code.globalstate.directives = self.directives
283 self.body.generate_function_definitions(env, code)
284 env.directives = env_old
285 code.globalstate.directives = code_old
287 def generate_execution_code(self, code):
288 old = code.globalstate.directives
289 code.globalstate.directives = self.directives
290 self.body.generate_execution_code(code)
291 code.globalstate.directives = old
293 def annotate(self, code):
294 old = code.globalstate.directives
295 code.globalstate.directives = self.directives
296 self.body.annotate(code)
297 code.globalstate.directives = old
299 class BlockNode(object):
300 # Mixin class for nodes representing a declaration block.
302 def generate_const_definitions(self, env, code):
303 if env.const_entries:
304 for entry in env.const_entries:
305 if not entry.is_interned:
306 code.globalstate.add_const_definition(entry)
308 def generate_interned_string_decls(self, env, code):
309 entries = env.global_scope().new_interned_string_entries
311 for entry in entries:
312 code.globalstate.add_interned_string_decl(entry)
315 def generate_py_string_decls(self, env, code):
317 return # earlier error
318 entries = env.pystring_entries
320 for entry in entries:
321 if not entry.is_interned:
322 code.globalstate.add_py_string_decl(entry)
324 def generate_interned_num_decls(self, env, code):
325 # Flush accumulated interned nums from the global scope
326 # and generate declarations for them.
327 genv = env.global_scope()
328 entries = genv.interned_nums
330 for entry in entries:
331 code.globalstate.add_interned_num_decl(entry)
334 def generate_cached_builtins_decls(self, env, code):
335 entries = env.global_scope().undeclared_cached_builtins
336 for entry in entries:
337 code.globalstate.add_cached_builtin_decl(entry)
341 class StatListNode(Node):
342 # stats a list of StatNode
344 child_attrs = ["stats"]
346 def create_analysed(pos, env, *args, **kw):
347 node = StatListNode(pos, *args, **kw)
348 return node # No node-specific analysis necesarry
349 create_analysed = staticmethod(create_analysed)
351 def analyse_control_flow(self, env):
352 for stat in self.stats:
353 stat.analyse_control_flow(env)
355 def analyse_declarations(self, env):
356 #print "StatListNode.analyse_declarations" ###
357 for stat in self.stats:
358 stat.analyse_declarations(env)
360 def analyse_expressions(self, env):
361 #print "StatListNode.analyse_expressions" ###
362 for stat in self.stats:
363 stat.analyse_expressions(env)
365 def generate_function_definitions(self, env, code):
366 #print "StatListNode.generate_function_definitions" ###
367 for stat in self.stats:
368 stat.generate_function_definitions(env, code)
370 def generate_execution_code(self, code):
371 #print "StatListNode.generate_execution_code" ###
372 for stat in self.stats:
373 code.mark_pos(stat.pos)
374 stat.generate_execution_code(code)
376 def annotate(self, code):
377 for stat in self.stats:
381 class StatNode(Node):
383 # Code generation for statements is split into the following subphases:
385 # (1) generate_function_definitions
386 # Emit C code for the definitions of any structs,
387 # unions, enums and functions defined in the current
390 # (2) generate_execution_code
391 # Emit C code for executable statements.
394 def generate_function_definitions(self, env, code):
397 def generate_execution_code(self, code):
398 raise InternalError("generate_execution_code not implemented for %s" % \
399 self.__class__.__name__)
402 class CDefExternNode(StatNode):
403 # include_file string or None
406 child_attrs = ["body"]
408 def analyse_declarations(self, env):
409 if self.include_file:
410 env.add_include_file(self.include_file)
411 old_cinclude_flag = env.in_cinclude
413 self.body.analyse_declarations(env)
414 env.in_cinclude = old_cinclude_flag
416 def analyse_expressions(self, env):
419 def generate_execution_code(self, code):
422 def annotate(self, code):
423 self.body.annotate(code)
426 class CDeclaratorNode(Node):
427 # Part of a C declaration.
429 # Processing during analyse_declarations phase:
432 # Returns (name, type) pair where name is the
433 # CNameDeclaratorNode of the name being declared
434 # and type is the type it is being declared as.
436 # calling_convention string Calling convention of CFuncDeclaratorNode
437 # for which this is a base
441 calling_convention = ""
444 class CNameDeclaratorNode(CDeclaratorNode):
445 # name string The Pyrex name being declared
446 # cname string or None C name, if specified
447 # default ExprNode or None the value assigned on declaration
449 child_attrs = ['default']
453 def analyse(self, base_type, env, nonempty = 0):
454 if nonempty and self.name == '':
455 # May have mistaken the name for the type.
456 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
457 error(self.pos, "Missing argument name")
458 elif base_type.is_void:
459 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
461 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
462 base_type = py_object_type
463 self.type = base_type
464 return self, base_type
466 class CPtrDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Pointer base type cannot be a Python object")
475 ptr_type = PyrexTypes.c_ptr_type(base_type)
476 return self.base.analyse(ptr_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
486 self.dimension.analyse_const_expression(env)
487 if not self.dimension.type.is_int:
488 error(self.dimension.pos, "Array dimension not integer")
489 size = self.dimension.result()
497 if not base_type.is_complete():
499 "Array element type '%s' is incomplete" % base_type)
500 if base_type.is_pyobject:
502 "Array element cannot be a Python object")
503 if base_type.is_cfunction:
505 "Array element cannot be a function")
506 array_type = PyrexTypes.c_array_type(base_type, size)
507 return self.base.analyse(array_type, env, nonempty = nonempty)
510 class CFuncDeclaratorNode(CDeclaratorNode):
511 # base CDeclaratorNode
512 # args [CArgDeclNode]
513 # has_varargs boolean
514 # exception_value ConstNode
515 # exception_check boolean True if PyErr_Occurred check needed
516 # nogil boolean Can be called without gil
517 # with_gil boolean Acquire gil around function body
519 child_attrs = ["base", "args", "exception_value"]
522 optional_arg_count = 0
524 def analyse(self, return_type, env, nonempty = 0):
528 for arg_node in self.args:
529 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
530 name = name_declarator.name
531 if name_declarator.cname:
533 "Function argument cannot have C name specification")
534 # Turn *[] argument into **
536 type = PyrexTypes.c_ptr_type(type.base_type)
537 # Catch attempted C-style func(void) decl
539 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
540 # if type.is_pyobject and self.nogil:
542 # "Function with Python argument cannot be declared nogil")
543 func_type_args.append(
544 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
546 self.optional_arg_count += 1
547 elif self.optional_arg_count:
548 error(self.pos, "Non-default argument follows default argument")
550 if self.optional_arg_count:
551 scope = StructOrUnionScope()
552 arg_count_member = '%sn' % Naming.pyrex_prefix
553 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
554 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
555 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
556 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
557 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
562 cname = struct_cname)
563 self.op_args_struct.defined_in_pxd = 1
564 self.op_args_struct.used = 1
568 if self.exception_check == '+':
569 env.add_include_file('stdexcept')
570 if return_type.is_pyobject \
571 and (self.exception_value or self.exception_check) \
572 and self.exception_check != '+':
574 "Exception clause not allowed for function returning Python object")
576 if self.exception_value:
577 self.exception_value.analyse_const_expression(env)
578 if self.exception_check == '+':
579 exc_val_type = self.exception_value.type
580 if not exc_val_type.is_error and \
581 not exc_val_type.is_pyobject and \
582 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
583 error(self.exception_value.pos,
584 "Exception value must be a Python exception or cdef function with no arguments.")
585 exc_val = self.exception_value
587 exc_val = self.exception_value.result()
588 if not return_type.assignable_from(self.exception_value.type):
589 error(self.exception_value.pos,
590 "Exception value incompatible with function return type")
591 exc_check = self.exception_check
592 if return_type.is_array:
594 "Function cannot return an array")
595 if return_type.is_cfunction:
597 "Function cannot return a function")
598 func_type = PyrexTypes.CFuncType(
599 return_type, func_type_args, self.has_varargs,
600 optional_arg_count = self.optional_arg_count,
601 exception_value = exc_val, exception_check = exc_check,
602 calling_convention = self.base.calling_convention,
603 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
604 if self.optional_arg_count:
605 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
606 return self.base.analyse(func_type, env)
609 class CArgDeclNode(Node):
610 # Item in a function declaration argument list.
612 # base_type CBaseTypeNode
613 # declarator CDeclaratorNode
614 # not_none boolean Tagged with 'not None'
615 # default ExprNode or None
616 # default_entry Symtab.Entry Entry for the variable holding the default value
617 # default_result_code string cname or code fragment for default value
618 # is_self_arg boolean Is the "self" arg of an extension type method
619 # is_kw_only boolean Is a keyword-only argument
621 child_attrs = ["base_type", "declarator", "default"]
626 name_declarator = None
628 def analyse(self, env, nonempty = 0):
629 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
630 if self.type is None:
631 # The parser may missinterpret names as types...
633 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
635 self.declarator.name = self.base_type.name
636 self.base_type.name = None
637 self.base_type.is_basic_c_type = False
640 could_be_name = False
641 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
642 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
643 self.declarator.name = self.base_type.arg_name
644 return self.declarator.analyse(base_type, env, nonempty = nonempty)
646 return self.name_declarator, self.type
648 def annotate(self, code):
650 self.default.annotate(code)
653 class CBaseTypeNode(Node):
654 # Abstract base class for C base type nodes.
656 # Processing during analyse_declarations phase:
663 class CAnalysedBaseTypeNode(Node):
668 def analyse(self, env, could_be_name = False):
671 class CSimpleBaseTypeNode(CBaseTypeNode):
673 # module_path [string] Qualifying name components
674 # is_basic_c_type boolean
678 # is_self_arg boolean Is self argument of C method
681 arg_name = None # in case the argument name was interpreted as a type
683 def analyse(self, env, could_be_name = False):
684 # Return type descriptor.
685 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
687 if self.is_basic_c_type:
688 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
690 error(self.pos, "Unrecognised type modifier combination")
691 elif self.name == "object" and not self.module_path:
692 type = py_object_type
693 elif self.name is None:
694 if self.is_self_arg and env.is_c_class_scope:
695 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
696 type = env.parent_type
698 type = py_object_type
701 scope = env.find_imported_module(self.module_path, self.pos)
705 if scope.is_c_class_scope:
706 scope = scope.global_scope()
707 entry = scope.lookup(self.name)
708 if entry and entry.is_type:
711 if self.is_self_arg and env.is_c_class_scope:
712 type = env.parent_type
714 type = py_object_type
715 self.arg_name = self.name
717 error(self.pos, "'%s' is not a type identifier" % self.name)
719 if not type.is_numeric or type.is_complex:
720 error(self.pos, "can only complexify c numeric types")
721 type = PyrexTypes.CComplexType(type)
722 type.create_declaration_utility_code(env)
726 return PyrexTypes.error_type
728 class CBufferAccessTypeNode(CBaseTypeNode):
730 # positional_args [ExprNode] List of positional arguments
731 # keyword_args DictNode Keyword arguments
732 # base_type_node CBaseTypeNode
735 # type PyrexType.BufferType ...containing the right options
738 child_attrs = ["base_type_node", "positional_args",
739 "keyword_args", "dtype_node"]
745 def analyse(self, env, could_be_name = False):
746 base_type = self.base_type_node.analyse(env)
747 if base_type.is_error: return base_type
750 options = Buffer.analyse_buffer_options(
753 self.positional_args,
755 base_type.buffer_defaults)
757 self.type = PyrexTypes.BufferType(base_type, **options)
760 class CComplexBaseTypeNode(CBaseTypeNode):
761 # base_type CBaseTypeNode
762 # declarator CDeclaratorNode
764 child_attrs = ["base_type", "declarator"]
766 def analyse(self, env, could_be_name = False):
767 base = self.base_type.analyse(env, could_be_name)
768 _, type = self.declarator.analyse(base, env)
772 class CVarDefNode(StatNode):
773 # C variable definition or forward/extern function declaration.
775 # visibility 'private' or 'public' or 'extern'
776 # base_type CBaseTypeNode
777 # declarators [CDeclaratorNode]
780 # need_properties [entry]
782 # decorators [cython.locals(...)] or None
783 # directive_locals { string : NameNode } locals defined by cython.locals(...)
785 child_attrs = ["base_type", "declarators"]
789 directive_locals = {}
791 def analyse_declarations(self, env, dest_scope = None):
794 self.dest_scope = dest_scope
795 base_type = self.base_type.analyse(env)
796 if (dest_scope.is_c_class_scope
797 and self.visibility == 'public'
798 and base_type.is_pyobject
799 and (base_type.is_builtin_type or base_type.is_extension_type)):
800 self.need_properties = []
802 visibility = 'private'
804 need_property = False
805 visibility = self.visibility
807 for declarator in self.declarators:
808 name_declarator, type = declarator.analyse(base_type, env)
809 if not type.is_complete():
810 if not (self.visibility == 'extern' and type.is_array):
811 error(declarator.pos,
812 "Variable type '%s' is incomplete" % type)
813 if self.visibility == 'extern' and type.is_pyobject:
814 error(declarator.pos,
815 "Python object cannot be declared extern")
816 name = name_declarator.name
817 cname = name_declarator.cname
819 error(declarator.pos, "Missing name in declaration.")
821 if type.is_cfunction:
822 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
823 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
825 if entry is not None:
826 entry.directive_locals = self.directive_locals
828 if self.directive_locals:
829 s.error("Decorators can only be followed by functions")
830 if self.in_pxd and self.visibility != 'extern':
832 "Only 'extern' C variable declaration allowed in .pxd file")
833 entry = dest_scope.declare_var(name, type, declarator.pos,
834 cname = cname, visibility = visibility, is_cdef = 1)
836 self.need_properties.append(entry)
837 entry.needs_property = 1
840 class CStructOrUnionDefNode(StatNode):
842 # cname string or None
843 # kind "struct" or "union"
844 # typedef_flag boolean
845 # visibility "public" or "private"
847 # attributes [CVarDefNode] or None
851 child_attrs = ["attributes"]
853 def analyse_declarations(self, env):
855 if self.visibility == 'extern' and self.packed:
856 error(self.pos, "Cannot declare extern struct as 'packed'")
857 if self.attributes is not None:
858 scope = StructOrUnionScope(self.name)
859 self.entry = env.declare_struct_or_union(
860 self.name, self.kind, scope, self.typedef_flag, self.pos,
861 self.cname, visibility = self.visibility, packed = self.packed)
862 if self.attributes is not None:
863 if self.in_pxd and not env.in_cinclude:
864 self.entry.defined_in_pxd = 1
865 for attr in self.attributes:
866 attr.analyse_declarations(env, scope)
867 if self.visibility != 'extern':
868 need_typedef_indirection = False
869 for attr in scope.var_entries:
872 type = type.base_type
873 if type == self.entry.type:
874 error(attr.pos, "Struct cannot contain itself as a member.")
875 if self.typedef_flag:
877 type = type.base_type
878 if type == self.entry.type:
879 need_typedef_indirection = True
880 if need_typedef_indirection:
881 # C can't handle typedef structs that refer to themselves.
882 struct_entry = self.entry
883 cname = env.new_const_cname()
884 self.entry = env.declare_typedef(self.name, struct_entry.type, self.pos, cname = self.cname, visibility='ignore')
885 struct_entry.type.typedef_flag = False
886 struct_entry.cname = struct_entry.type.cname = env.new_const_cname()
888 def analyse_expressions(self, env):
891 def generate_execution_code(self, code):
895 class CEnumDefNode(StatNode):
896 # name string or None
897 # cname string or None
898 # items [CEnumDefItemNode]
899 # typedef_flag boolean
900 # visibility "public" or "private"
904 child_attrs = ["items"]
906 def analyse_declarations(self, env):
907 self.entry = env.declare_enum(self.name, self.pos,
908 cname = self.cname, typedef_flag = self.typedef_flag,
909 visibility = self.visibility)
910 if self.items is not None:
911 if self.in_pxd and not env.in_cinclude:
912 self.entry.defined_in_pxd = 1
913 for item in self.items:
914 item.analyse_declarations(env, self.entry)
916 def analyse_expressions(self, env):
917 if self.visibility == 'public':
918 self.temp = env.allocate_temp_pyobject()
919 env.release_temp(self.temp)
921 def generate_execution_code(self, code):
922 if self.visibility == 'public':
923 for item in self.entry.enum_values:
924 code.putln("%s = PyInt_FromLong(%s); %s" % (
927 code.error_goto_if_null(self.temp, item.pos)))
928 code.put_gotref(self.temp)
929 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
933 code.error_goto(item.pos)))
934 code.put_decref_clear(self.temp, PyrexTypes.py_object_type)
937 class CEnumDefItemNode(StatNode):
939 # cname string or None
940 # value ExprNode or None
942 child_attrs = ["value"]
944 def analyse_declarations(self, env, enum_entry):
946 self.value.analyse_const_expression(env)
947 if not self.value.type.is_int:
948 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
949 self.value.analyse_const_expression(env)
950 value = self.value.result()
953 entry = env.declare_const(self.name, enum_entry.type,
954 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
955 enum_entry.enum_values.append(entry)
958 class CTypeDefNode(StatNode):
959 # base_type CBaseTypeNode
960 # declarator CDeclaratorNode
961 # visibility "public" or "private"
964 child_attrs = ["base_type", "declarator"]
966 def analyse_declarations(self, env):
967 base = self.base_type.analyse(env)
968 name_declarator, type = self.declarator.analyse(base, env)
969 name = name_declarator.name
970 cname = name_declarator.cname
971 entry = env.declare_typedef(name, type, self.pos,
972 cname = cname, visibility = self.visibility)
973 if self.in_pxd and not env.in_cinclude:
974 entry.defined_in_pxd = 1
976 def analyse_expressions(self, env):
978 def generate_execution_code(self, code):
982 class FuncDefNode(StatNode, BlockNode):
983 # Base class for function definition nodes.
985 # return_type PyrexType
986 # #filename string C name of filename string const
988 # needs_closure boolean Whether or not this function has inner functions/classes/yield
989 # directive_locals { string : NameNode } locals defined by cython.locals(...)
993 needs_closure = False
995 def analyse_default_values(self, env):
996 genv = env.global_scope()
997 for arg in self.args:
1000 if not hasattr(arg, 'default_entry'):
1001 arg.default.analyse_types(env)
1002 arg.default = arg.default.coerce_to(arg.type, genv)
1003 if arg.default.is_literal:
1004 arg.default_entry = arg.default
1005 arg.default_result_code = arg.default.calculate_result_code()
1006 if arg.default.type != arg.type and not arg.type.is_int:
1007 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
1009 arg.default.allocate_temps(genv)
1010 arg.default_entry = genv.add_default_value(arg.type)
1011 if arg.type.is_pyobject:
1012 arg.default_entry.init = 0
1013 arg.default_entry.used = 1
1014 arg.default_result_code = arg.default_entry.cname
1017 "This argument cannot have a default value")
1020 def need_gil_acquisition(self, lenv):
1023 def create_local_scope(self, env):
1025 while env.is_py_class_scope or env.is_c_class_scope:
1026 env = env.outer_scope
1027 if self.needs_closure:
1028 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1030 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1031 lenv.return_type = self.return_type
1032 type = self.entry.type
1033 if type.is_cfunction:
1034 lenv.nogil = type.nogil and not type.with_gil
1035 self.local_scope = lenv
1036 lenv.directives = env.directives
1039 def generate_function_definitions(self, env, code):
1042 lenv = self.local_scope
1044 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1045 self.entry.scope.is_c_class_scope)
1047 # Generate C code for header and body of function
1048 code.enter_cfunc_scope()
1049 code.return_from_error_cleanup_label = code.new_label()
1051 # ----- Top-level constants used by this function
1052 code.mark_pos(self.pos)
1053 self.generate_interned_num_decls(lenv, code)
1054 self.generate_interned_string_decls(lenv, code)
1055 self.generate_py_string_decls(lenv, code)
1056 self.generate_cached_builtins_decls(lenv, code)
1058 #code.put_var_declarations(lenv.const_entries, static = 1)
1059 self.generate_const_definitions(lenv, code)
1060 # ----- Function header
1063 self.py_func.generate_function_header(code,
1064 with_pymethdef = env.is_py_class_scope,
1066 self.generate_function_header(code,
1067 with_pymethdef = env.is_py_class_scope)
1068 # ----- Local variable declarations
1069 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1070 self.generate_argument_declarations(lenv, code)
1071 if self.needs_closure:
1072 code.putln("/* TODO: declare and create scope object */")
1073 code.put_var_declarations(lenv.var_entries)
1075 if not self.return_type.is_void:
1076 if self.return_type.is_pyobject:
1080 (self.return_type.declaration_code(
1081 Naming.retval_cname),
1083 tempvardecl_code = code.insertion_point()
1084 self.generate_keyword_list(code)
1085 # ----- Extern library function declarations
1086 lenv.generate_library_function_declarations(code)
1087 # ----- GIL acquisition
1088 acquire_gil = self.need_gil_acquisition(lenv)
1090 env.use_utility_code(force_init_threads_utility_code)
1091 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1092 # ----- Automatic lead-ins for certain special functions
1094 code.put_setup_refcount_context(self.entry.name)
1095 if is_getbuffer_slot:
1096 self.getbuffer_init(code)
1097 # ----- Fetch arguments
1098 self.generate_argument_parsing_code(env, code)
1099 # If an argument is assigned to in the body, we must
1100 # incref it to properly keep track of refcounts.
1101 for entry in lenv.arg_entries:
1102 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1103 code.put_var_incref(entry)
1104 # ----- Initialise local variables
1105 for entry in lenv.var_entries:
1106 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1107 code.put_init_var_to_py_none(entry)
1108 # ----- Initialise local buffer auxiliary variables
1109 for entry in lenv.var_entries + lenv.arg_entries:
1110 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1111 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1112 # ----- Check and convert arguments
1113 self.generate_argument_type_tests(code)
1114 # ----- Acquire buffer arguments
1115 for entry in lenv.arg_entries:
1116 if entry.type.is_buffer:
1117 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1118 # ----- Function body
1119 self.body.generate_execution_code(code)
1120 # ----- Default return value
1122 if self.return_type.is_pyobject:
1123 #if self.return_type.is_extension_type:
1124 # lhs = "(PyObject *)%s" % Naming.retval_cname
1126 lhs = Naming.retval_cname
1127 code.put_init_to_py_none(lhs, self.return_type)
1129 val = self.return_type.default_value
1131 code.putln("%s = %s;" % (Naming.retval_cname, val))
1132 # ----- Error cleanup
1133 if code.error_label in code.labels_used:
1134 code.put_goto(code.return_label)
1135 code.put_label(code.error_label)
1136 # cleanup temps the old way
1137 code.put_var_xdecrefs(lenv.temp_entries)
1138 # cleanup temps the new way
1139 for cname, type in code.funcstate.all_managed_temps():
1140 code.put_xdecref(cname, type)
1142 # Clean up buffers -- this calls a Python function
1143 # so need to save and restore error state
1144 buffers_present = len(lenv.buffer_entries) > 0
1146 code.globalstate.use_utility_code(restore_exception_utility_code)
1147 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1148 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1149 for entry in lenv.buffer_entries:
1150 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1151 #code.putln("%s = 0;" % entry.cname)
1152 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1154 err_val = self.error_value()
1155 exc_check = self.caller_will_check_exceptions()
1156 if err_val is not None or exc_check:
1157 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1159 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1160 % self.entry.qualified_name, 0)
1162 '__Pyx_WriteUnraisable("%s");' %
1163 self.entry.qualified_name)
1164 env.use_utility_code(unraisable_exception_utility_code)
1165 env.use_utility_code(restore_exception_utility_code)
1166 default_retval = self.return_type.default_value
1167 if err_val is None and default_retval:
1168 err_val = default_retval
1169 if err_val is not None:
1172 Naming.retval_cname,
1175 if is_getbuffer_slot:
1176 self.getbuffer_error_cleanup(code)
1178 # If we are using the non-error cleanup section we should
1179 # jump past it if we have an error. The if-test below determine
1180 # whether this section is used.
1181 if buffers_present or is_getbuffer_slot:
1182 code.put_goto(code.return_from_error_cleanup_label)
1185 # ----- Non-error return cleanup
1186 # If you add anything here, remember to add a condition to the
1187 # if-test above in the error block (so that it can jump past this
1189 code.put_label(code.return_label)
1190 for entry in lenv.buffer_entries:
1192 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1193 if is_getbuffer_slot:
1194 self.getbuffer_normal_cleanup(code)
1195 # ----- Return cleanup for both error and no-error return
1196 code.put_label(code.return_from_error_cleanup_label)
1197 if not Options.init_local_none:
1198 for entry in lenv.var_entries:
1199 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1200 entry.xdecref_cleanup = 1
1201 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1202 # Decref any increfed args
1203 for entry in lenv.arg_entries:
1204 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1205 code.put_var_decref(entry)
1207 # code.putln("/* TODO: decref scope object */")
1209 # This code is duplicated in ModuleNode.generate_module_init_func
1211 default_retval = self.return_type.default_value
1212 err_val = self.error_value()
1213 if err_val is None and default_retval:
1214 err_val = default_retval
1215 if self.return_type.is_pyobject:
1216 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1218 code.put_finish_refcount_context()
1221 code.putln("PyGILState_Release(_save);")
1223 if not self.return_type.is_void:
1224 code.putln("return %s;" % Naming.retval_cname)
1227 # ----- Go back and insert temp variable declarations
1228 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1229 tempvardecl_code.put_temp_declarations(code.funcstate)
1230 # ----- Python version
1231 code.exit_cfunc_scope()
1233 self.py_func.generate_function_definitions(env, code)
1234 self.generate_wrapper_functions(code)
1236 def declare_argument(self, env, arg):
1237 if arg.type.is_void:
1238 error(arg.pos, "Invalid use of 'void'")
1239 elif not arg.type.is_complete() and not arg.type.is_array:
1241 "Argument type '%s' is incomplete" % arg.type)
1242 return env.declare_arg(arg.name, arg.type, arg.pos)
1244 def generate_wrapper_functions(self, code):
1247 def generate_execution_code(self, code):
1248 # Evaluate and store argument default values
1249 for arg in self.args:
1250 default = arg.default
1252 if not default.is_literal:
1253 default.generate_evaluation_code(code)
1254 default.make_owned_reference(code)
1257 arg.default_entry.cname,
1258 default.result_as(arg.default_entry.type)))
1259 if default.is_temp and default.type.is_pyobject:
1260 code.putln("%s = 0;" % default.result())
1261 default.free_temps(code)
1262 code.put_var_giveref(arg.default_entry)
1263 # For Python class methods, create and store function object
1265 self.assmt.generate_execution_code(code)
1268 # Special code for the __getbuffer__ function
1270 def getbuffer_init(self, code):
1271 info = self.local_scope.arg_entries[1].cname
1272 # Python 3.0 betas have a bug in memoryview which makes it call
1273 # getbuffer with a NULL parameter. For now we work around this;
1274 # the following line should be removed when this bug is fixed.
1275 code.putln("if (%s == NULL) return 0;" % info)
1276 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1277 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1279 def getbuffer_error_cleanup(self, code):
1280 info = self.local_scope.arg_entries[1].cname
1281 code.put_gotref("%s->obj" % info)
1282 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1285 def getbuffer_normal_cleanup(self, code):
1286 info = self.local_scope.arg_entries[1].cname
1287 code.putln("if (%s->obj == Py_None) {" % info)
1288 code.put_gotref("Py_None")
1289 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1292 class CFuncDefNode(FuncDefNode):
1293 # C function definition.
1295 # modifiers ['inline']
1296 # visibility 'private' or 'public' or 'extern'
1297 # base_type CBaseTypeNode
1298 # declarator CDeclaratorNode
1301 # decorators [DecoratorNode] list of decorators
1303 # with_gil boolean Acquire GIL around body
1305 # py_func wrapper for calling from Python
1306 # overridable whether or not this is a cpdef function
1307 # inline_in_pxd whether this is an inline function in a pxd file
1309 child_attrs = ["base_type", "declarator", "body", "py_func"]
1311 inline_in_pxd = False
1313 directive_locals = {}
1315 def unqualified_name(self):
1316 return self.entry.name
1318 def analyse_declarations(self, env):
1319 directive_locals = self.directive_locals = env.directives['locals']
1320 base_type = self.base_type.analyse(env)
1321 # The 2 here is because we need both function and argument names.
1322 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1323 if not type.is_cfunction:
1325 "Suite attached to non-function declaration")
1326 # Remember the actual type according to the function header
1327 # written here, because the type in the symbol table entry
1328 # may be different if we're overriding a C method inherited
1329 # from the base type of an extension type.
1331 type.is_overridable = self.overridable
1332 declarator = self.declarator
1333 while not hasattr(declarator, 'args'):
1334 declarator = declarator.base
1335 self.args = declarator.args
1336 for formal_arg, type_arg in zip(self.args, type.args):
1337 formal_arg.type = type_arg.type
1338 formal_arg.name = type_arg.name
1339 formal_arg.cname = type_arg.cname
1340 name = name_declarator.name
1341 cname = name_declarator.cname
1342 self.entry = env.declare_cfunction(
1343 name, type, self.pos,
1344 cname = cname, visibility = self.visibility,
1345 defining = self.body is not None,
1346 api = self.api, modifiers = self.modifiers)
1347 self.entry.inline_func_in_pxd = self.inline_in_pxd
1348 self.return_type = type.return_type
1350 if self.overridable and not env.is_module_scope:
1351 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1352 # An error will be produced in the cdef function
1353 self.overridable = False
1355 if self.overridable:
1357 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1358 self.py_func = DefNode(pos = self.pos,
1359 name = self.entry.name,
1362 starstar_arg = None,
1364 body = py_func_body,
1366 self.py_func.is_module_scope = env.is_module_scope
1367 self.py_func.analyse_declarations(env)
1368 self.entry.as_variable = self.py_func.entry
1369 # Reset scope entry the above cfunction
1370 env.entries[name] = self.entry
1371 self.py_func.interned_attr_cname = env.intern_identifier(
1372 self.py_func.entry.name)
1373 if not env.is_module_scope or Options.lookup_module_cpdef:
1374 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1375 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1377 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1379 args = self.type.args
1380 if omit_optional_args:
1381 args = args[:len(args) - self.type.optional_arg_count]
1382 arg_names = [arg.name for arg in args]
1384 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1386 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1387 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1388 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1389 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)
1390 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1392 def declare_arguments(self, env):
1393 for arg in self.type.args:
1395 error(arg.pos, "Missing argument name")
1396 self.declare_argument(env, arg)
1398 def need_gil_acquisition(self, lenv):
1400 with_gil = self.type.with_gil
1401 if type.nogil and not with_gil:
1402 if type.return_type.is_pyobject:
1404 "Function with Python return type cannot be declared nogil")
1405 for entry in lenv.var_entries + lenv.temp_entries:
1406 if entry.type.is_pyobject:
1407 error(self.pos, "Function declared nogil has Python locals or temporaries")
1410 def analyse_expressions(self, env):
1411 self.local_scope.directives = env.directives
1412 self.analyse_default_values(env)
1413 if self.py_func is not None:
1414 self.py_func.analyse_expressions(env)
1416 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1419 visibility = self.entry.visibility
1420 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1421 arg_decls.append(arg.declaration_code())
1422 if with_dispatch and self.overridable:
1423 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1424 if type.optional_arg_count and with_opt_args:
1425 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1426 if type.has_varargs:
1427 arg_decls.append("...")
1429 arg_decls = ["void"]
1431 cname = self.entry.func_cname
1432 entity = type.function_header_code(cname, ', '.join(arg_decls))
1433 if visibility == 'public':
1434 dll_linkage = "DL_EXPORT"
1437 header = self.return_type.declaration_code(entity,
1438 dll_linkage = dll_linkage)
1439 if visibility == 'extern':
1440 storage_class = "%s " % Naming.extern_c_macro
1441 elif visibility == 'public':
1444 storage_class = "static "
1445 code.putln("%s%s %s {" % (
1447 ' '.join(self.modifiers).upper(), # macro forms
1450 def generate_argument_declarations(self, env, code):
1451 for arg in self.args:
1453 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1455 def generate_keyword_list(self, code):
1458 def generate_argument_parsing_code(self, env, code):
1460 if self.type.optional_arg_count:
1461 code.putln('if (%s) {' % Naming.optional_args_cname)
1462 for arg in self.args:
1464 # FIXME: simple name prefixing doesn't work when
1465 # argument name mangling is in place
1466 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1467 declarator = arg.declarator
1468 while not hasattr(declarator, 'name'):
1469 declarator = declarator.base
1470 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1472 for _ in range(self.type.optional_arg_count):
1476 def generate_argument_conversion_code(self, code):
1479 def generate_argument_type_tests(self, code):
1480 # Generate type tests for args whose type in a parent
1481 # class is a supertype of the declared type.
1482 for arg in self.type.args:
1483 if arg.needs_type_test:
1484 self.generate_arg_type_test(arg, code)
1486 def generate_arg_type_test(self, arg, code):
1487 # Generate type test for one argument.
1488 if arg.type.typeobj_is_available():
1489 typeptr_cname = arg.type.typeptr_cname
1490 arg_code = "((PyObject *)%s)" % arg.cname
1492 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1497 type.is_builtin_type,
1498 code.error_goto(arg.pos)))
1500 error(arg.pos, "Cannot test type of extern C class "
1501 "without type object name specification")
1503 def error_value(self):
1504 if self.return_type.is_pyobject:
1508 return self.entry.type.exception_value
1510 def caller_will_check_exceptions(self):
1511 return self.entry.type.exception_check
1513 def generate_wrapper_functions(self, code):
1514 # If the C signature of a function has changed, we need to generate
1515 # wrappers to put in the slots here.
1518 func_type = entry.type
1519 while entry.prev_entry is not None:
1521 entry = entry.prev_entry
1522 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1524 self.generate_function_header(code,
1526 with_dispatch = entry.type.is_overridable,
1527 with_opt_args = entry.type.optional_arg_count,
1528 cname = entry.func_cname)
1529 if not self.return_type.is_void:
1531 args = self.type.args
1532 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1533 if entry.type.is_overridable:
1534 arglist.append(Naming.skip_dispatch_cname)
1535 elif func_type.is_overridable:
1537 if entry.type.optional_arg_count:
1538 arglist.append(Naming.optional_args_cname)
1539 elif func_type.optional_arg_count:
1540 arglist.append('NULL')
1541 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1545 class PyArgDeclNode(Node):
1546 # Argument which must be a Python object (used
1547 # for * and ** arguments).
1550 # entry Symtab.Entry
1554 class DecoratorNode(Node):
1557 # decorator NameNode or CallNode
1558 child_attrs = ['decorator']
1561 class DefNode(FuncDefNode):
1562 # A Python function definition.
1564 # name string the Python name of the function
1565 # decorators [DecoratorNode] list of decorators
1566 # args [CArgDeclNode] formal arguments
1567 # star_arg PyArgDeclNode or None * argument
1568 # starstar_arg PyArgDeclNode or None ** argument
1569 # doc EncodedString or None
1572 # The following subnode is constructed internally
1573 # when the def statement is inside a Python class definition.
1575 # assmt AssignmentNode Function construction/assignment
1577 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1581 num_required_kw_args = 0
1582 reqd_kw_flags_cname = "0"
1588 def __init__(self, pos, **kwds):
1589 FuncDefNode.__init__(self, pos, **kwds)
1591 for arg in self.args:
1598 self.num_kwonly_args = k
1599 self.num_required_kw_args = rk
1600 self.num_required_args = r
1602 def as_cfunction(self, cfunc=None, scope=None):
1604 error(self.star_arg.pos, "cdef function cannot have star argument")
1605 if self.starstar_arg:
1606 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1609 for formal_arg in self.args:
1610 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1611 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1613 type = py_object_type,
1614 pos = formal_arg.pos))
1615 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1617 has_varargs = False,
1618 exception_value = None,
1619 exception_check = False,
1622 is_overridable = True)
1623 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1625 cfunc_type = cfunc.type
1626 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1627 error(self.pos, "wrong number of arguments")
1628 error(declarator.pos, "previous declaration here")
1629 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1630 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1631 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1632 formal_arg.type = type_arg.type
1633 formal_arg.name_declarator = name_declarator
1635 if cfunc_type.exception_value is None:
1636 exception_value = None
1638 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1639 declarator = CFuncDeclaratorNode(self.pos,
1640 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1642 has_varargs = False,
1643 exception_check = cfunc_type.exception_check,
1644 exception_value = exception_value,
1645 with_gil = cfunc_type.with_gil,
1646 nogil = cfunc_type.nogil)
1647 return CFuncDefNode(self.pos,
1649 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1650 declarator = declarator,
1653 overridable = cfunc_type.is_overridable,
1655 with_gil = cfunc_type.with_gil,
1656 nogil = cfunc_type.nogil,
1657 visibility = 'private',
1659 directive_locals = getattr(cfunc, 'directive_locals', {}))
1661 def analyse_declarations(self, env):
1662 directive_locals = self.directive_locals = env.directives['locals']
1663 for arg in self.args:
1664 if hasattr(arg, 'name'):
1666 name_declarator = None
1668 base_type = arg.base_type.analyse(env)
1669 name_declarator, type = \
1670 arg.declarator.analyse(base_type, env)
1671 arg.name = name_declarator.name
1672 if arg.name in directive_locals:
1673 type_node = directive_locals[arg.name]
1674 other_type = type_node.analyse_as_type(env)
1675 if other_type is None:
1676 error(type_node.pos, "Not a type")
1677 elif (type is not PyrexTypes.py_object_type
1678 and not type.same_as(other_type)):
1679 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1680 error(type_node.pos, "Previous declaration here")
1683 if name_declarator and name_declarator.cname:
1685 "Python function argument cannot have C name specification")
1686 arg.type = type.as_argument_type()
1688 arg.needs_conversion = 0
1689 arg.needs_type_test = 0
1691 if arg.not_none and not arg.type.is_extension_type:
1693 "Only extension type arguments can have 'not None'")
1694 self.declare_pyfunction(env)
1695 self.analyse_signature(env)
1696 self.return_type = self.entry.signature.return_type()
1698 def analyse_signature(self, env):
1699 any_type_tests_needed = 0
1700 if self.entry.is_special:
1701 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1702 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1703 # Use the simpler calling signature for zero- and one-argument functions.
1704 if self.entry.signature is TypeSlots.pyfunction_signature:
1705 if len(self.args) == 0:
1706 self.entry.signature = TypeSlots.pyfunction_noargs
1707 elif len(self.args) == 1:
1708 if self.args[0].default is None and not self.args[0].kw_only:
1709 self.entry.signature = TypeSlots.pyfunction_onearg
1710 elif self.entry.signature is TypeSlots.pymethod_signature:
1711 if len(self.args) == 1:
1712 self.entry.signature = TypeSlots.unaryfunc
1713 elif len(self.args) == 2:
1714 if self.args[1].default is None and not self.args[1].kw_only:
1715 self.entry.signature = TypeSlots.ibinaryfunc
1716 sig = self.entry.signature
1717 nfixed = sig.num_fixed_args()
1718 for i in range(nfixed):
1719 if i < len(self.args):
1722 if sig.is_self_arg(i):
1724 arg.hdr_type = arg.type = env.parent_type
1725 arg.needs_conversion = 0
1727 arg.hdr_type = sig.fixed_arg_type(i)
1728 if not arg.type.same_as(arg.hdr_type):
1729 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1730 arg.needs_type_test = 1
1731 any_type_tests_needed = 1
1733 arg.needs_conversion = 1
1734 if arg.needs_conversion:
1735 arg.hdr_cname = Naming.arg_prefix + arg.name
1737 arg.hdr_cname = Naming.var_prefix + arg.name
1739 self.bad_signature()
1741 if nfixed < len(self.args):
1742 if not sig.has_generic_args:
1743 self.bad_signature()
1744 for arg in self.args:
1745 if arg.is_generic and \
1746 (arg.type.is_extension_type or arg.type.is_builtin_type):
1747 arg.needs_type_test = 1
1748 any_type_tests_needed = 1
1749 if any_type_tests_needed:
1750 env.use_utility_code(arg_type_test_utility_code)
1752 def bad_signature(self):
1753 sig = self.entry.signature
1754 expected_str = "%d" % sig.num_fixed_args()
1755 if sig.has_generic_args:
1756 expected_str = expected_str + " or more"
1758 if name.startswith("__") and name.endswith("__"):
1759 desc = "Special method"
1763 "%s %s has wrong number of arguments "
1764 "(%d declared, %s expected)" % (
1765 desc, self.name, len(self.args), expected_str))
1767 def signature_has_nongeneric_args(self):
1768 argcount = len(self.args)
1769 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1773 def signature_has_generic_args(self):
1774 return self.entry.signature.has_generic_args
1776 def declare_pyfunction(self, env):
1777 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1779 entry = env.lookup_here(self.name)
1780 if entry and entry.type.is_cfunction and not self.is_wrapper:
1781 warning(self.pos, "Overriding cdef method with def method.", 5)
1782 entry = env.declare_pyfunction(self.name, self.pos)
1784 prefix = env.scope_prefix
1785 entry.func_cname = \
1786 Naming.pyfunc_prefix + prefix + name
1787 entry.pymethdef_cname = \
1788 Naming.pymethdef_prefix + prefix + name
1789 if Options.docstrings:
1790 entry.doc = embed_position(self.pos, self.doc)
1792 Naming.funcdoc_prefix + prefix + name
1796 def declare_arguments(self, env):
1797 for arg in self.args:
1799 error(arg.pos, "Missing argument name")
1800 if arg.needs_conversion:
1801 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1802 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1803 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1804 if arg.type.is_pyobject:
1805 arg.entry.init = "0"
1806 arg.entry.init_to_none = 0
1808 arg.entry = self.declare_argument(env, arg)
1810 arg.entry.is_self_arg = arg.is_self_arg
1811 if not arg.is_self_arg:
1812 arg.name_entry = env.get_string_const(
1813 arg.name, identifier = True)
1814 env.add_py_string(arg.name_entry, identifier = True)
1816 if arg.is_self_arg or \
1817 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1818 arg.entry.is_declared_generic = 1
1819 self.declare_python_arg(env, self.star_arg)
1820 self.declare_python_arg(env, self.starstar_arg)
1822 def declare_python_arg(self, env, arg):
1824 entry = env.declare_var(arg.name,
1825 PyrexTypes.py_object_type, arg.pos)
1828 entry.init_to_none = 0
1829 entry.xdecref_cleanup = 1
1831 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1833 def analyse_expressions(self, env):
1834 self.local_scope.directives = env.directives
1835 self.analyse_default_values(env)
1836 if env.is_py_class_scope:
1837 self.synthesize_assignment_node(env)
1839 def synthesize_assignment_node(self, env):
1841 self.assmt = SingleAssignmentNode(self.pos,
1842 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1843 rhs = ExprNodes.UnboundMethodNode(self.pos,
1844 class_cname = env.class_obj_cname,
1845 function = ExprNodes.PyCFunctionNode(self.pos,
1846 pymethdef_cname = self.entry.pymethdef_cname)))
1847 self.assmt.analyse_declarations(env)
1848 self.assmt.analyse_expressions(env)
1850 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1852 sig = self.entry.signature
1853 if sig.has_dummy_arg:
1854 arg_code_list.append(
1855 "PyObject *%s" % Naming.self_cname)
1856 for arg in self.args:
1857 if not arg.is_generic:
1859 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1861 arg_code_list.append(
1862 arg.hdr_type.declaration_code(arg.hdr_cname))
1863 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1864 arg_code_list.append("PyObject *unused")
1865 if sig.has_generic_args:
1866 arg_code_list.append(
1867 "PyObject *%s, PyObject *%s"
1868 % (Naming.args_cname, Naming.kwds_cname))
1869 arg_code = ", ".join(arg_code_list)
1870 dc = self.return_type.declaration_code(self.entry.func_cname)
1871 header = "static %s(%s)" % (dc, arg_code)
1872 code.putln("%s; /*proto*/" % header)
1875 if self.entry.doc and Options.docstrings:
1876 docstr = self.entry.doc
1877 if not isinstance(docstr, str):
1878 docstr = docstr.utf8encode()
1880 'static char %s[] = "%s";' % (
1881 self.entry.doc_cname,
1882 split_docstring(escape_byte_string(docstr))))
1885 "static PyMethodDef %s = " %
1886 self.entry.pymethdef_cname)
1887 code.put_pymethoddef(self.entry, ";")
1888 code.putln("%s {" % header)
1890 def generate_argument_declarations(self, env, code):
1891 for arg in self.args:
1892 if arg.is_generic: # or arg.needs_conversion:
1893 if arg.needs_conversion:
1894 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1896 code.put_var_declaration(arg.entry)
1898 def generate_keyword_list(self, code):
1899 if self.signature_has_generic_args() and \
1900 self.signature_has_nongeneric_args():
1902 "static PyObject **%s[] = {" %
1903 Naming.pykwdlist_cname)
1904 for arg in self.args:
1906 code.put('&%s,' % arg.name_entry.pystring_cname)
1909 def generate_argument_parsing_code(self, env, code):
1910 # Generate PyArg_ParseTuple call for generic
1911 # arguments, if any.
1912 if self.entry.signature.has_dummy_arg:
1913 # get rid of unused argument warning
1914 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1916 old_error_label = code.new_error_label()
1917 our_error_label = code.error_label
1918 end_label = code.new_label("argument_unpacking_done")
1920 has_kwonly_args = self.num_kwonly_args > 0
1921 has_star_or_kw_args = self.star_arg is not None \
1922 or self.starstar_arg is not None or has_kwonly_args
1924 if not self.signature_has_generic_args():
1925 if has_star_or_kw_args:
1926 error(self.pos, "This method cannot have * or keyword arguments")
1927 self.generate_argument_conversion_code(code)
1929 elif not self.signature_has_nongeneric_args():
1930 # func(*args) or func(**kw) or func(*args, **kw)
1931 self.generate_stararg_copy_code(code)
1934 positional_args = []
1937 for arg in self.args:
1938 arg_entry = arg.entry
1942 if not arg.is_self_arg:
1944 kw_only_args.append(arg)
1946 positional_args.append(arg)
1948 kw_only_args.append(arg)
1951 error(arg.pos, "Non-default argument following default argument")
1952 elif not arg.is_self_arg:
1953 positional_args.append(arg)
1954 if arg.type.from_py_function is None:
1955 arg.type.create_from_py_utility_code(env)
1957 self.generate_tuple_and_keyword_parsing_code(
1958 positional_args, kw_only_args, end_label, code)
1960 code.error_label = old_error_label
1961 if code.label_used(our_error_label):
1962 if not code.label_used(end_label):
1963 code.put_goto(end_label)
1964 code.put_label(our_error_label)
1965 if has_star_or_kw_args:
1966 self.generate_arg_decref(self.star_arg, code)
1967 if self.starstar_arg:
1968 if self.starstar_arg.entry.xdecref_cleanup:
1969 code.put_var_xdecref(self.starstar_arg.entry)
1971 code.put_var_decref(self.starstar_arg.entry)
1972 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1973 code.putln("return %s;" % self.error_value())
1974 if code.label_used(end_label):
1975 code.put_label(end_label)
1977 def generate_arg_assignment(self, arg, item, code):
1978 if arg.type.is_pyobject:
1980 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1981 code.putln("%s = %s;" % (arg.entry.cname, item))
1983 func = arg.type.from_py_function
1985 code.putln("%s = %s(%s); %s" % (
1989 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1991 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1993 def generate_arg_xdecref(self, arg, code):
1995 code.put_var_xdecref(arg.entry)
1997 def generate_arg_decref(self, arg, code):
1999 code.put_var_decref(arg.entry)
2001 def generate_stararg_copy_code(self, code):
2002 if not self.star_arg:
2003 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2004 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2006 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2007 self.name.utf8encode(), Naming.args_cname, self.error_value()))
2010 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2012 if self.starstar_arg:
2014 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2016 kwarg_check = "%s" % Naming.kwds_cname
2018 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2019 Naming.kwds_cname, Naming.kwds_cname)
2021 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2022 kwarg_check, Naming.kwds_cname, self.name,
2023 bool(self.starstar_arg), self.error_value()))
2025 if self.starstar_arg:
2026 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2027 self.starstar_arg.entry.cname,
2030 code.putln("if (unlikely(!%s)) return %s;" % (
2031 self.starstar_arg.entry.cname, self.error_value()))
2032 self.starstar_arg.entry.xdecref_cleanup = 0
2033 code.put_gotref(self.starstar_arg.entry.cname)
2037 code.put_incref(Naming.args_cname, py_object_type)
2038 code.putln("%s = %s;" % (
2039 self.star_arg.entry.cname,
2041 self.star_arg.entry.xdecref_cleanup = 0
2043 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2044 kw_only_args, success_label, code):
2045 argtuple_error_label = code.new_label("argtuple_error")
2047 min_positional_args = self.num_required_args - self.num_required_kw_args
2048 if len(self.args) > 0 and self.args[0].is_self_arg:
2049 min_positional_args -= 1
2050 max_positional_args = len(positional_args)
2051 has_fixed_positional_count = not self.star_arg and \
2052 min_positional_args == max_positional_args
2054 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2055 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2056 if self.num_required_kw_args:
2057 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2059 if self.starstar_arg or self.star_arg:
2060 self.generate_stararg_init_code(max_positional_args, code)
2062 # --- optimised code when we receive keyword arguments
2063 if self.num_required_kw_args:
2064 likely_hint = "likely"
2066 likely_hint = "unlikely"
2067 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2068 self.generate_keyword_unpacking_code(
2069 min_positional_args, max_positional_args,
2070 has_fixed_positional_count,
2071 positional_args, kw_only_args, argtuple_error_label, code)
2073 # --- optimised code when we do not receive any keyword arguments
2074 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2075 # Python raises arg tuple related errors first, so we must
2076 # check the length here
2077 if min_positional_args == max_positional_args and not self.star_arg:
2081 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2082 Naming.args_cname, compare, min_positional_args))
2083 code.put_goto(argtuple_error_label)
2085 if self.num_required_kw_args:
2086 # pure error case: keywords required but not passed
2087 if max_positional_args > min_positional_args and not self.star_arg:
2088 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2089 Naming.args_cname, max_positional_args))
2090 code.put_goto(argtuple_error_label)
2091 code.putln('} else {')
2092 for i, arg in enumerate(kw_only_args):
2094 # required keyword-only argument missing
2095 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2096 self.name.utf8encode(),
2097 arg.name_entry.pystring_cname))
2098 code.putln(code.error_goto(self.pos))
2101 elif min_positional_args == max_positional_args:
2102 # parse the exact number of positional arguments from the
2104 code.putln('} else {')
2105 for i, arg in enumerate(positional_args):
2106 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2107 self.generate_arg_assignment(arg, item, code)
2108 self.generate_arg_default_assignments(code)
2111 # parse the positional arguments from the variable length
2113 code.putln('} else {')
2114 self.generate_arg_default_assignments(code)
2115 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2117 code.putln('default:')
2118 reversed_args = list(enumerate(positional_args))[::-1]
2119 for i, arg in reversed_args:
2120 if i >= min_positional_args-1:
2121 if min_positional_args > 1:
2122 code.putln('case %2d:' % (i+1)) # pure code beautification
2124 code.put('case %2d: ' % (i+1))
2125 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2126 self.generate_arg_assignment(arg, item, code)
2127 if min_positional_args == 0:
2128 code.put('case 0: ')
2129 code.putln('break;')
2131 if min_positional_args:
2132 for i in range(min_positional_args-1, -1, -1):
2133 code.putln('case %2d:' % i)
2134 code.put_goto(argtuple_error_label)
2136 code.put('default: ')
2137 code.put_goto(argtuple_error_label)
2142 if code.label_used(argtuple_error_label):
2143 code.put_goto(success_label)
2144 code.put_label(argtuple_error_label)
2145 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2146 self.name.utf8encode(), has_fixed_positional_count,
2147 min_positional_args, max_positional_args,
2149 code.putln(code.error_goto(self.pos))
2151 def generate_arg_default_assignments(self, code):
2152 for arg in self.args:
2153 if arg.is_generic and arg.default:
2157 arg.default_result_code))
2159 def generate_stararg_init_code(self, max_positional_args, code):
2160 if self.starstar_arg:
2161 self.starstar_arg.entry.xdecref_cleanup = 0
2162 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2163 self.starstar_arg.entry.cname,
2164 self.starstar_arg.entry.cname,
2165 self.error_value()))
2166 code.put_gotref(self.starstar_arg.entry.cname)
2168 self.star_arg.entry.xdecref_cleanup = 0
2169 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2171 max_positional_args))
2172 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2173 self.star_arg.entry.cname, Naming.args_cname,
2174 max_positional_args, Naming.args_cname))
2175 code.put_gotref(self.star_arg.entry.cname)
2176 if self.starstar_arg:
2178 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2179 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2180 code.putln('return %s;' % self.error_value())
2183 code.putln("if (unlikely(!%s)) return %s;" % (
2184 self.star_arg.entry.cname, self.error_value()))
2185 code.putln('} else {')
2186 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2187 code.put_incref(Naming.empty_tuple, py_object_type)
2190 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2191 has_fixed_positional_count, positional_args,
2192 kw_only_args, argtuple_error_label, code):
2193 all_args = tuple(positional_args) + tuple(kw_only_args)
2194 max_args = len(all_args)
2197 for i, arg in enumerate(all_args):
2198 if arg.default and arg.type.is_pyobject:
2199 default_value = arg.default_result_code
2200 if arg.type is not PyrexTypes.py_object_type:
2201 default_value = "(PyObject*)"+default_value
2202 default_args.append((i, default_value))
2204 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2206 # it looks funny to separate the init-to-0 from setting the
2207 # default value, but C89 needs this
2208 code.putln("PyObject* values[%d] = {%s};" % (
2209 max_args, ','.join(['0']*max_args)))
2210 for i, default_value in default_args:
2211 code.putln('values[%d] = %s;' % (i, default_value))
2213 # parse the tuple and check that it's not too long
2214 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2216 code.putln('default:')
2217 for i in range(max_positional_args-1, -1, -1):
2218 code.put('case %2d: ' % (i+1))
2219 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2220 i, Naming.args_cname, i))
2221 code.putln('case 0: break;')
2222 if not self.star_arg:
2223 code.put('default: ') # more arguments than allowed
2224 code.put_goto(argtuple_error_label)
2227 # now fill up the positional/required arguments with values
2229 if self.num_required_args or max_positional_args > 0:
2230 last_required_arg = -1
2231 for i, arg in enumerate(all_args):
2233 last_required_arg = i
2234 if last_required_arg < max_positional_args:
2235 last_required_arg = max_positional_args-1
2236 num_required_args = self.num_required_args
2237 if max_positional_args > 0:
2238 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2239 for i, arg in enumerate(all_args[:last_required_arg+1]):
2240 if max_positional_args > 0 and i <= max_positional_args:
2241 if self.star_arg and i == max_positional_args:
2242 code.putln('default:')
2244 code.putln('case %2d:' % i)
2247 # handled separately below
2249 code.putln('if (kw_args > %d) {' % num_required_args)
2250 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2251 Naming.kwds_cname, arg.name_entry.pystring_cname))
2252 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2255 num_required_args -= 1
2256 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2257 i, Naming.kwds_cname, arg.name_entry.pystring_cname))
2258 code.putln('if (likely(values[%d])) kw_args--;' % i);
2259 if i < min_positional_args:
2261 # special case: we know arg 0 is missing
2263 code.put_goto(argtuple_error_label)
2265 # print the correct number of values (args or
2266 # kwargs) that were passed into positional
2267 # arguments up to this point
2268 code.putln('else {')
2269 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2270 self.name.utf8encode(), has_fixed_positional_count,
2271 min_positional_args, max_positional_args, i))
2272 code.putln(code.error_goto(self.pos))
2275 code.putln('else {')
2276 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2277 self.name.utf8encode(), arg.name_entry.pystring_cname))
2278 code.putln(code.error_goto(self.pos))
2280 if max_positional_args > 0:
2283 if kw_only_args and not self.starstar_arg:
2284 # unpack optional keyword-only arguments
2285 # checking for interned strings in a dict is faster than iterating
2286 # but it's too likely that we must iterate if we expect **kwargs
2288 for i, arg in enumerate(all_args[max_positional_args:]):
2289 if not arg.kw_only or not arg.default:
2291 optional_args.append((i+max_positional_args, arg))
2293 # this mimics an unrolled loop so that we can "break" out of it
2294 code.putln('while (kw_args > 0) {')
2295 code.putln('PyObject* value;')
2296 for i, arg in optional_args:
2298 'value = PyDict_GetItem(%s, %s);' % (
2299 Naming.kwds_cname, arg.name_entry.pystring_cname))
2301 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2302 code.putln('break;')
2305 code.putln('if (unlikely(kw_args > 0)) {')
2306 # non-positional/-required kw args left in dict: default args,
2307 # kw-only args, **kwargs or error
2309 # This is sort of a catch-all: except for checking required
2310 # arguments, this will always do the right thing for unpacking
2311 # keyword arguments, so that we can concentrate on optimising
2312 # common cases above.
2313 if max_positional_args == 0:
2316 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2317 Naming.args_cname, max_positional_args,
2318 Naming.args_cname, max_positional_args))
2319 pos_arg_count = "used_pos_args"
2321 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2322 code.globalstate.use_utility_code(parse_keywords_utility_code)
2324 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2326 Naming.pykwdlist_cname,
2327 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2329 self.name.utf8encode()))
2330 code.putln(code.error_goto(self.pos))
2333 # convert arg values to their final type and assign them
2334 for i, arg in enumerate(all_args):
2335 if arg.default and not arg.type.is_pyobject:
2336 code.putln("if (values[%d]) {" % i)
2337 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2338 if arg.default and not arg.type.is_pyobject:
2339 code.putln('} else {')
2343 arg.default_result_code))
2346 def generate_argument_conversion_code(self, code):
2347 # Generate code to convert arguments from
2348 # signature type to declared type, if needed.
2349 for arg in self.args:
2350 if arg.needs_conversion:
2351 self.generate_arg_conversion(arg, code)
2353 def generate_arg_conversion(self, arg, code):
2354 # Generate conversion code for one argument.
2355 old_type = arg.hdr_type
2357 if old_type.is_pyobject:
2359 code.putln("if (%s) {" % arg.hdr_cname)
2361 code.putln("assert(%s); {" % arg.hdr_cname)
2362 self.generate_arg_conversion_from_pyobject(arg, code)
2364 elif new_type.is_pyobject:
2365 self.generate_arg_conversion_to_pyobject(arg, code)
2367 if new_type.assignable_from(old_type):
2369 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2372 "Cannot convert 1 argument from '%s' to '%s'" %
2373 (old_type, new_type))
2375 def generate_arg_conversion_from_pyobject(self, arg, code):
2377 func = new_type.from_py_function
2378 # copied from CoerceFromPyTypeNode
2380 code.putln("%s = %s(%s); %s" % (
2384 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2387 "Cannot convert Python object argument to type '%s'"
2390 def generate_arg_conversion_to_pyobject(self, arg, code):
2391 old_type = arg.hdr_type
2392 func = old_type.to_py_function
2394 code.putln("%s = %s(%s); %s" % (
2398 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2399 code.put_var_gotref(arg.entry)
2402 "Cannot convert argument of type '%s' to Python object"
2405 def generate_argument_type_tests(self, code):
2406 # Generate type tests for args whose signature
2407 # type is PyObject * and whose declared type is
2408 # a subtype thereof.
2409 for arg in self.args:
2410 if arg.needs_type_test:
2411 self.generate_arg_type_test(arg, code)
2413 def generate_arg_type_test(self, arg, code):
2414 # Generate type test for one argument.
2415 if arg.type.typeobj_is_available():
2416 typeptr_cname = arg.type.typeptr_cname
2417 arg_code = "((PyObject *)%s)" % arg.entry.cname
2419 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2424 arg.type.is_builtin_type,
2425 code.error_goto(arg.pos)))
2427 error(arg.pos, "Cannot test type of extern C class "
2428 "without type object name specification")
2430 def error_value(self):
2431 return self.entry.signature.error_value
2433 def caller_will_check_exceptions(self):
2436 class OverrideCheckNode(StatNode):
2437 # A Node for dispatching to the def method if it
2446 child_attrs = ['body']
2450 def analyse_expressions(self, env):
2451 self.args = env.arg_entries
2452 if self.py_func.is_module_scope:
2457 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2458 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2459 call_node = ExprNodes.SimpleCallNode(self.pos,
2460 function=self.func_node,
2461 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2462 self.body = ReturnStatNode(self.pos, value=call_node)
2463 self.body.analyse_expressions(env)
2465 def generate_execution_code(self, code):
2466 # Check to see if we are an extension type
2467 if self.py_func.is_module_scope:
2468 self_arg = "((PyObject *)%s)" % Naming.module_cname
2470 self_arg = "((PyObject *)%s)" % self.args[0].cname
2471 code.putln("/* Check if called by wrapper */")
2472 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2473 code.putln("/* Check if overriden in Python */")
2474 if self.py_func.is_module_scope:
2475 code.putln("else {")
2477 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2478 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2479 # need to get attribute manually--scope would return cdef method
2480 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result(), self_arg, self.py_func.interned_attr_cname, err))
2481 code.put_gotref(self.func_node.py_result())
2482 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2483 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result(), self.py_func.entry.func_cname)
2484 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2485 self.body.generate_execution_code(code)
2487 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2490 class ClassDefNode(StatNode, BlockNode):
2493 class PyClassDefNode(ClassDefNode):
2494 # A Python class definition.
2496 # name EncodedString Name of the class
2497 # doc string or None
2498 # body StatNode Attribute definition code
2499 # entry Symtab.Entry
2500 # scope PyClassScope
2502 # The following subnodes are constructed internally:
2504 # dict DictNode Class dictionary
2505 # classobj ClassNode Class object
2506 # target NameNode Variable to assign class object to
2508 child_attrs = ["body", "dict", "classobj", "target"]
2510 def __init__(self, pos, name, bases, doc, body):
2511 StatNode.__init__(self, pos)
2516 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2517 if self.doc and Options.docstrings:
2518 doc = embed_position(self.pos, self.doc)
2519 doc_node = ExprNodes.StringNode(pos, value = doc)
2522 self.classobj = ExprNodes.ClassNode(pos, name = name,
2523 bases = bases, dict = self.dict, doc = doc_node)
2524 self.target = ExprNodes.NameNode(pos, name = name)
2526 def as_cclass(self):
2528 Return this node as if it were declared as an extension class
2530 bases = self.classobj.bases.args
2532 base_class_name = None
2533 base_class_module = None
2534 elif len(bases) == 1:
2537 from ExprNodes import AttributeNode, NameNode
2538 while isinstance(base, AttributeNode):
2539 path.insert(0, base.attribute)
2541 if isinstance(base, NameNode):
2542 path.insert(0, base.name)
2543 base_class_name = path[-1]
2545 base_class_module = u'.'.join(path[:-1])
2547 base_class_module = None
2549 error(self.classobj.bases.args.pos, "Invalid base class")
2551 error(self.classobj.bases.args.pos, "C class may only have one base class")
2554 return CClassDefNode(self.pos,
2555 visibility = 'private',
2557 class_name = self.name,
2558 base_class_module = base_class_module,
2559 base_class_name = base_class_name,
2564 def create_scope(self, env):
2566 while env.is_py_class_scope or env.is_c_class_scope:
2567 env = env.outer_scope
2568 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2571 def analyse_declarations(self, env):
2572 self.target.analyse_target_declaration(env)
2573 cenv = self.create_scope(env)
2574 cenv.directives = env.directives
2575 cenv.class_obj_cname = self.target.entry.cname
2576 self.body.analyse_declarations(cenv)
2578 def analyse_expressions(self, env):
2579 self.dict.analyse_expressions(env)
2580 self.classobj.analyse_expressions(env)
2581 genv = env.global_scope()
2583 cenv.class_dict_cname = self.dict.result()
2584 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2585 self.body.analyse_expressions(cenv)
2586 self.target.analyse_target_expression(env, self.classobj)
2587 self.dict.release_temp(env)
2588 #self.classobj.release_temp(env)
2589 #self.target.release_target_temp(env)
2591 def generate_function_definitions(self, env, code):
2592 self.generate_py_string_decls(self.scope, code)
2593 self.body.generate_function_definitions(self.scope, code)
2595 def generate_execution_code(self, code):
2596 self.dict.generate_evaluation_code(code)
2597 self.classobj.generate_evaluation_code(code)
2598 self.body.generate_execution_code(code)
2599 self.target.generate_assignment_code(self.classobj, code)
2600 self.dict.generate_disposal_code(code)
2601 self.dict.free_temps(code)
2604 class CClassDefNode(ClassDefNode):
2605 # An extension type definition.
2607 # visibility 'private' or 'public' or 'extern'
2608 # typedef_flag boolean
2610 # module_name string or None For import of extern type objects
2611 # class_name string Unqualified name of class
2612 # as_name string or None Name to declare as in this scope
2613 # base_class_module string or None Module containing the base class
2614 # base_class_name string or None Name of the base class
2615 # objstruct_name string or None Specified C name of object struct
2616 # typeobj_name string or None Specified C name of type object
2617 # in_pxd boolean Is in a .pxd file
2618 # doc string or None
2619 # body StatNode or None
2620 # entry Symtab.Entry
2621 # base_type PyExtensionType or None
2622 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2623 # buffer_defaults_pos
2625 child_attrs = ["body"]
2626 buffer_defaults_node = None
2627 buffer_defaults_pos = None
2628 typedef_flag = False
2630 objstruct_name = None
2633 def analyse_declarations(self, env):
2634 #print "CClassDefNode.analyse_declarations:", self.class_name
2635 #print "...visibility =", self.visibility
2636 #print "...module_name =", self.module_name
2639 if self.buffer_defaults_node:
2640 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2641 env, [], self.buffer_defaults_node,
2642 need_complete=False)
2644 buffer_defaults = None
2646 if env.in_cinclude and not self.objstruct_name:
2647 error(self.pos, "Object struct name specification required for "
2648 "C class defined in 'extern from' block")
2649 self.base_type = None
2650 # Now that module imports are cached, we need to
2651 # import the modules for extern classes.
2652 if self.module_name:
2654 for module in env.cimported_modules:
2655 if module.name == self.module_name:
2656 self.module = module
2657 if self.module is None:
2658 self.module = ModuleScope(self.module_name, None, env.context)
2659 self.module.has_extern_class = 1
2660 env.add_imported_module(self.module)
2662 if self.base_class_name:
2663 if self.base_class_module:
2664 base_class_scope = env.find_module(self.base_class_module, self.pos)
2666 base_class_scope = env
2667 if self.base_class_name == 'object':
2668 # extension classes are special and don't need to inherit from object
2669 if base_class_scope is None or base_class_scope.lookup('object') is None:
2670 self.base_class_name = None
2671 self.base_class_module = None
2672 base_class_scope = None
2673 if base_class_scope:
2674 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2675 if base_class_entry:
2676 if not base_class_entry.is_type:
2677 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2678 elif not base_class_entry.type.is_extension_type:
2679 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2680 elif not base_class_entry.type.is_complete():
2681 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2683 self.base_type = base_class_entry.type
2684 has_body = self.body is not None
2685 if self.module_name and self.visibility != 'extern':
2686 module_path = self.module_name.split(".")
2687 home_scope = env.find_imported_module(module_path, self.pos)
2693 if self.visibility == 'extern':
2694 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2695 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2697 self.entry = home_scope.declare_c_class(
2698 name = self.class_name,
2700 defining = has_body and self.in_pxd,
2701 implementing = has_body and not self.in_pxd,
2702 module_name = self.module_name,
2703 base_type = self.base_type,
2704 objstruct_cname = self.objstruct_name,
2705 typeobj_cname = self.typeobj_name,
2706 visibility = self.visibility,
2707 typedef_flag = self.typedef_flag,
2709 buffer_defaults = buffer_defaults)
2710 if home_scope is not env and self.visibility == 'extern':
2711 env.add_imported_entry(self.class_name, self.entry, pos)
2712 scope = self.entry.type.scope
2713 if scope is not None:
2714 scope.directives = env.directives
2716 if self.doc and Options.docstrings:
2717 scope.doc = embed_position(self.pos, self.doc)
2720 self.body.analyse_declarations(scope)
2724 scope.implemented = 1
2725 env.allocate_vtable_names(self.entry)
2727 def analyse_expressions(self, env):
2729 scope = self.entry.type.scope
2730 self.body.analyse_expressions(scope)
2732 def generate_function_definitions(self, env, code):
2733 self.generate_py_string_decls(self.entry.type.scope, code)
2735 self.body.generate_function_definitions(
2736 self.entry.type.scope, code)
2738 def generate_execution_code(self, code):
2739 # This is needed to generate evaluation code for
2740 # default values of method arguments.
2742 self.body.generate_execution_code(code)
2744 def annotate(self, code):
2746 self.body.annotate(code)
2749 class PropertyNode(StatNode):
2750 # Definition of a property in an extension type.
2753 # doc EncodedString or None Doc string
2756 child_attrs = ["body"]
2758 def analyse_declarations(self, env):
2759 entry = env.declare_property(self.name, self.doc, self.pos)
2761 if self.doc and Options.docstrings:
2762 doc_entry = env.get_string_const(
2763 self.doc, identifier = False)
2764 entry.doc_cname = doc_entry.cname
2765 entry.scope.directives = env.directives
2766 self.body.analyse_declarations(entry.scope)
2768 def analyse_expressions(self, env):
2769 self.body.analyse_expressions(env)
2771 def generate_function_definitions(self, env, code):
2772 self.body.generate_function_definitions(env, code)
2774 def generate_execution_code(self, code):
2777 def annotate(self, code):
2778 self.body.annotate(code)
2781 class GlobalNode(StatNode):
2782 # Global variable declaration.
2788 def analyse_declarations(self, env):
2789 for name in self.names:
2790 env.declare_global(name, self.pos)
2792 def analyse_expressions(self, env):
2795 def generate_execution_code(self, code):
2799 class ExprStatNode(StatNode):
2800 # Expression used as a statement.
2804 child_attrs = ["expr"]
2806 def analyse_declarations(self, env):
2808 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2809 func = self.expr.function.as_cython_attribute()
2810 if func == u'declare':
2811 args, kwds = self.expr.explicit_args_kwds()
2813 error(self.expr.pos, "Variable names must be specified.")
2814 for var, type_node in kwds.key_value_pairs:
2815 type = type_node.analyse_as_type(env)
2817 error(type_node.pos, "Unknown type")
2819 env.declare_var(var.value, type, var.pos, is_cdef = True)
2820 self.__class__ = PassStatNode
2822 def analyse_expressions(self, env):
2823 self.expr.analyse_expressions(env)
2824 self.expr.release_temp(env)
2826 def generate_execution_code(self, code):
2827 self.expr.generate_evaluation_code(code)
2828 if not self.expr.is_temp and self.expr.result():
2829 code.putln("%s;" % self.expr.result())
2830 self.expr.generate_disposal_code(code)
2831 self.expr.free_temps(code)
2833 def annotate(self, code):
2834 self.expr.annotate(code)
2837 class AssignmentNode(StatNode):
2838 # Abstract base class for assignment nodes.
2840 # The analyse_expressions and generate_execution_code
2841 # phases of assignments are split into two sub-phases
2842 # each, to enable all the right hand sides of a
2843 # parallel assignment to be evaluated before assigning
2844 # to any of the left hand sides.
2846 def analyse_expressions(self, env):
2847 self.analyse_types(env)
2848 self.allocate_rhs_temps(env)
2849 self.allocate_lhs_temps(env)
2851 # def analyse_expressions(self, env):
2852 # self.analyse_expressions_1(env)
2853 # self.analyse_expressions_2(env)
2855 def generate_execution_code(self, code):
2856 self.generate_rhs_evaluation_code(code)
2857 self.generate_assignment_code(code)
2860 class SingleAssignmentNode(AssignmentNode):
2861 # The simplest case:
2865 # lhs ExprNode Left hand side
2866 # rhs ExprNode Right hand side
2867 # first bool Is this guaranteed the first assignment to lhs?
2869 child_attrs = ["lhs", "rhs"]
2871 declaration_only = False
2873 def analyse_declarations(self, env):
2876 # handle declarations of the form x = cython.foo()
2877 if isinstance(self.rhs, ExprNodes.CallNode):
2878 func_name = self.rhs.function.as_cython_attribute()
2880 args, kwds = self.rhs.explicit_args_kwds()
2882 if func_name in ['declare', 'typedef']:
2883 if len(args) > 2 or kwds is not None:
2884 error(rhs.pos, "Can only declare one type at a time.")
2886 type = args[0].analyse_as_type(env)
2888 error(args[0].pos, "Unknown type")
2891 if func_name == 'declare':
2892 if isinstance(lhs, ExprNodes.NameNode):
2893 vars = [(lhs.name, lhs.pos)]
2894 elif isinstance(lhs, ExprNodes.TupleNode):
2895 vars = [(var.name, var.pos) for var in lhs.args]
2897 error(lhs.pos, "Invalid declaration")
2899 for var, pos in vars:
2900 env.declare_var(var, type, pos, is_cdef = True)
2905 self.declaration_only = True
2907 self.declaration_only = True
2908 if not isinstance(lhs, ExprNodes.NameNode):
2909 error(lhs.pos, "Invalid declaration.")
2910 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2912 elif func_name in ['struct', 'union']:
2913 self.declaration_only = True
2914 if len(args) > 0 or kwds is None:
2915 error(rhs.pos, "Struct or union members must be given by name.")
2918 for member, type_node in kwds.key_value_pairs:
2919 type = type_node.analyse_as_type(env)
2921 error(type_node.pos, "Unknown type")
2923 members.append((member.value, type, member.pos))
2924 if len(members) < len(kwds.key_value_pairs):
2926 if not isinstance(self.lhs, ExprNodes.NameNode):
2927 error(self.lhs.pos, "Invalid declaration.")
2928 name = self.lhs.name
2929 scope = StructOrUnionScope(name)
2930 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2931 for member, type, pos in members:
2932 scope.declare_var(member, type, pos)
2934 if self.declaration_only:
2937 self.lhs.analyse_target_declaration(env)
2939 def analyse_types(self, env, use_temp = 0):
2940 self.rhs.analyse_types(env)
2941 self.lhs.analyse_target_types(env)
2942 self.lhs.gil_assignment_check(env)
2943 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2945 self.rhs = self.rhs.coerce_to_temp(env)
2947 def allocate_rhs_temps(self, env):
2948 self.rhs.allocate_temps(env)
2950 def allocate_lhs_temps(self, env):
2951 self.lhs.allocate_target_temps(env, self.rhs)
2952 #self.lhs.release_target_temp(env)
2953 #self.rhs.release_temp(env)
2955 def generate_rhs_evaluation_code(self, code):
2956 self.rhs.generate_evaluation_code(code)
2958 def generate_assignment_code(self, code):
2959 self.lhs.generate_assignment_code(self.rhs, code)
2961 def annotate(self, code):
2962 self.lhs.annotate(code)
2963 self.rhs.annotate(code)
2966 class CascadedAssignmentNode(AssignmentNode):
2967 # An assignment with multiple left hand sides:
2971 # lhs_list [ExprNode] Left hand sides
2972 # rhs ExprNode Right hand sides
2976 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2978 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2979 coerced_rhs_list = None
2981 def analyse_declarations(self, env):
2982 for lhs in self.lhs_list:
2983 lhs.analyse_target_declaration(env)
2985 def analyse_types(self, env, use_temp = 0):
2986 self.rhs.analyse_types(env)
2988 self.rhs = self.rhs.coerce_to_temp(env)
2990 self.rhs = self.rhs.coerce_to_simple(env)
2991 from ExprNodes import CloneNode
2992 self.coerced_rhs_list = []
2993 for lhs in self.lhs_list:
2994 lhs.analyse_target_types(env)
2995 lhs.gil_assignment_check(env)
2996 rhs = CloneNode(self.rhs)
2997 rhs = rhs.coerce_to(lhs.type, env)
2998 self.coerced_rhs_list.append(rhs)
3000 def allocate_rhs_temps(self, env):
3001 self.rhs.allocate_temps(env)
3003 def allocate_lhs_temps(self, env):
3004 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
3005 rhs.allocate_temps(env)
3006 lhs.allocate_target_temps(env, rhs)
3007 #lhs.release_target_temp(env)
3008 #rhs.release_temp(env)
3009 self.rhs.release_temp(env)
3011 def generate_rhs_evaluation_code(self, code):
3012 self.rhs.generate_evaluation_code(code)
3014 def generate_assignment_code(self, code):
3015 for i in range(len(self.lhs_list)):
3016 lhs = self.lhs_list[i]
3017 rhs = self.coerced_rhs_list[i]
3018 rhs.generate_evaluation_code(code)
3019 lhs.generate_assignment_code(rhs, code)
3020 # Assignment has disposed of the cloned RHS
3021 self.rhs.generate_disposal_code(code)
3022 self.rhs.free_temps(code)
3024 def annotate(self, code):
3025 for i in range(len(self.lhs_list)):
3026 lhs = self.lhs_list[i].annotate(code)
3027 rhs = self.coerced_rhs_list[i].annotate(code)
3028 self.rhs.annotate(code)
3031 class ParallelAssignmentNode(AssignmentNode):
3032 # A combined packing/unpacking assignment:
3036 # This has been rearranged by the parser into
3038 # a = d ; b = e ; c = f
3040 # but we must evaluate all the right hand sides
3041 # before assigning to any of the left hand sides.
3043 # stats [AssignmentNode] The constituent assignments
3045 child_attrs = ["stats"]
3047 def analyse_declarations(self, env):
3048 for stat in self.stats:
3049 stat.analyse_declarations(env)
3051 def analyse_expressions(self, env):
3052 for stat in self.stats:
3053 stat.analyse_types(env, use_temp = 1)
3054 stat.allocate_rhs_temps(env)
3055 for stat in self.stats:
3056 stat.allocate_lhs_temps(env)
3058 # def analyse_expressions(self, env):
3059 # for stat in self.stats:
3060 # stat.analyse_expressions_1(env, use_temp = 1)
3061 # for stat in self.stats:
3062 # stat.analyse_expressions_2(env)
3064 def generate_execution_code(self, code):
3065 for stat in self.stats:
3066 stat.generate_rhs_evaluation_code(code)
3067 for stat in self.stats:
3068 stat.generate_assignment_code(code)
3070 def annotate(self, code):
3071 for stat in self.stats:
3075 class InPlaceAssignmentNode(AssignmentNode):
3076 # An in place arithmatic operand:
3082 # lhs ExprNode Left hand side
3083 # rhs ExprNode Right hand side
3084 # op char one of "+-*/%^&|"
3085 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3087 # This code is a bit tricky because in order to obey Python
3088 # semantics the sub-expressions (e.g. indices) of the lhs must
3089 # not be evaluated twice. So we must re-use the values calculated
3090 # in evaluation phase for the assignment phase as well.
3091 # Fortunately, the type of the lhs node is fairly constrained
3092 # (it must be a NameNode, AttributeNode, or IndexNode).
3094 child_attrs = ["lhs", "rhs"]
3097 def analyse_declarations(self, env):
3098 self.lhs.analyse_target_declaration(env)
3100 def analyse_types(self, env):
3101 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3102 self.rhs.analyse_types(env)
3103 self.lhs.analyse_target_types(env)
3104 if Options.incref_local_binop and self.dup.type.is_pyobject:
3105 self.dup = self.dup.coerce_to_temp(env)
3107 def allocate_rhs_temps(self, env):
3109 if self.lhs.type.is_pyobject:
3110 self.rhs = self.rhs.coerce_to_pyobject(env)
3111 elif self.rhs.type.is_pyobject:
3112 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3113 if self.lhs.type.is_pyobject:
3114 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3115 self.result_value.allocate_temps(env)
3117 # self.rhs = self.rhs.coerce_to_temp(env)
3118 self.rhs.allocate_temps(env)
3119 self.dup.allocate_subexpr_temps(env)
3120 self.dup.allocate_temp(env)
3122 def allocate_lhs_temps(self, env):
3123 self.lhs.allocate_target_temps(env, self.rhs)
3124 # self.lhs.release_target_temp(env)
3125 self.dup.release_temp(env)
3126 if self.dup.is_temp:
3127 self.dup.release_subexpr_temps(env)
3128 # self.rhs.release_temp(env)
3129 if self.lhs.type.is_pyobject:
3130 self.result_value.release_temp(env)
3132 def generate_execution_code(self, code):
3134 self.rhs.generate_evaluation_code(code)
3135 self.dup.generate_subexpr_evaluation_code(code)
3136 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3137 # This is because we're manually messing with subexpr nodes
3138 if self.dup.is_temp:
3139 self.dup.allocate_temp_result(code)
3140 # self.dup.generate_result_code is run only if it is not buffer access
3141 if self.operator == "**":
3145 if self.lhs.type.is_pyobject:
3146 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3147 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3148 self.dup.generate_result_code(code)
3150 "%s = %s(%s, %s%s); %s" % (
3151 self.result_value.result(),
3152 self.py_operation_function(),
3153 self.dup.py_result(),
3154 self.rhs.py_result(),
3156 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3157 code.put_gotref(self.result_value.py_result())
3158 self.result_value.generate_evaluation_code(code) # May be a type check...
3159 self.rhs.generate_disposal_code(code)
3160 self.rhs.free_temps(code)
3161 self.dup.generate_disposal_code(code)
3162 self.dup.free_temps(code)
3163 self.lhs.generate_assignment_code(self.result_value, code)
3165 c_op = self.operator
3169 error(self.pos, "No C inplace power operator")
3170 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3171 error(self.pos, "Inplace operators not implemented for complex types.")
3173 # have to do assignment directly to avoid side-effects
3174 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3175 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3177 self.dup.generate_result_code(code)
3178 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3179 self.rhs.generate_disposal_code(code)
3180 self.rhs.free_temps(code)
3181 if self.dup.is_temp:
3182 self.dup.generate_subexpr_disposal_code(code)
3183 self.dup.free_subexpr_temps(code)
3185 def create_dup_node(self, env):
3188 self.dup.analyse_types(env)
3189 if isinstance(self.lhs, ExprNodes.NameNode):
3190 target_lhs = ExprNodes.NameNode(self.dup.pos,
3191 name = self.dup.name,
3192 is_temp = self.dup.is_temp,
3193 entry = self.dup.entry)
3194 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3195 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3196 obj = ExprNodes.CloneNode(self.lhs.obj),
3197 attribute = self.dup.attribute,
3198 is_temp = self.dup.is_temp)
3199 elif isinstance(self.lhs, ExprNodes.IndexNode):
3201 index = ExprNodes.CloneNode(self.lhs.index)
3204 if self.lhs.indices:
3205 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3208 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3209 base = ExprNodes.CloneNode(self.dup.base),
3212 is_temp = self.dup.is_temp)
3215 self.lhs = target_lhs
3218 def py_operation_function(self):
3219 return self.py_functions[self.operator]
3222 "|": "PyNumber_InPlaceOr",
3223 "^": "PyNumber_InPlaceXor",
3224 "&": "PyNumber_InPlaceAnd",
3225 "+": "PyNumber_InPlaceAdd",
3226 "-": "PyNumber_InPlaceSubtract",
3227 "*": "PyNumber_InPlaceMultiply",
3228 "/": "PyNumber_InPlaceDivide",
3229 "%": "PyNumber_InPlaceRemainder",
3230 "<<": "PyNumber_InPlaceLshift",
3231 ">>": "PyNumber_InPlaceRshift",
3232 "**": "PyNumber_InPlacePower",
3233 "//": "PyNumber_InPlaceFloorDivide",
3236 def annotate(self, code):
3237 self.lhs.annotate(code)
3238 self.rhs.annotate(code)
3239 self.dup.annotate(code)
3242 class PrintStatNode(StatNode):
3245 # arg_tuple TupleNode
3246 # append_newline boolean
3248 child_attrs = ["arg_tuple"]
3250 def analyse_expressions(self, env):
3251 self.arg_tuple.analyse_expressions(env)
3252 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3253 self.arg_tuple.release_temp(env)
3254 env.use_utility_code(printing_utility_code)
3255 if len(self.arg_tuple.args) == 1 and self.append_newline:
3256 env.use_utility_code(printing_one_utility_code)
3259 gil_message = "Python print statement"
3261 def generate_execution_code(self, code):
3262 if len(self.arg_tuple.args) == 1 and self.append_newline:
3263 arg = self.arg_tuple.args[0]
3264 arg.generate_evaluation_code(code)
3267 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3269 code.error_goto(self.pos)))
3270 arg.generate_disposal_code(code)
3271 arg.free_temps(code)
3273 self.arg_tuple.generate_evaluation_code(code)
3275 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3276 self.arg_tuple.py_result(),
3277 self.append_newline,
3278 code.error_goto(self.pos)))
3279 self.arg_tuple.generate_disposal_code(code)
3280 self.arg_tuple.free_temps(code)
3282 def annotate(self, code):
3283 self.arg_tuple.annotate(code)
3286 class ExecStatNode(StatNode):
3291 child_attrs = ["args"]
3293 def analyse_expressions(self, env):
3294 for i, arg in enumerate(self.args):
3295 arg.analyse_expressions(env)
3296 arg = arg.coerce_to_pyobject(env)
3297 arg.release_temp(env)
3299 self.temp_result = env.allocate_temp_pyobject()
3300 env.release_temp(self.temp_result)
3301 env.use_utility_code(Builtin.pyexec_utility_code)
3304 gil_message = "Python exec statement"
3306 def generate_execution_code(self, code):
3308 for arg in self.args:
3309 arg.generate_evaluation_code(code)
3310 args.append( arg.py_result() )
3311 args = tuple(args + ['0', '0'][:3-len(args)])
3312 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3313 (self.temp_result,) + args))
3314 for arg in self.args:
3315 arg.generate_disposal_code(code)
3316 arg.free_temps(code)
3318 code.error_goto_if_null(self.temp_result, self.pos))
3319 code.put_gotref(self.temp_result)
3320 code.put_decref_clear(self.temp_result, py_object_type)
3322 def annotate(self, code):
3323 for arg in self.args:
3327 class DelStatNode(StatNode):
3332 child_attrs = ["args"]
3334 def analyse_declarations(self, env):
3335 for arg in self.args:
3336 arg.analyse_target_declaration(env)
3338 def analyse_expressions(self, env):
3339 for arg in self.args:
3340 arg.analyse_target_expression(env, None)
3341 if arg.type.is_pyobject:
3344 error(arg.pos, "Deletion of non-Python object")
3345 #arg.release_target_temp(env)
3347 gil_message = "Deleting Python object"
3349 def generate_execution_code(self, code):
3350 for arg in self.args:
3351 if arg.type.is_pyobject:
3352 arg.generate_deletion_code(code)
3353 # else error reported earlier
3355 def annotate(self, code):
3356 for arg in self.args:
3360 class PassStatNode(StatNode):
3365 def analyse_expressions(self, env):
3368 def generate_execution_code(self, code):
3372 class BreakStatNode(StatNode):
3376 def analyse_expressions(self, env):
3379 def generate_execution_code(self, code):
3380 if not code.break_label:
3381 error(self.pos, "break statement not inside loop")
3383 code.put_goto(code.break_label)
3386 class ContinueStatNode(StatNode):
3390 def analyse_expressions(self, env):
3393 def generate_execution_code(self, code):
3394 if code.funcstate.in_try_finally:
3395 error(self.pos, "continue statement inside try of try...finally")
3396 elif not code.continue_label:
3397 error(self.pos, "continue statement not inside loop")
3399 code.put_goto(code.continue_label)
3402 class ReturnStatNode(StatNode):
3405 # value ExprNode or None
3406 # return_type PyrexType
3407 # temps_in_use [Entry] Temps in use at time of return
3409 child_attrs = ["value"]
3411 def analyse_expressions(self, env):
3412 return_type = env.return_type
3413 self.return_type = return_type
3414 self.temps_in_use = env.temps_in_use()
3416 error(self.pos, "Return not inside a function body")
3419 self.value.analyse_types(env)
3420 if return_type.is_void or return_type.is_returncode:
3421 error(self.value.pos,
3422 "Return with value in void function")
3424 self.value = self.value.coerce_to(env.return_type, env)
3425 self.value.allocate_temps(env)
3426 self.value.release_temp(env)
3428 if (not return_type.is_void
3429 and not return_type.is_pyobject
3430 and not return_type.is_returncode):
3431 error(self.pos, "Return value required")
3432 if return_type.is_pyobject:
3435 gil_message = "Returning Python object"
3437 def generate_execution_code(self, code):
3438 code.mark_pos(self.pos)
3439 if not self.return_type:
3440 # error reported earlier
3442 if self.return_type.is_pyobject:
3443 code.put_xdecref(Naming.retval_cname,
3446 self.value.generate_evaluation_code(code)
3447 self.value.make_owned_reference(code)
3450 Naming.retval_cname,
3451 self.value.result_as(self.return_type)))
3452 self.value.generate_post_assignment_code(code)
3453 self.value.free_temps(code)
3455 if self.return_type.is_pyobject:
3456 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3457 elif self.return_type.is_returncode:
3460 Naming.retval_cname,
3461 self.return_type.default_value))
3462 # free temps the old way
3463 for entry in self.temps_in_use:
3464 code.put_var_decref_clear(entry)
3465 # free temps the new way
3466 for cname, type in code.funcstate.temps_holding_reference():
3467 code.put_decref_clear(cname, type)
3470 # code.return_label)
3471 code.put_goto(code.return_label)
3473 def annotate(self, code):
3475 self.value.annotate(code)
3478 class RaiseStatNode(StatNode):
3481 # exc_type ExprNode or None
3482 # exc_value ExprNode or None
3483 # exc_tb ExprNode or None
3485 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3487 def analyse_expressions(self, env):
3489 self.exc_type.analyse_types(env)
3490 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3491 self.exc_type.allocate_temps(env)
3493 self.exc_value.analyse_types(env)
3494 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3495 self.exc_value.allocate_temps(env)
3497 self.exc_tb.analyse_types(env)
3498 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3499 self.exc_tb.allocate_temps(env)
3501 self.exc_type.release_temp(env)
3503 self.exc_value.release_temp(env)
3505 self.exc_tb.release_temp(env)
3506 env.use_utility_code(raise_utility_code)
3507 env.use_utility_code(restore_exception_utility_code)
3510 gil_message = "Raising exception"
3512 def generate_execution_code(self, code):
3514 self.exc_type.generate_evaluation_code(code)
3515 type_code = self.exc_type.py_result()
3519 self.exc_value.generate_evaluation_code(code)
3520 value_code = self.exc_value.py_result()
3524 self.exc_tb.generate_evaluation_code(code)
3525 tb_code = self.exc_tb.py_result()
3528 if self.exc_type or self.exc_value or self.exc_tb:
3530 "__Pyx_Raise(%s, %s, %s);" % (
3537 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3539 obj.generate_disposal_code(code)
3540 obj.free_temps(code)
3542 code.error_goto(self.pos))
3544 def annotate(self, code):
3546 self.exc_type.annotate(code)
3548 self.exc_value.annotate(code)
3550 self.exc_tb.annotate(code)
3553 class ReraiseStatNode(StatNode):
3557 def analyse_expressions(self, env):
3559 env.use_utility_code(raise_utility_code)
3560 env.use_utility_code(restore_exception_utility_code)
3562 gil_message = "Raising exception"
3564 def generate_execution_code(self, code):
3565 vars = code.funcstate.exc_vars
3567 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3568 code.putln(code.error_goto(self.pos))
3570 error(self.pos, "Reraise not inside except clause")
3573 class AssertStatNode(StatNode):
3577 # value ExprNode or None
3579 child_attrs = ["cond", "value"]
3581 def analyse_expressions(self, env):
3582 self.cond = self.cond.analyse_boolean_expression(env)
3584 self.value.analyse_types(env)
3585 self.value = self.value.coerce_to_pyobject(env)
3586 self.value.allocate_temps(env)
3587 self.cond.release_temp(env)
3589 self.value.release_temp(env)
3591 #env.recycle_pending_temps() # TEMPORARY
3593 gil_message = "Raising exception"
3595 def generate_execution_code(self, code):
3596 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3597 self.cond.generate_evaluation_code(code)
3599 "if (unlikely(!%s)) {" %
3602 self.value.generate_evaluation_code(code)
3604 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3605 self.value.py_result())
3606 self.value.generate_disposal_code(code)
3607 self.value.free_temps(code)
3610 "PyErr_SetNone(PyExc_AssertionError);")
3612 code.error_goto(self.pos))
3615 self.cond.generate_disposal_code(code)
3616 self.cond.free_temps(code)
3617 code.putln("#endif")
3619 def annotate(self, code):
3620 self.cond.annotate(code)
3622 self.value.annotate(code)
3625 class IfStatNode(StatNode):
3628 # if_clauses [IfClauseNode]
3629 # else_clause StatNode or None
3631 child_attrs = ["if_clauses", "else_clause"]
3633 def analyse_control_flow(self, env):
3634 env.start_branching(self.pos)
3635 for if_clause in self.if_clauses:
3636 if_clause.analyse_control_flow(env)
3637 env.next_branch(if_clause.end_pos())
3638 if self.else_clause:
3639 self.else_clause.analyse_control_flow(env)
3640 env.finish_branching(self.end_pos())
3642 def analyse_declarations(self, env):
3643 for if_clause in self.if_clauses:
3644 if_clause.analyse_declarations(env)
3645 if self.else_clause:
3646 self.else_clause.analyse_declarations(env)
3648 def analyse_expressions(self, env):
3649 for if_clause in self.if_clauses:
3650 if_clause.analyse_expressions(env)
3651 if self.else_clause:
3652 self.else_clause.analyse_expressions(env)
3654 def generate_execution_code(self, code):
3655 code.mark_pos(self.pos)
3656 end_label = code.new_label()
3657 for if_clause in self.if_clauses:
3658 if_clause.generate_execution_code(code, end_label)
3659 if self.else_clause:
3660 code.putln("/*else*/ {")
3661 self.else_clause.generate_execution_code(code)
3663 code.put_label(end_label)
3665 def annotate(self, code):
3666 for if_clause in self.if_clauses:
3667 if_clause.annotate(code)
3668 if self.else_clause:
3669 self.else_clause.annotate(code)
3672 class IfClauseNode(Node):
3673 # if or elif clause in an if statement
3675 # condition ExprNode
3678 child_attrs = ["condition", "body"]
3680 def analyse_control_flow(self, env):
3681 self.body.analyse_control_flow(env)
3683 def analyse_declarations(self, env):
3684 self.condition.analyse_declarations(env)
3685 self.body.analyse_declarations(env)
3687 def analyse_expressions(self, env):
3689 self.condition.analyse_temp_boolean_expression(env)
3690 self.condition.release_temp(env)
3691 self.body.analyse_expressions(env)
3693 def generate_execution_code(self, code, end_label):
3694 self.condition.generate_evaluation_code(code)
3697 self.condition.result())
3698 self.condition.generate_disposal_code(code)
3699 self.condition.free_temps(code)
3700 self.body.generate_execution_code(code)
3704 code.put_goto(end_label)
3707 def annotate(self, code):
3708 self.condition.annotate(code)
3709 self.body.annotate(code)
3712 class SwitchCaseNode(StatNode):
3713 # Generated in the optimization of an if-elif-else node
3715 # conditions [ExprNode]
3718 child_attrs = ['conditions', 'body']
3720 def generate_execution_code(self, code):
3721 for cond in self.conditions:
3722 code.mark_pos(cond.pos)
3723 code.putln("case %s:" % cond.calculate_result_code())
3724 self.body.generate_execution_code(code)
3725 code.putln("break;")
3727 def annotate(self, code):
3728 for cond in self.conditions:
3730 self.body.annotate(code)
3732 class SwitchStatNode(StatNode):
3733 # Generated in the optimization of an if-elif-else node
3736 # cases [SwitchCaseNode]
3737 # else_clause StatNode or None
3739 child_attrs = ['test', 'cases', 'else_clause']
3741 def generate_execution_code(self, code):
3742 code.putln("switch (%s) {" % self.test.calculate_result_code())
3743 for case in self.cases:
3744 case.generate_execution_code(code)
3745 if self.else_clause is not None:
3746 code.putln("default:")
3747 self.else_clause.generate_execution_code(code)
3748 code.putln("break;")
3751 def annotate(self, code):
3752 self.test.annotate(code)
3753 for case in self.cases:
3755 if self.else_clause is not None:
3756 self.else_clause.annotate(code)
3758 class LoopNode(object):
3760 def analyse_control_flow(self, env):
3761 env.start_branching(self.pos)
3762 self.body.analyse_control_flow(env)
3763 env.next_branch(self.body.end_pos())
3764 if self.else_clause:
3765 self.else_clause.analyse_control_flow(env)
3766 env.finish_branching(self.end_pos())
3769 class WhileStatNode(LoopNode, StatNode):
3772 # condition ExprNode
3774 # else_clause StatNode
3776 child_attrs = ["condition", "body", "else_clause"]
3778 def analyse_declarations(self, env):
3779 self.body.analyse_declarations(env)
3780 if self.else_clause:
3781 self.else_clause.analyse_declarations(env)
3783 def analyse_expressions(self, env):
3785 self.condition.analyse_temp_boolean_expression(env)
3786 self.condition.release_temp(env)
3787 #env.recycle_pending_temps() # TEMPORARY
3788 self.body.analyse_expressions(env)
3789 if self.else_clause:
3790 self.else_clause.analyse_expressions(env)
3792 def generate_execution_code(self, code):
3793 old_loop_labels = code.new_loop_labels()
3796 self.condition.generate_evaluation_code(code)
3797 self.condition.generate_disposal_code(code)
3800 self.condition.result())
3801 self.condition.free_temps(code)
3802 self.body.generate_execution_code(code)
3803 code.put_label(code.continue_label)
3805 break_label = code.break_label
3806 code.set_loop_labels(old_loop_labels)
3807 if self.else_clause:
3808 code.putln("/*else*/ {")
3809 self.else_clause.generate_execution_code(code)
3811 code.put_label(break_label)
3813 def annotate(self, code):
3814 self.condition.annotate(code)
3815 self.body.annotate(code)
3816 if self.else_clause:
3817 self.else_clause.annotate(code)
3820 def ForStatNode(pos, **kw):
3821 if 'iterator' in kw:
3822 return ForInStatNode(pos, **kw)
3824 return ForFromStatNode(pos, **kw)
3826 class ForInStatNode(LoopNode, StatNode):
3830 # iterator IteratorNode
3832 # else_clause StatNode
3833 # item NextNode used internally
3835 child_attrs = ["target", "iterator", "body", "else_clause"]
3838 def analyse_declarations(self, env):
3839 self.target.analyse_target_declaration(env)
3840 self.body.analyse_declarations(env)
3841 if self.else_clause:
3842 self.else_clause.analyse_declarations(env)
3844 def analyse_expressions(self, env):
3846 self.target.analyse_target_types(env)
3847 self.iterator.analyse_expressions(env)
3848 self.item = ExprNodes.NextNode(self.iterator, env)
3849 self.item = self.item.coerce_to(self.target.type, env)
3850 self.item.allocate_temps(env)
3851 self.target.allocate_target_temps(env, self.item)
3852 #self.item.release_temp(env)
3853 #self.target.release_target_temp(env)
3854 self.body.analyse_expressions(env)
3855 if self.else_clause:
3856 self.else_clause.analyse_expressions(env)
3857 self.iterator.release_temp(env)
3859 def generate_execution_code(self, code):
3860 old_loop_labels = code.new_loop_labels()
3861 self.iterator.allocate_counter_temp(code)
3862 self.iterator.generate_evaluation_code(code)
3865 self.item.generate_evaluation_code(code)
3866 self.target.generate_assignment_code(self.item, code)
3867 self.body.generate_execution_code(code)
3868 code.put_label(code.continue_label)
3871 break_label = code.break_label
3872 code.set_loop_labels(old_loop_labels)
3873 if self.else_clause:
3874 code.putln("/*else*/ {")
3875 self.else_clause.generate_execution_code(code)
3877 code.put_label(break_label)
3878 self.iterator.release_counter_temp(code)
3879 self.iterator.generate_disposal_code(code)
3880 self.iterator.free_temps(code)
3882 def annotate(self, code):
3883 self.target.annotate(code)
3884 self.iterator.annotate(code)
3885 self.body.annotate(code)
3886 if self.else_clause:
3887 self.else_clause.annotate(code)
3888 self.item.annotate(code)
3891 class ForFromStatNode(LoopNode, StatNode):
3892 # for name from expr rel name rel expr
3899 # step ExprNode or None
3901 # else_clause StatNode or None
3907 # loopvar_node ExprNode (usually a NameNode or temp node)
3908 # py_loopvar_node PyTempNode or None
3909 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3911 is_py_target = False
3913 py_loopvar_node = None
3916 def analyse_declarations(self, env):
3917 self.target.analyse_target_declaration(env)
3918 self.body.analyse_declarations(env)
3919 if self.else_clause:
3920 self.else_clause.analyse_declarations(env)
3922 def analyse_expressions(self, env):
3924 self.target.analyse_target_types(env)
3925 self.bound1.analyse_types(env)
3926 self.bound2.analyse_types(env)
3927 if self.step is not None:
3928 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3929 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3930 self.step.analyse_types(env)
3932 target_type = self.target.type
3933 if self.target.type.is_numeric:
3934 loop_type = self.target.type
3936 loop_type = PyrexTypes.c_int_type
3937 if not self.bound1.type.is_pyobject:
3938 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3939 if not self.bound2.type.is_pyobject:
3940 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3941 if self.step is not None and not self.step.type.is_pyobject:
3942 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3943 self.bound1 = self.bound1.coerce_to(loop_type, env)
3944 self.bound2 = self.bound2.coerce_to(loop_type, env)
3945 if not self.bound2.is_literal:
3946 self.bound2 = self.bound2.coerce_to_temp(env)
3947 if self.step is not None:
3948 self.step = self.step.coerce_to(loop_type, env)
3949 if not self.step.is_literal:
3950 self.step = self.step.coerce_to_temp(env)
3952 target_type = self.target.type
3953 if not (target_type.is_pyobject or target_type.is_numeric):
3954 error(self.target.pos,
3955 "for-from loop variable must be c numeric type or Python object")
3956 if target_type.is_numeric:
3957 self.is_py_target = False
3958 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3959 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3960 self.loopvar_node = self.target
3961 self.py_loopvar_node = None
3963 self.is_py_target = True
3964 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3965 c_loopvar_node.allocate_temps(env)
3966 self.loopvar_node = c_loopvar_node
3967 self.py_loopvar_node = \
3968 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3969 self.bound1.allocate_temps(env)
3970 self.bound2.allocate_temps(env)
3971 if self.step is not None:
3972 self.step.allocate_temps(env)
3973 if self.is_py_target:
3974 self.py_loopvar_node.allocate_temps(env)
3975 self.target.allocate_target_temps(env, self.py_loopvar_node)
3976 #self.target.release_target_temp(env)
3977 #self.py_loopvar_node.release_temp(env)
3978 self.body.analyse_expressions(env)
3979 if self.is_py_target:
3980 c_loopvar_node.release_temp(env)
3981 if self.else_clause:
3982 self.else_clause.analyse_expressions(env)
3983 self.bound1.release_temp(env)
3984 self.bound2.release_temp(env)
3985 if self.step is not None:
3986 self.step.release_temp(env)
3988 def generate_execution_code(self, code):
3989 old_loop_labels = code.new_loop_labels()
3990 from_range = self.from_range
3991 self.bound1.generate_evaluation_code(code)
3992 self.bound2.generate_evaluation_code(code)
3993 offset, incop = self.relation_table[self.relation1]
3994 if self.step is not None:
3995 self.step.generate_evaluation_code(code)
3996 step = self.step.result()
3997 incop = "%s=%s" % (incop[0], step)
3999 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4001 loopvar_name = self.loopvar_node.result()
4003 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4005 self.bound1.result(), offset,
4006 loopvar_name, self.relation2, self.bound2.result(),
4007 loopvar_name, incop))
4008 if self.py_loopvar_node:
4009 self.py_loopvar_node.generate_evaluation_code(code)
4010 self.target.generate_assignment_code(self.py_loopvar_node, code)
4012 code.putln("%s = %s;" % (
4013 self.target.result(), loopvar_name))
4014 self.body.generate_execution_code(code)
4015 code.put_label(code.continue_label)
4016 if self.py_loopvar_node:
4017 # This mess is to make for..from loops with python targets behave
4018 # exactly like those with C targets with regards to re-assignment
4019 # of the loop variable.
4021 if self.target.entry.is_pyglobal:
4022 # We know target is a NameNode, this is the only ugly case.
4023 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4024 target_node.result_code = code.funcstate.allocate_temp(py_object_type, False)
4025 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4026 target_node.result_code,
4027 Naming.module_cname,
4028 self.target.entry.interned_cname,
4029 code.error_goto_if_null(target_node.result_code, self.target.pos)))
4030 code.put_gotref(target_node.result_code)
4032 target_node = self.target
4033 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4034 from_py_node.temp_code = loopvar_name
4035 from_py_node.generate_result_code(code)
4036 if self.target.entry.is_pyglobal:
4037 code.put_decref_clear(target_node.result_code, py_object_type)
4038 code.funcstate.release_temp(target_node.result_code)
4040 if self.py_loopvar_node:
4041 # This is potentially wasteful, but we don't want the semantics to
4042 # depend on whether or not the loop is a python type.
4043 self.py_loopvar_node.generate_evaluation_code(code)
4044 self.target.generate_assignment_code(self.py_loopvar_node, code)
4045 break_label = code.break_label
4046 code.set_loop_labels(old_loop_labels)
4047 if self.else_clause:
4048 code.putln("/*else*/ {")
4049 self.else_clause.generate_execution_code(code)
4051 code.put_label(break_label)
4052 self.bound1.generate_disposal_code(code)
4053 self.bound1.free_temps(code)
4054 self.bound2.generate_disposal_code(code)
4055 self.bound2.free_temps(code)
4056 if self.step is not None:
4057 self.step.generate_disposal_code(code)
4058 self.step.free_temps(code)
4060 code.funcstate.release_temp(loopvar_name)
4063 # {relop : (initial offset, increment op)}
4070 def annotate(self, code):
4071 self.target.annotate(code)
4072 self.bound1.annotate(code)
4073 self.bound2.annotate(code)
4075 self.bound2.annotate(code)
4076 self.body.annotate(code)
4077 if self.else_clause:
4078 self.else_clause.annotate(code)
4081 class WithStatNode(StatNode):
4083 Represents a Python with statement.
4085 This is only used at parse tree level; and is not present in
4086 analysis or generation phases.
4088 # manager The with statement manager object
4089 # target Node (lhs expression)
4091 child_attrs = ["manager", "target", "body"]
4093 class TryExceptStatNode(StatNode):
4094 # try .. except statement
4097 # except_clauses [ExceptClauseNode]
4098 # else_clause StatNode or None
4099 # cleanup_list [Entry] old style temps to clean up on error
4101 child_attrs = ["body", "except_clauses", "else_clause"]
4103 def analyse_control_flow(self, env):
4104 env.start_branching(self.pos)
4105 self.body.analyse_control_flow(env)
4106 successful_try = env.control_flow # grab this for later
4107 env.next_branch(self.body.end_pos())
4108 env.finish_branching(self.body.end_pos())
4110 env.start_branching(self.except_clauses[0].pos)
4111 for except_clause in self.except_clauses:
4112 except_clause.analyse_control_flow(env)
4113 env.next_branch(except_clause.end_pos())
4115 # the else cause it executed only when the try clause finishes
4116 env.control_flow.incoming = successful_try
4117 if self.else_clause:
4118 self.else_clause.analyse_control_flow(env)
4119 env.finish_branching(self.end_pos())
4121 def analyse_declarations(self, env):
4122 self.body.analyse_declarations(env)
4123 for except_clause in self.except_clauses:
4124 except_clause.analyse_declarations(env)
4125 if self.else_clause:
4126 self.else_clause.analyse_declarations(env)
4128 env.use_utility_code(reset_exception_utility_code)
4130 def analyse_expressions(self, env):
4131 self.body.analyse_expressions(env)
4132 self.cleanup_list = env.free_temp_entries[:]
4133 default_clause_seen = 0
4134 for except_clause in self.except_clauses:
4135 except_clause.analyse_expressions(env)
4136 if default_clause_seen:
4137 error(except_clause.pos, "default 'except:' must be last")
4138 if not except_clause.pattern:
4139 default_clause_seen = 1
4140 self.has_default_clause = default_clause_seen
4141 if self.else_clause:
4142 self.else_clause.analyse_expressions(env)
4145 gil_message = "Try-except statement"
4147 def generate_execution_code(self, code):
4148 old_return_label = code.return_label
4149 old_break_label = code.break_label
4150 old_continue_label = code.continue_label
4151 old_error_label = code.new_error_label()
4152 our_error_label = code.error_label
4153 except_end_label = code.new_label('exception_handled')
4154 except_error_label = code.new_label('except_error')
4155 except_return_label = code.new_label('except_return')
4156 try_return_label = code.new_label('try_return')
4157 try_break_label = code.new_label('try_break')
4158 try_continue_label = code.new_label('try_continue')
4159 try_end_label = code.new_label('try_end')
4162 code.putln("PyObject %s;" %
4163 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4164 code.putln("__Pyx_ExceptionSave(%s);" %
4165 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4166 for var in Naming.exc_save_vars:
4167 code.put_xgotref(var)
4170 code.return_label = try_return_label
4171 code.break_label = try_break_label
4172 code.continue_label = try_continue_label
4173 self.body.generate_execution_code(code)
4176 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4177 code.error_label = except_error_label
4178 code.return_label = except_return_label
4179 if self.else_clause:
4182 self.else_clause.generate_execution_code(code)
4185 for var in Naming.exc_save_vars:
4186 code.put_xdecref_clear(var, py_object_type)
4187 code.put_goto(try_end_label)
4188 if code.label_used(try_return_label):
4189 code.put_label(try_return_label)
4190 for var in Naming.exc_save_vars:
4191 code.put_xdecref_clear(var, py_object_type)
4192 code.put_goto(old_return_label)
4193 code.put_label(our_error_label)
4194 code.put_var_xdecrefs_clear(self.cleanup_list)
4195 for temp_name, type in temps_to_clean_up:
4196 code.put_xdecref_clear(temp_name, type)
4197 for except_clause in self.except_clauses:
4198 except_clause.generate_handling_code(code, except_end_label)
4200 error_label_used = code.label_used(except_error_label)
4201 if error_label_used or not self.has_default_clause:
4202 if error_label_used:
4203 code.put_label(except_error_label)
4204 for var in Naming.exc_save_vars:
4205 code.put_xdecref(var, py_object_type)
4206 code.put_goto(old_error_label)
4208 if code.label_used(try_break_label):
4209 code.put_label(try_break_label)
4210 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4211 code.putln("__Pyx_ExceptionReset(%s);" %
4212 ', '.join(Naming.exc_save_vars))
4213 code.put_goto(old_break_label)
4215 if code.label_used(try_continue_label):
4216 code.put_label(try_continue_label)
4217 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4218 code.putln("__Pyx_ExceptionReset(%s);" %
4219 ', '.join(Naming.exc_save_vars))
4220 code.put_goto(old_continue_label)
4222 if code.label_used(except_return_label):
4223 code.put_label(except_return_label)
4224 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4225 code.putln("__Pyx_ExceptionReset(%s);" %
4226 ', '.join(Naming.exc_save_vars))
4227 code.put_goto(old_return_label)
4229 if code.label_used(except_end_label):
4230 code.put_label(except_end_label)
4231 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4232 code.putln("__Pyx_ExceptionReset(%s);" %
4233 ', '.join(Naming.exc_save_vars))
4234 code.put_label(try_end_label)
4237 code.return_label = old_return_label
4238 code.break_label = old_break_label
4239 code.continue_label = old_continue_label
4240 code.error_label = old_error_label
4242 def annotate(self, code):
4243 self.body.annotate(code)
4244 for except_node in self.except_clauses:
4245 except_node.annotate(code)
4246 if self.else_clause:
4247 self.else_clause.annotate(code)
4250 class ExceptClauseNode(Node):
4251 # Part of try ... except statement.
4254 # target ExprNode or None
4256 # excinfo_target NameNode or None optional target for exception info
4257 # match_flag string result of exception match
4258 # exc_value ExcValueNode used internally
4259 # function_name string qualified name of enclosing function
4260 # exc_vars (string * 3) local exception variables
4262 # excinfo_target is never set by the parser, but can be set by a transform
4263 # in order to extract more extensive information about the exception as a
4264 # sys.exc_info()-style tuple into a target variable
4266 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4269 excinfo_target = None
4271 def analyse_declarations(self, env):
4273 self.target.analyse_target_declaration(env)
4274 if self.excinfo_target is not None:
4275 self.excinfo_target.analyse_target_declaration(env)
4276 self.body.analyse_declarations(env)
4278 def analyse_expressions(self, env):
4280 genv = env.global_scope()
4281 self.function_name = env.qualified_name
4283 self.pattern.analyse_expressions(env)
4284 self.pattern = self.pattern.coerce_to_pyobject(env)
4285 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4286 self.pattern.release_temp(env)
4287 env.release_temp(self.match_flag)
4289 if self.target or self.excinfo_target:
4290 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4292 self.exc_vars = None
4295 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4296 self.exc_value.allocate_temps(env)
4297 self.target.analyse_target_expression(env, self.exc_value)
4298 if self.excinfo_target is not None:
4300 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4301 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4302 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4303 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4305 self.excinfo_tuple.analyse_expressions(env)
4306 self.excinfo_tuple.allocate_temps(env)
4307 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4309 self.body.analyse_expressions(env)
4312 for var in self.exc_vars:
4313 env.release_temp(var)
4315 def generate_handling_code(self, code, end_label):
4316 code.mark_pos(self.pos)
4318 self.pattern.generate_evaluation_code(code)
4320 "%s = PyErr_ExceptionMatches(%s);" % (
4322 self.pattern.py_result()))
4323 self.pattern.generate_disposal_code(code)
4324 self.pattern.free_temps(code)
4329 code.putln("/*except:*/ {")
4332 exc_vars = self.exc_vars
4333 elif not getattr(self.body, 'stats', True):
4334 # most simple case: no exception variable, empty body (pass)
4335 # => reset the exception state, done
4336 code.putln("PyErr_Restore(0,0,0);")
4337 code.put_goto(end_label)
4341 # during type analysis, we didn't know if we need the
4342 # exception value, but apparently, we do
4343 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4347 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4348 # We always have to fetch the exception value even if
4349 # there is no target, because this also normalises the
4350 # exception and stores it in the thread state.
4351 code.globalstate.use_utility_code(get_exception_utility_code)
4352 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4353 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4354 code.error_goto(self.pos)))
4358 self.exc_value.generate_evaluation_code(code)
4359 self.target.generate_assignment_code(self.exc_value, code)
4360 if self.excinfo_target is not None:
4361 self.excinfo_tuple.generate_evaluation_code(code)
4362 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4365 old_break_label, old_continue_label = code.break_label, code.continue_label
4366 code.break_label = code.new_label('except_break')
4367 code.continue_label = code.new_label('except_continue')
4369 old_exc_vars = code.funcstate.exc_vars
4370 code.funcstate.exc_vars = exc_vars
4371 self.body.generate_execution_code(code)
4372 code.funcstate.exc_vars = old_exc_vars
4373 for var in exc_vars:
4374 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4375 code.put_goto(end_label)
4377 if code.label_used(code.break_label):
4378 code.put_label(code.break_label)
4379 for var in exc_vars:
4380 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4381 code.put_goto(old_break_label)
4382 code.break_label = old_break_label
4384 if code.label_used(code.continue_label):
4385 code.put_label(code.continue_label)
4386 for var in exc_vars:
4387 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4388 code.put_goto(old_continue_label)
4389 code.continue_label = old_continue_label
4391 if not self.exc_vars:
4392 # clean up locally allocated temps
4393 for temp in exc_vars:
4394 code.funcstate.release_temp(temp)
4399 def annotate(self, code):
4401 self.pattern.annotate(code)
4403 self.target.annotate(code)
4404 self.body.annotate(code)
4407 class TryFinallyStatNode(StatNode):
4408 # try ... finally statement
4411 # finally_clause StatNode
4413 # cleanup_list [Entry] old_style temps to clean up on error
4415 # The plan is that we funnel all continue, break
4416 # return and error gotos into the beginning of the
4417 # finally block, setting a variable to remember which
4418 # one we're doing. At the end of the finally block, we
4419 # switch on the variable to figure out where to go.
4420 # In addition, if we're doing an error, we save the
4421 # exception on entry to the finally block and restore
4424 child_attrs = ["body", "finally_clause"]
4426 preserve_exception = 1
4428 disallow_continue_in_try_finally = 0
4429 # There doesn't seem to be any point in disallowing
4430 # continue in the try block, since we have no problem
4433 def create_analysed(pos, env, body, finally_clause):
4434 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4435 node.cleanup_list = []
4437 create_analysed = staticmethod(create_analysed)
4439 def analyse_control_flow(self, env):
4440 env.start_branching(self.pos)
4441 self.body.analyse_control_flow(env)
4442 env.next_branch(self.body.end_pos())
4443 env.finish_branching(self.body.end_pos())
4444 self.finally_clause.analyse_control_flow(env)
4446 def analyse_declarations(self, env):
4447 self.body.analyse_declarations(env)
4448 self.finally_clause.analyse_declarations(env)
4450 def analyse_expressions(self, env):
4451 self.body.analyse_expressions(env)
4452 self.cleanup_list = env.free_temp_entries[:]
4453 self.finally_clause.analyse_expressions(env)
4456 gil_message = "Try-finally statement"
4458 def generate_execution_code(self, code):
4459 old_error_label = code.error_label
4460 old_labels = code.all_new_labels()
4461 new_labels = code.get_all_labels()
4462 new_error_label = code.error_label
4463 catch_label = code.new_label()
4466 if self.disallow_continue_in_try_finally:
4467 was_in_try_finally = code.funcstate.in_try_finally
4468 code.funcstate.in_try_finally = 1
4469 self.body.generate_execution_code(code)
4470 if self.disallow_continue_in_try_finally:
4471 code.funcstate.in_try_finally = was_in_try_finally
4474 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4478 error_label_used = 0
4479 for i, new_label in enumerate(new_labels):
4480 if new_label in code.labels_used:
4481 cases_used.append(i)
4482 if new_label == new_error_label:
4483 error_label_used = 1
4484 error_label_case = i
4488 if error_label_used and self.preserve_exception:
4490 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4492 "int %s;" % Naming.exc_lineno_name)
4493 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4494 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4495 code.putln(exc_var_init_zero)
4497 exc_var_init_zero = None
4498 code.use_label(catch_label)
4500 "__pyx_why = 0; goto %s;" % catch_label)
4501 for i in cases_used:
4502 new_label = new_labels[i]
4503 #if new_label and new_label != "<try>":
4504 if new_label == new_error_label and self.preserve_exception:
4505 self.put_error_catcher(code,
4506 new_error_label, i+1, catch_label, temps_to_clean_up)
4508 code.put('%s: ' % new_label)
4509 if exc_var_init_zero:
4510 code.putln(exc_var_init_zero)
4511 code.putln("__pyx_why = %s; goto %s;" % (
4514 code.put_label(catch_label)
4515 code.set_all_labels(old_labels)
4516 if error_label_used:
4517 code.new_error_label()
4518 finally_error_label = code.error_label
4519 self.finally_clause.generate_execution_code(code)
4520 if error_label_used:
4521 if finally_error_label in code.labels_used and self.preserve_exception:
4522 over_label = code.new_label()
4523 code.put_goto(over_label);
4524 code.put_label(finally_error_label)
4525 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4526 for var in Naming.exc_vars:
4527 code.putln("Py_XDECREF(%s);" % var)
4529 code.put_goto(old_error_label)
4530 code.put_label(over_label)
4531 code.error_label = old_error_label
4534 "switch (__pyx_why) {")
4535 for i in cases_used:
4536 old_label = old_labels[i]
4537 if old_label == old_error_label and self.preserve_exception:
4538 self.put_error_uncatcher(code, i+1, old_error_label)
4540 code.use_label(old_label)
4542 "case %s: goto %s;" % (
4550 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4551 code.globalstate.use_utility_code(restore_exception_utility_code)
4558 code.put_var_xdecrefs_clear(self.cleanup_list)
4559 for temp_name, type in temps_to_clean_up:
4560 code.put_xdecref_clear(temp_name, type)
4562 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4566 Naming.exc_lineno_name, Naming.lineno_cname))
4570 code.put_goto(catch_label)
4574 def put_error_uncatcher(self, code, i, error_label):
4575 code.globalstate.use_utility_code(restore_exception_utility_code)
4580 "__Pyx_ErrRestore(%s, %s, %s);" %
4584 Naming.lineno_cname, Naming.exc_lineno_name))
4585 for var in Naming.exc_vars:
4589 code.put_goto(error_label)
4593 def annotate(self, code):
4594 self.body.annotate(code)
4595 self.finally_clause.annotate(code)
4598 class GILStatNode(TryFinallyStatNode):
4599 # 'with gil' or 'with nogil' statement
4601 # state string 'gil' or 'nogil'
4605 preserve_exception = 0
4607 def __init__(self, pos, state, body):
4609 TryFinallyStatNode.__init__(self, pos,
4611 finally_clause = GILExitNode(pos, state = state))
4613 def analyse_expressions(self, env):
4614 env.use_utility_code(force_init_threads_utility_code)
4615 was_nogil = env.nogil
4617 TryFinallyStatNode.analyse_expressions(self, env)
4618 env.nogil = was_nogil
4620 def gil_check(self, env):
4623 def generate_execution_code(self, code):
4624 code.mark_pos(self.pos)
4625 if self.state == 'gil':
4626 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4628 code.putln("{ PyThreadState *_save;")
4629 code.putln("Py_UNBLOCK_THREADS")
4630 TryFinallyStatNode.generate_execution_code(self, code)
4634 class GILExitNode(StatNode):
4635 # Used as the 'finally' block in a GILStatNode
4637 # state string 'gil' or 'nogil'
4641 def analyse_expressions(self, env):
4644 def generate_execution_code(self, code):
4645 if self.state == 'gil':
4646 code.putln("PyGILState_Release();")
4648 code.putln("Py_BLOCK_THREADS")
4651 class CImportStatNode(StatNode):
4654 # module_name string Qualified name of module being imported
4655 # as_name string or None Name specified in "as" clause, if any
4659 def analyse_declarations(self, env):
4660 if not env.is_module_scope:
4661 error(self.pos, "cimport only allowed at module level")
4663 module_scope = env.find_module(self.module_name, self.pos)
4664 if "." in self.module_name:
4665 names = [EncodedString(name) for name in self.module_name.split(".")]
4667 top_module_scope = env.context.find_submodule(top_name)
4668 module_scope = top_module_scope
4669 for name in names[1:]:
4670 submodule_scope = module_scope.find_submodule(name)
4671 module_scope.declare_module(name, submodule_scope, self.pos)
4672 module_scope = submodule_scope
4674 env.declare_module(self.as_name, module_scope, self.pos)
4676 env.declare_module(top_name, top_module_scope, self.pos)
4678 name = self.as_name or self.module_name
4679 env.declare_module(name, module_scope, self.pos)
4681 def analyse_expressions(self, env):
4684 def generate_execution_code(self, code):
4688 class FromCImportStatNode(StatNode):
4689 # from ... cimport statement
4691 # module_name string Qualified name of module
4692 # imported_names [(pos, name, as_name, kind)] Names to be imported
4696 def analyse_declarations(self, env):
4697 if not env.is_module_scope:
4698 error(self.pos, "cimport only allowed at module level")
4700 module_scope = env.find_module(self.module_name, self.pos)
4701 env.add_imported_module(module_scope)
4702 for pos, name, as_name, kind in self.imported_names:
4704 for local_name, entry in module_scope.entries.items():
4705 env.add_imported_entry(local_name, entry, pos)
4707 entry = module_scope.lookup(name)
4709 if kind and not self.declaration_matches(entry, kind):
4710 entry.redeclared(pos)
4712 if kind == 'struct' or kind == 'union':
4713 entry = module_scope.declare_struct_or_union(name,
4714 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4715 elif kind == 'class':
4716 entry = module_scope.declare_c_class(name, pos = pos,
4717 module_name = self.module_name)
4719 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4720 if submodule_scope.parent_module is module_scope:
4721 env.declare_module(as_name or name, submodule_scope, self.pos)
4723 error(pos, "Name '%s' not declared in module '%s'"
4724 % (name, self.module_name))
4727 local_name = as_name or name
4728 env.add_imported_entry(local_name, entry, pos)
4730 def declaration_matches(self, entry, kind):
4731 if not entry.is_type:
4735 if not type.is_extension_type:
4738 if not type.is_struct_or_union:
4740 if kind != type.kind:
4744 def analyse_expressions(self, env):
4747 def generate_execution_code(self, code):
4751 class FromImportStatNode(StatNode):
4752 # from ... import statement
4755 # items [(string, NameNode)]
4756 # interned_items [(string, NameNode, ExprNode)]
4757 # item PyTempNode used internally
4758 # import_star boolean used internally
4760 child_attrs = ["module"]
4763 def analyse_declarations(self, env):
4764 for name, target in self.items:
4766 if not env.is_module_scope:
4767 error(self.pos, "import * only allowed at module level")
4769 env.has_import_star = 1
4770 self.import_star = 1
4772 target.analyse_target_declaration(env)
4774 def analyse_expressions(self, env):
4776 self.module.analyse_expressions(env)
4777 self.item = ExprNodes.PyTempNode(self.pos, env)
4778 self.item.allocate_temp(env)
4779 self.interned_items = []
4780 for name, target in self.items:
4782 for _, entry in env.entries.items():
4783 if not entry.is_type and entry.type.is_extension_type:
4784 env.use_utility_code(ExprNodes.type_test_utility_code)
4787 entry = env.lookup(target.name)
4788 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4789 continue # already cimported
4790 target.analyse_target_expression(env, None)
4791 if target.type is py_object_type:
4794 coerced_item = self.item.coerce_to(target.type, env)
4795 self.interned_items.append(
4796 (env.intern_identifier(name), target, coerced_item))
4797 #target.release_target_temp(env) # was release_temp ?!?
4798 self.module.release_temp(env)
4799 self.item.release_temp(env)
4801 def generate_execution_code(self, code):
4802 self.module.generate_evaluation_code(code)
4803 if self.import_star:
4805 'if (%s(%s) < 0) %s;' % (
4807 self.module.py_result(),
4808 code.error_goto(self.pos)))
4809 for cname, target, coerced_item in self.interned_items:
4811 '%s = PyObject_GetAttr(%s, %s); %s' % (
4813 self.module.py_result(),
4815 code.error_goto_if_null(self.item.result(), self.pos)))
4816 code.put_gotref(self.item.py_result())
4817 if coerced_item is None:
4818 target.generate_assignment_code(self.item, code)
4820 coerced_item.allocate_temp_result(code)
4821 coerced_item.generate_result_code(code)
4822 target.generate_assignment_code(coerced_item, code)
4823 if self.item.result() != coerced_item.result():
4824 code.put_decref_clear(self.item.result(), self.item.type)
4825 self.module.generate_disposal_code(code)
4826 self.module.free_temps(code)
4830 #------------------------------------------------------------------------------------
4832 # Runtime support code
4834 #------------------------------------------------------------------------------------
4836 utility_function_predeclarations = \
4839 #define INLINE __inline__
4841 #define INLINE __inline
4846 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4850 static int %(skip_dispatch_cname)s = 0;
4852 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4854 if Options.gcc_branch_hints:
4855 branch_prediction_macros = \
4858 /* Test for GCC > 2.95 */
4859 #if __GNUC__ > 2 || \
4860 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4861 #define likely(x) __builtin_expect(!!(x), 1)
4862 #define unlikely(x) __builtin_expect(!!(x), 0)
4863 #else /* __GNUC__ > 2 ... */
4864 #define likely(x) (x)
4865 #define unlikely(x) (x)
4866 #endif /* __GNUC__ > 2 ... */
4867 #else /* __GNUC__ */
4868 #define likely(x) (x)
4869 #define unlikely(x) (x)
4870 #endif /* __GNUC__ */
4873 branch_prediction_macros = \
4875 #define likely(x) (x)
4876 #define unlikely(x) (x)
4879 #get_name_predeclaration = \
4880 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4882 #get_name_interned_predeclaration = \
4883 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4885 #------------------------------------------------------------------------------------
4887 printing_utility_code = UtilityCode(
4889 static int __Pyx_Print(PyObject *, int); /*proto*/
4890 #if PY_MAJOR_VERSION >= 3
4891 static PyObject* %s = 0;
4892 static PyObject* %s = 0;
4894 """ % (Naming.print_function, Naming.print_function_kwargs),
4896 #if PY_MAJOR_VERSION < 3
4897 static PyObject *__Pyx_GetStdout(void) {
4898 PyObject *f = PySys_GetObject((char *)"stdout");
4900 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4905 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4910 if (!(f = __Pyx_GetStdout()))
4912 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4913 if (PyFile_SoftSpace(f, 1)) {
4914 if (PyFile_WriteString(" ", f) < 0)
4917 v = PyTuple_GET_ITEM(arg_tuple, i);
4918 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4920 if (PyString_Check(v)) {
4921 char *s = PyString_AsString(v);
4922 Py_ssize_t len = PyString_Size(v);
4924 isspace(Py_CHARMASK(s[len-1])) &&
4926 PyFile_SoftSpace(f, 0);
4930 if (PyFile_WriteString("\n", f) < 0)
4932 PyFile_SoftSpace(f, 0);
4937 #else /* Python 3 has a print function */
4939 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4940 PyObject* kwargs = 0;
4941 PyObject* result = 0;
4942 PyObject* end_string;
4943 if (!%(PRINT_FUNCTION)s) {
4944 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4945 if (!%(PRINT_FUNCTION)s)
4949 if (!%(PRINT_KWARGS)s) {
4950 %(PRINT_KWARGS)s = PyDict_New();
4951 if (!%(PRINT_KWARGS)s)
4953 end_string = PyUnicode_FromStringAndSize(" ", 1);
4956 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4957 Py_DECREF(end_string);
4960 Py_DECREF(end_string);
4962 kwargs = %(PRINT_KWARGS)s;
4964 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4972 """ % {'BUILTINS' : Naming.builtins_cname,
4973 'PRINT_FUNCTION' : Naming.print_function,
4974 'PRINT_KWARGS' : Naming.print_function_kwargs}
4978 printing_one_utility_code = UtilityCode(
4980 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4983 #if PY_MAJOR_VERSION < 3
4985 static int __Pyx_PrintOne(PyObject *o) {
4987 if (!(f = __Pyx_GetStdout()))
4989 if (PyFile_SoftSpace(f, 0)) {
4990 if (PyFile_WriteString(" ", f) < 0)
4993 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4995 if (PyFile_WriteString("\n", f) < 0)
4998 /* the line below is just to avoid compiler
4999 * compiler warnings about unused functions */
5000 return __Pyx_Print(NULL, 0);
5003 #else /* Python 3 has a print function */
5005 static int __Pyx_PrintOne(PyObject *o) {
5007 PyObject* arg_tuple = PyTuple_New(1);
5008 if (unlikely(!arg_tuple))
5011 PyTuple_SET_ITEM(arg_tuple, 0, o);
5012 res = __Pyx_Print(arg_tuple, 1);
5013 Py_DECREF(arg_tuple);
5019 requires=[printing_utility_code])
5023 #------------------------------------------------------------------------------------
5025 # The following function is based on do_raise() from ceval.c.
5027 raise_utility_code = UtilityCode(
5029 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5032 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5036 /* First, check the traceback argument, replacing None with NULL. */
5037 if (tb == Py_None) {
5041 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5042 PyErr_SetString(PyExc_TypeError,
5043 "raise: arg 3 must be a traceback or None");
5046 /* Next, replace a missing value with None */
5047 if (value == NULL) {
5051 #if PY_VERSION_HEX < 0x02050000
5052 if (!PyClass_Check(type))
5054 if (!PyType_Check(type))
5057 /* Raising an instance. The value should be a dummy. */
5058 if (value != Py_None) {
5059 PyErr_SetString(PyExc_TypeError,
5060 "instance exception may not have a separate value");
5063 /* Normalize to raise <class>, <instance> */
5066 #if PY_VERSION_HEX < 0x02050000
5067 if (PyInstance_Check(type)) {
5068 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5073 PyErr_SetString(PyExc_TypeError,
5074 "raise: exception must be an old-style class or instance");
5078 type = (PyObject*) Py_TYPE(type);
5080 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5081 PyErr_SetString(PyExc_TypeError,
5082 "raise: exception class must be a subclass of BaseException");
5087 __Pyx_ErrRestore(type, value, tb);
5097 #------------------------------------------------------------------------------------
5099 reraise_utility_code = UtilityCode(
5101 static void __Pyx_ReRaise(void); /*proto*/
5104 static void __Pyx_ReRaise(void) {
5105 PyThreadState *tstate = PyThreadState_GET();
5106 PyObject* tmp_type = tstate->curexc_type;
5107 PyObject* tmp_value = tstate->curexc_value;
5108 PyObject* tmp_tb = tstate->curexc_traceback;
5109 tstate->curexc_type = tstate->exc_type;
5110 tstate->curexc_value = tstate->exc_value;
5111 tstate->curexc_traceback = tstate->exc_traceback;
5112 tstate->exc_type = 0;
5113 tstate->exc_value = 0;
5114 tstate->exc_traceback = 0;
5115 Py_XDECREF(tmp_type);
5116 Py_XDECREF(tmp_value);
5121 #------------------------------------------------------------------------------------
5123 arg_type_test_utility_code = UtilityCode(
5125 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5126 const char *name, int exact); /*proto*/
5129 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5130 const char *name, int exact)
5133 PyErr_Format(PyExc_SystemError, "Missing type object");
5136 if (none_allowed && obj == Py_None) return 1;
5138 if (Py_TYPE(obj) == type) return 1;
5141 if (PyObject_TypeCheck(obj, type)) return 1;
5143 PyErr_Format(PyExc_TypeError,
5144 "Argument '%s' has incorrect type (expected %s, got %s)",
5145 name, type->tp_name, Py_TYPE(obj)->tp_name);
5150 #------------------------------------------------------------------------------------
5152 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5153 # many or too few positional arguments were found. This handles
5154 # Py_ssize_t formatting correctly.
5156 raise_argtuple_invalid_utility_code = UtilityCode(
5158 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5159 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5162 static void __Pyx_RaiseArgtupleInvalid(
5163 const char* func_name,
5167 Py_ssize_t num_found)
5169 Py_ssize_t num_expected;
5170 const char *number, *more_or_less;
5172 if (num_found < num_min) {
5173 num_expected = num_min;
5174 more_or_less = "at least";
5176 num_expected = num_max;
5177 more_or_less = "at most";
5180 more_or_less = "exactly";
5182 number = (num_expected == 1) ? "" : "s";
5183 PyErr_Format(PyExc_TypeError,
5184 #if PY_VERSION_HEX < 0x02050000
5185 "%s() takes %s %d positional argument%s (%d given)",
5187 "%s() takes %s %zd positional argument%s (%zd given)",
5189 func_name, more_or_less, num_expected, number, num_found);
5193 raise_keyword_required_utility_code = UtilityCode(
5195 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5198 static INLINE void __Pyx_RaiseKeywordRequired(
5199 const char* func_name,
5202 PyErr_Format(PyExc_TypeError,
5203 #if PY_MAJOR_VERSION >= 3
5204 "%s() needs keyword-only argument %U", func_name, kw_name);
5206 "%s() needs keyword-only argument %s", func_name,
5207 PyString_AS_STRING(kw_name));
5212 raise_double_keywords_utility_code = UtilityCode(
5214 static void __Pyx_RaiseDoubleKeywordsError(
5215 const char* func_name, PyObject* kw_name); /*proto*/
5218 static void __Pyx_RaiseDoubleKeywordsError(
5219 const char* func_name,
5222 PyErr_Format(PyExc_TypeError,
5223 #if PY_MAJOR_VERSION >= 3
5224 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5226 "%s() got multiple values for keyword argument '%s'", func_name,
5227 PyString_AS_STRING(kw_name));
5232 #------------------------------------------------------------------------------------
5234 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5235 # were passed to a function, or if any keywords were passed to a
5236 # function that does not accept them.
5238 keyword_string_check_utility_code = UtilityCode(
5240 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5241 const char* function_name, int kw_allowed); /*proto*/
5244 static INLINE int __Pyx_CheckKeywordStrings(
5246 const char* function_name,
5251 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5252 #if PY_MAJOR_VERSION < 3
5253 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5255 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5257 goto invalid_keyword_type;
5259 if ((!kw_allowed) && unlikely(key))
5260 goto invalid_keyword;
5262 invalid_keyword_type:
5263 PyErr_Format(PyExc_TypeError,
5264 "%s() keywords must be strings", function_name);
5267 PyErr_Format(PyExc_TypeError,
5268 #if PY_MAJOR_VERSION < 3
5269 "%s() got an unexpected keyword argument '%s'",
5270 function_name, PyString_AsString(key));
5272 "%s() got an unexpected keyword argument '%U'",
5273 function_name, key);
5279 #------------------------------------------------------------------------------------
5281 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5282 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5283 # keywords will raise an invalid keyword error.
5285 # Three kinds of errors are checked: 1) non-string keywords, 2)
5286 # unexpected keywords and 3) overlap with positional arguments.
5288 # If num_posargs is greater 0, it denotes the number of positional
5289 # arguments that were passed and that must therefore not appear
5290 # amongst the keywords as well.
5292 # This method does not check for required keyword arguments.
5295 parse_keywords_utility_code = UtilityCode(
5297 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5298 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5299 const char* function_name); /*proto*/
5302 static int __Pyx_ParseOptionalKeywords(
5304 PyObject **argnames[],
5307 Py_ssize_t num_pos_args,
5308 const char* function_name)
5310 PyObject *key = 0, *value = 0;
5313 PyObject*** first_kw_arg = argnames + num_pos_args;
5315 while (PyDict_Next(kwds, &pos, &key, &value)) {
5316 name = first_kw_arg;
5317 while (*name && (**name != key)) name++;
5319 values[name-argnames] = value;
5321 #if PY_MAJOR_VERSION < 3
5322 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5324 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5326 goto invalid_keyword_type;
5328 for (name = first_kw_arg; *name; name++) {
5329 #if PY_MAJOR_VERSION >= 3
5330 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5331 PyUnicode_Compare(**name, key) == 0) break;
5333 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5334 _PyString_Eq(**name, key)) break;
5338 values[name-argnames] = value;
5340 /* unexpected keyword found */
5341 for (name=argnames; name != first_kw_arg; name++) {
5342 if (**name == key) goto arg_passed_twice;
5343 #if PY_MAJOR_VERSION >= 3
5344 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5345 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5347 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5348 _PyString_Eq(**name, key)) goto arg_passed_twice;
5352 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5354 goto invalid_keyword;
5362 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5364 invalid_keyword_type:
5365 PyErr_Format(PyExc_TypeError,
5366 "%s() keywords must be strings", function_name);
5369 PyErr_Format(PyExc_TypeError,
5370 #if PY_MAJOR_VERSION < 3
5371 "%s() got an unexpected keyword argument '%s'",
5372 function_name, PyString_AsString(key));
5374 "%s() got an unexpected keyword argument '%U'",
5375 function_name, key);
5382 #------------------------------------------------------------------------------------
5384 traceback_utility_code = UtilityCode(
5386 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5389 #include "compile.h"
5390 #include "frameobject.h"
5391 #include "traceback.h"
5393 static void __Pyx_AddTraceback(const char *funcname) {
5394 PyObject *py_srcfile = 0;
5395 PyObject *py_funcname = 0;
5396 PyObject *py_globals = 0;
5397 PyObject *empty_string = 0;
5398 PyCodeObject *py_code = 0;
5399 PyFrameObject *py_frame = 0;
5401 #if PY_MAJOR_VERSION < 3
5402 py_srcfile = PyString_FromString(%(FILENAME)s);
5404 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5406 if (!py_srcfile) goto bad;
5408 #if PY_MAJOR_VERSION < 3
5409 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5411 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5415 #if PY_MAJOR_VERSION < 3
5416 py_funcname = PyString_FromString(funcname);
5418 py_funcname = PyUnicode_FromString(funcname);
5421 if (!py_funcname) goto bad;
5422 py_globals = PyModule_GetDict(%(GLOBALS)s);
5423 if (!py_globals) goto bad;
5424 #if PY_MAJOR_VERSION < 3
5425 empty_string = PyString_FromStringAndSize("", 0);
5427 empty_string = PyBytes_FromStringAndSize("", 0);
5429 if (!empty_string) goto bad;
5430 py_code = PyCode_New(
5431 0, /*int argcount,*/
5432 #if PY_MAJOR_VERSION >= 3
5433 0, /*int kwonlyargcount,*/
5436 0, /*int stacksize,*/
5438 empty_string, /*PyObject *code,*/
5439 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5440 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5441 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5442 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5443 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5444 py_srcfile, /*PyObject *filename,*/
5445 py_funcname, /*PyObject *name,*/
5446 %(LINENO)s, /*int firstlineno,*/
5447 empty_string /*PyObject *lnotab*/
5449 if (!py_code) goto bad;
5450 py_frame = PyFrame_New(
5451 PyThreadState_GET(), /*PyThreadState *tstate,*/
5452 py_code, /*PyCodeObject *code,*/
5453 py_globals, /*PyObject *globals,*/
5454 0 /*PyObject *locals*/
5456 if (!py_frame) goto bad;
5457 py_frame->f_lineno = %(LINENO)s;
5458 PyTraceBack_Here(py_frame);
5460 Py_XDECREF(py_srcfile);
5461 Py_XDECREF(py_funcname);
5462 Py_XDECREF(empty_string);
5463 Py_XDECREF(py_code);
5464 Py_XDECREF(py_frame);
5467 'FILENAME': Naming.filename_cname,
5468 'LINENO': Naming.lineno_cname,
5469 'CFILENAME': Naming.cfilenm_cname,
5470 'CLINENO': Naming.clineno_cname,
5471 'GLOBALS': Naming.module_cname,
5472 'EMPTY_TUPLE' : Naming.empty_tuple,
5475 restore_exception_utility_code = UtilityCode(
5477 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5478 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5481 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5482 PyObject *tmp_type, *tmp_value, *tmp_tb;
5483 PyThreadState *tstate = PyThreadState_GET();
5485 #if PY_MAJOR_VERSION >= 3
5486 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5487 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5488 tmp_type = tstate->exc_type;
5489 tmp_value = tstate->exc_value;
5490 tmp_tb = tstate->exc_traceback;
5491 PyErr_NormalizeException(&type, &value, &tb);
5492 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5493 tstate->exc_type = 0;
5494 tstate->exc_value = 0;
5495 tstate->exc_traceback = 0;
5496 PyException_SetContext(value, tmp_value);
5497 Py_DECREF(tmp_type);
5502 tmp_type = tstate->curexc_type;
5503 tmp_value = tstate->curexc_value;
5504 tmp_tb = tstate->curexc_traceback;
5505 tstate->curexc_type = type;
5506 tstate->curexc_value = value;
5507 tstate->curexc_traceback = tb;
5508 Py_XDECREF(tmp_type);
5509 Py_XDECREF(tmp_value);
5513 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5514 PyThreadState *tstate = PyThreadState_GET();
5515 *type = tstate->curexc_type;
5516 *value = tstate->curexc_value;
5517 *tb = tstate->curexc_traceback;
5519 tstate->curexc_type = 0;
5520 tstate->curexc_value = 0;
5521 tstate->curexc_traceback = 0;
5526 #------------------------------------------------------------------------------------
5528 unraisable_exception_utility_code = UtilityCode(
5530 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5533 static void __Pyx_WriteUnraisable(const char *name) {
5534 PyObject *old_exc, *old_val, *old_tb;
5536 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5537 #if PY_MAJOR_VERSION < 3
5538 ctx = PyString_FromString(name);
5540 ctx = PyUnicode_FromString(name);
5542 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5544 PyErr_WriteUnraisable(Py_None);
5546 PyErr_WriteUnraisable(ctx);
5551 requires=[restore_exception_utility_code])
5553 #------------------------------------------------------------------------------------
5555 set_vtable_utility_code = UtilityCode(
5557 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5560 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5561 PyObject *pycobj = 0;
5564 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5567 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5580 #------------------------------------------------------------------------------------
5582 get_vtable_utility_code = UtilityCode(
5584 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5587 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5591 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5594 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5595 if (!*(void **)vtabptr)
5608 #------------------------------------------------------------------------------------
5610 init_string_tab_utility_code = UtilityCode(
5612 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5615 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5617 #if PY_MAJOR_VERSION < 3
5618 if (t->is_unicode && (!t->is_identifier)) {
5619 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5620 } else if (t->intern) {
5621 *t->p = PyString_InternFromString(t->s);
5623 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5625 #else /* Python 3+ has unicode identifiers */
5626 if (t->is_identifier || (t->is_unicode && t->intern)) {
5627 *t->p = PyUnicode_InternFromString(t->s);
5628 } else if (t->is_unicode) {
5629 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5631 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5642 #------------------------------------------------------------------------------------
5644 get_exception_utility_code = UtilityCode(
5646 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5649 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5650 PyObject *tmp_type, *tmp_value, *tmp_tb;
5651 PyThreadState *tstate = PyThreadState_GET();
5652 *type = tstate->curexc_type;
5653 *value = tstate->curexc_value;
5654 *tb = tstate->curexc_traceback;
5655 tstate->curexc_type = 0;
5656 tstate->curexc_value = 0;
5657 tstate->curexc_traceback = 0;
5658 PyErr_NormalizeException(type, value, tb);
5659 if (PyErr_Occurred())
5664 tmp_type = tstate->exc_type;
5665 tmp_value = tstate->exc_value;
5666 tmp_tb = tstate->exc_traceback;
5667 tstate->exc_type = *type;
5668 tstate->exc_value = *value;
5669 tstate->exc_traceback = *tb;
5670 /* Make sure tstate is in a consistent state when we XDECREF
5671 these objects (XDECREF may run arbitrary code). */
5672 Py_XDECREF(tmp_type);
5673 Py_XDECREF(tmp_value);
5685 #------------------------------------------------------------------------------------
5687 reset_exception_utility_code = UtilityCode(
5689 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5690 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5693 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5694 PyThreadState *tstate = PyThreadState_GET();
5695 *type = tstate->exc_type;
5696 *value = tstate->exc_value;
5697 *tb = tstate->exc_traceback;
5703 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5704 PyObject *tmp_type, *tmp_value, *tmp_tb;
5705 PyThreadState *tstate = PyThreadState_GET();
5706 tmp_type = tstate->exc_type;
5707 tmp_value = tstate->exc_value;
5708 tmp_tb = tstate->exc_traceback;
5709 tstate->exc_type = type;
5710 tstate->exc_value = value;
5711 tstate->exc_traceback = tb;
5712 Py_XDECREF(tmp_type);
5713 Py_XDECREF(tmp_value);
5718 #------------------------------------------------------------------------------------
5720 force_init_threads_utility_code = UtilityCode(
5722 #ifndef __PYX_FORCE_INIT_THREADS
5723 #if PY_VERSION_HEX < 0x02040200
5724 #define __PYX_FORCE_INIT_THREADS 1
5726 #define __PYX_FORCE_INIT_THREADS 0
5731 #------------------------------------------------------------------------------------