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
17 from Code import UtilityCode
18 from StringEncoding import EncodedString, escape_byte_string, split_docstring
23 absolute_path_length = 0
25 def relative_position(pos):
27 We embed the relative filename in the generated C file, since we
28 don't want to have to regnerate and compile all the source code
29 whenever the Python install directory moves (which could happen,
30 e.g,. when distributing binaries.)
33 a position tuple -- (absolute filename, line number column position)
41 global absolute_path_length
42 if absolute_path_length==0:
43 absolute_path_length = len(os.path.abspath(os.getcwd()))
44 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
46 def embed_position(pos, docstring):
47 if not Options.embed_pos_in_docstring:
49 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
52 return EncodedString(pos_line)
54 # make sure we can encode the filename in the docstring encoding
55 # otherwise make the docstring a unicode string
56 encoding = docstring.encoding
57 if encoding is not None:
59 encoded_bytes = pos_line.encode(encoding)
60 except UnicodeEncodeError:
64 # reuse the string encoding of the original docstring
65 doc = EncodedString(pos_line)
67 doc = EncodedString(pos_line + u'\n' + docstring)
68 doc.encoding = encoding
72 from Code import CCodeWriter
73 from types import FunctionType
75 def write_func_call(func):
77 if len(args) > 1 and isinstance(args[1], CCodeWriter):
78 # here we annotate the code with this function call
79 # but only if new code is generated
81 marker = ' /* %s -> %s.%s %s */' % (
82 ' ' * code.call_level,
83 node.__class__.__name__,
86 pristine = code.buffer.stream.tell()
88 start = code.buffer.stream.tell()
90 res = func(*args, **kwds)
92 if start == code.buffer.stream.tell():
93 code.buffer.stream.seek(pristine)
95 marker = marker.replace('->', '<-')
99 return func(*args, **kwds)
102 class VerboseCodeWriter(type):
103 # Set this as a metaclass to trace function calls in code.
104 # This slows down code generation and makes much larger files.
105 def __new__(cls, name, bases, attrs):
107 for mname, m in attrs.items():
108 if isinstance(m, FunctionType):
109 attrs[mname] = write_func_call(m)
110 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
114 # pos (string, int, int) Source file position
115 # is_name boolean Is a NameNode
116 # is_literal boolean Is a ConstNode
118 if DebugFlags.debug_trace_code_generation:
119 __metaclass__ = VerboseCodeWriter
125 # All descandants should set child_attrs to a list of the attributes
126 # containing nodes considered "children" in the tree. Each such attribute
127 # can either contain a single node or a list of nodes. See Visitor.py.
130 def __init__(self, pos, **kw):
132 self.__dict__.update(kw)
134 gil_message = "Operation"
137 def _gil_check(self, env):
142 error(self.pos, "%s not allowed without gil" % self.gil_message)
144 def clone_node(self):
145 """Clone the node. This is defined as a shallow copy, except for member lists
146 amongst the child attributes (from get_child_accessors) which are also
147 copied. Lists containing child nodes are thus seen as a way for the node
148 to hold multiple children directly; the list is not treated as a seperate
149 level in the tree."""
150 result = copy.copy(self)
151 for attrname in result.child_attrs:
152 value = getattr(result, attrname)
153 if isinstance(value, list):
154 setattr(result, attrname, [x for x in value])
159 # There are 4 phases of parse tree processing, applied in order to
160 # all the statements in a given scope-block:
162 # (0) analyse_control_flow
163 # Create the control flow tree into which state can be asserted and
166 # (1) analyse_declarations
167 # Make symbol table entries for all declarations at the current
168 # level, both explicit (def, cdef, etc.) and implicit (assignment
169 # to an otherwise undeclared name).
171 # (2) analyse_expressions
172 # Determine the result types of expressions and fill in the
173 # 'type' attribute of each ExprNode. Insert coercion nodes into the
174 # tree where needed to convert to and from Python objects.
175 # Allocate temporary locals for intermediate results. Fill
176 # in the 'result_code' attribute of each ExprNode with a C code
180 # Emit C code for all declarations, statements and expressions.
181 # Recursively applies the 3 processing phases to the bodies of
185 def analyse_control_flow(self, env):
188 def analyse_declarations(self, env):
191 def analyse_expressions(self, env):
192 raise InternalError("analyse_expressions not implemented for %s" % \
193 self.__class__.__name__)
195 def generate_code(self, code):
196 raise InternalError("generate_code not implemented for %s" % \
197 self.__class__.__name__)
199 def annotate(self, code):
200 # mro does the wrong thing
201 if isinstance(self, BlockNode):
202 self.body.annotate(code)
207 except AttributeError:
209 if not self.child_attrs:
212 for attr in self.child_attrs:
213 child = getattr(self, attr)
214 # Sometimes lists, sometimes nodes
217 elif isinstance(child, list):
219 pos = max(pos, c.end_pos())
221 pos = max(pos, child.end_pos())
225 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
227 return "<...nesting level cutoff...>"
228 if encountered is None:
230 if id(self) in encountered:
231 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
232 encountered.add(id(self))
234 def dump_child(x, level):
235 if isinstance(x, Node):
236 return x.dump(level, filter_out, cutoff-1, encountered)
237 elif isinstance(x, list):
238 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
243 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
245 return "<%s (%d)>" % (self.__class__.__name__, id(self))
248 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
249 for key, value in attrs:
250 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
251 res += "%s>" % indent
254 class CompilerDirectivesNode(Node):
256 Sets compiler directives for the children nodes
258 # directives {string:value} A dictionary holding the right value for
259 # *all* possible directives.
261 child_attrs = ["body"]
263 def analyse_control_flow(self, env):
265 env.directives = self.directives
266 self.body.analyse_control_flow(env)
269 def analyse_declarations(self, env):
271 env.directives = self.directives
272 self.body.analyse_declarations(env)
275 def analyse_expressions(self, env):
277 env.directives = self.directives
278 self.body.analyse_expressions(env)
281 def generate_function_definitions(self, env, code):
282 env_old = env.directives
283 code_old = code.globalstate.directives
284 code.globalstate.directives = self.directives
285 self.body.generate_function_definitions(env, code)
286 env.directives = env_old
287 code.globalstate.directives = code_old
289 def generate_execution_code(self, code):
290 old = code.globalstate.directives
291 code.globalstate.directives = self.directives
292 self.body.generate_execution_code(code)
293 code.globalstate.directives = old
295 def annotate(self, code):
296 old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.annotate(code)
299 code.globalstate.directives = old
301 class BlockNode(object):
302 # Mixin class for nodes representing a declaration block.
304 def generate_cached_builtins_decls(self, env, code):
305 entries = env.global_scope().undeclared_cached_builtins
306 for entry in entries:
307 code.globalstate.add_cached_builtin_decl(entry)
311 class StatListNode(Node):
312 # stats a list of StatNode
314 child_attrs = ["stats"]
316 def create_analysed(pos, env, *args, **kw):
317 node = StatListNode(pos, *args, **kw)
318 return node # No node-specific analysis necesarry
319 create_analysed = staticmethod(create_analysed)
321 def analyse_control_flow(self, env):
322 for stat in self.stats:
323 stat.analyse_control_flow(env)
325 def analyse_declarations(self, env):
326 #print "StatListNode.analyse_declarations" ###
327 for stat in self.stats:
328 stat.analyse_declarations(env)
330 def analyse_expressions(self, env):
331 #print "StatListNode.analyse_expressions" ###
332 for stat in self.stats:
333 stat.analyse_expressions(env)
335 def generate_function_definitions(self, env, code):
336 #print "StatListNode.generate_function_definitions" ###
337 for stat in self.stats:
338 stat.generate_function_definitions(env, code)
340 def generate_execution_code(self, code):
341 #print "StatListNode.generate_execution_code" ###
342 for stat in self.stats:
343 code.mark_pos(stat.pos)
344 stat.generate_execution_code(code)
346 def annotate(self, code):
347 for stat in self.stats:
351 class StatNode(Node):
353 # Code generation for statements is split into the following subphases:
355 # (1) generate_function_definitions
356 # Emit C code for the definitions of any structs,
357 # unions, enums and functions defined in the current
360 # (2) generate_execution_code
361 # Emit C code for executable statements.
364 def generate_function_definitions(self, env, code):
367 def generate_execution_code(self, code):
368 raise InternalError("generate_execution_code not implemented for %s" % \
369 self.__class__.__name__)
372 class CDefExternNode(StatNode):
373 # include_file string or None
376 child_attrs = ["body"]
378 def analyse_declarations(self, env):
379 if self.include_file:
380 env.add_include_file(self.include_file)
381 old_cinclude_flag = env.in_cinclude
383 self.body.analyse_declarations(env)
384 env.in_cinclude = old_cinclude_flag
386 def analyse_expressions(self, env):
389 def generate_execution_code(self, code):
392 def annotate(self, code):
393 self.body.annotate(code)
396 class CDeclaratorNode(Node):
397 # Part of a C declaration.
399 # Processing during analyse_declarations phase:
402 # Returns (name, type) pair where name is the
403 # CNameDeclaratorNode of the name being declared
404 # and type is the type it is being declared as.
406 # calling_convention string Calling convention of CFuncDeclaratorNode
407 # for which this is a base
411 calling_convention = ""
414 class CNameDeclaratorNode(CDeclaratorNode):
415 # name string The Pyrex name being declared
416 # cname string or None C name, if specified
417 # default ExprNode or None the value assigned on declaration
419 child_attrs = ['default']
423 def analyse(self, base_type, env, nonempty = 0):
424 if nonempty and self.name == '':
425 # May have mistaken the name for the type.
426 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
427 error(self.pos, "Missing argument name")
428 elif base_type.is_void:
429 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
431 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
432 base_type = py_object_type
433 self.type = base_type
434 return self, base_type
436 class CPtrDeclaratorNode(CDeclaratorNode):
437 # base CDeclaratorNode
439 child_attrs = ["base"]
441 def analyse(self, base_type, env, nonempty = 0):
442 if base_type.is_pyobject:
444 "Pointer base type cannot be a Python object")
445 ptr_type = PyrexTypes.c_ptr_type(base_type)
446 return self.base.analyse(ptr_type, env, nonempty = nonempty)
448 class CArrayDeclaratorNode(CDeclaratorNode):
449 # base CDeclaratorNode
452 child_attrs = ["base", "dimension"]
454 def analyse(self, base_type, env, nonempty = 0):
456 self.dimension.analyse_const_expression(env)
457 if not self.dimension.type.is_int:
458 error(self.dimension.pos, "Array dimension not integer")
459 size = self.dimension.get_constant_c_result_code()
468 if not base_type.is_complete():
470 "Array element type '%s' is incomplete" % base_type)
471 if base_type.is_pyobject:
473 "Array element cannot be a Python object")
474 if base_type.is_cfunction:
476 "Array element cannot be a function")
477 array_type = PyrexTypes.c_array_type(base_type, size)
478 return self.base.analyse(array_type, env, nonempty = nonempty)
481 class CFuncDeclaratorNode(CDeclaratorNode):
482 # base CDeclaratorNode
483 # args [CArgDeclNode]
484 # has_varargs boolean
485 # exception_value ConstNode
486 # exception_check boolean True if PyErr_Occurred check needed
487 # nogil boolean Can be called without gil
488 # with_gil boolean Acquire gil around function body
490 child_attrs = ["base", "args", "exception_value"]
493 optional_arg_count = 0
495 def analyse(self, return_type, env, nonempty = 0):
499 for arg_node in self.args:
500 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
501 name = name_declarator.name
502 if name_declarator.cname:
504 "Function argument cannot have C name specification")
505 # Turn *[] argument into **
507 type = PyrexTypes.c_ptr_type(type.base_type)
508 # Catch attempted C-style func(void) decl
510 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
511 func_type_args.append(
512 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
514 self.optional_arg_count += 1
515 elif self.optional_arg_count:
516 error(self.pos, "Non-default argument follows default argument")
518 if self.optional_arg_count:
519 scope = StructOrUnionScope()
520 arg_count_member = '%sn' % Naming.pyrex_prefix
521 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
522 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
523 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
524 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
525 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
530 cname = struct_cname)
531 self.op_args_struct.defined_in_pxd = 1
532 self.op_args_struct.used = 1
536 if self.exception_check == '+':
537 env.add_include_file('stdexcept')
538 if return_type.is_pyobject \
539 and (self.exception_value or self.exception_check) \
540 and self.exception_check != '+':
542 "Exception clause not allowed for function returning Python object")
544 if self.exception_value:
545 self.exception_value.analyse_const_expression(env)
546 exc_val = self.exception_value.get_constant_c_result_code()
547 if self.exception_check == '+':
548 exc_val_type = self.exception_value.type
549 if not exc_val_type.is_error and \
550 not exc_val_type.is_pyobject and \
551 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
552 error(self.exception_value.pos,
553 "Exception value must be a Python exception or cdef function with no arguments.")
555 if not return_type.assignable_from(self.exception_value.type):
556 error(self.exception_value.pos,
557 "Exception value incompatible with function return type")
558 exc_check = self.exception_check
559 if return_type.is_array:
561 "Function cannot return an array")
562 if return_type.is_cfunction:
564 "Function cannot return a function")
565 func_type = PyrexTypes.CFuncType(
566 return_type, func_type_args, self.has_varargs,
567 optional_arg_count = self.optional_arg_count,
568 exception_value = exc_val, exception_check = exc_check,
569 calling_convention = self.base.calling_convention,
570 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
571 if self.optional_arg_count:
572 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
573 callspec = env.directives['callspec']
575 current = func_type.calling_convention
576 if current and current != callspec:
577 error(self.pos, "cannot have both '%s' and '%s' "
578 "calling conventions" % (current, callspec))
579 func_type.calling_convention = callspec
580 return self.base.analyse(func_type, env)
583 class CArgDeclNode(Node):
584 # Item in a function declaration argument list.
586 # base_type CBaseTypeNode
587 # declarator CDeclaratorNode
588 # not_none boolean Tagged with 'not None'
589 # default ExprNode or None
590 # default_value PyObjectConst constant for default value
591 # is_self_arg boolean Is the "self" arg of an extension type method
592 # is_kw_only boolean Is a keyword-only argument
594 child_attrs = ["base_type", "declarator", "default"]
599 name_declarator = None
602 def analyse(self, env, nonempty = 0):
603 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
604 if self.type is None:
605 # The parser may missinterpret names as types...
607 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
609 self.declarator.name = self.base_type.name
610 self.base_type.name = None
611 self.base_type.is_basic_c_type = False
614 could_be_name = False
615 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
616 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
617 self.declarator.name = self.base_type.arg_name
618 return self.declarator.analyse(base_type, env, nonempty = nonempty)
620 return self.name_declarator, self.type
622 def calculate_default_value_code(self, code):
623 if self.default_value is None:
625 if self.default.is_literal:
626 # will not output any code, just assign the result_code
627 self.default.generate_evaluation_code(code)
628 return self.type.cast_code(self.default.result())
629 self.default_value = code.get_argument_default_const(self.type)
630 return self.default_value
632 def annotate(self, code):
634 self.default.annotate(code)
637 class CBaseTypeNode(Node):
638 # Abstract base class for C base type nodes.
640 # Processing during analyse_declarations phase:
647 class CAnalysedBaseTypeNode(Node):
652 def analyse(self, env, could_be_name = False):
655 class CSimpleBaseTypeNode(CBaseTypeNode):
657 # module_path [string] Qualifying name components
658 # is_basic_c_type boolean
662 # is_self_arg boolean Is self argument of C method
665 arg_name = None # in case the argument name was interpreted as a type
667 def analyse(self, env, could_be_name = False):
668 # Return type descriptor.
669 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
671 if self.is_basic_c_type:
672 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
674 error(self.pos, "Unrecognised type modifier combination")
675 elif self.name == "object" and not self.module_path:
676 type = py_object_type
677 elif self.name is None:
678 if self.is_self_arg and env.is_c_class_scope:
679 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
680 type = env.parent_type
682 type = py_object_type
685 scope = env.find_imported_module(self.module_path, self.pos)
689 if scope.is_c_class_scope:
690 scope = scope.global_scope()
691 entry = scope.lookup(self.name)
692 if entry and entry.is_type:
695 if self.is_self_arg and env.is_c_class_scope:
696 type = env.parent_type
698 type = py_object_type
699 self.arg_name = self.name
701 error(self.pos, "'%s' is not a type identifier" % self.name)
703 if not type.is_numeric or type.is_complex:
704 error(self.pos, "can only complexify c numeric types")
705 type = PyrexTypes.CComplexType(type)
706 type.create_declaration_utility_code(env)
710 return PyrexTypes.error_type
712 class CBufferAccessTypeNode(CBaseTypeNode):
714 # positional_args [ExprNode] List of positional arguments
715 # keyword_args DictNode Keyword arguments
716 # base_type_node CBaseTypeNode
719 # type PyrexType.BufferType ...containing the right options
722 child_attrs = ["base_type_node", "positional_args",
723 "keyword_args", "dtype_node"]
729 def analyse(self, env, could_be_name = False):
730 base_type = self.base_type_node.analyse(env)
731 if base_type.is_error: return base_type
734 options = Buffer.analyse_buffer_options(
737 self.positional_args,
739 base_type.buffer_defaults)
741 self.type = PyrexTypes.BufferType(base_type, **options)
744 class CComplexBaseTypeNode(CBaseTypeNode):
745 # base_type CBaseTypeNode
746 # declarator CDeclaratorNode
748 child_attrs = ["base_type", "declarator"]
750 def analyse(self, env, could_be_name = False):
751 base = self.base_type.analyse(env, could_be_name)
752 _, type = self.declarator.analyse(base, env)
756 class CVarDefNode(StatNode):
757 # C variable definition or forward/extern function declaration.
759 # visibility 'private' or 'public' or 'extern'
760 # base_type CBaseTypeNode
761 # declarators [CDeclaratorNode]
764 # need_properties [entry]
766 # decorators [cython.locals(...)] or None
767 # directive_locals { string : NameNode } locals defined by cython.locals(...)
769 child_attrs = ["base_type", "declarators"]
773 directive_locals = {}
775 def analyse_declarations(self, env, dest_scope = None):
778 self.dest_scope = dest_scope
779 base_type = self.base_type.analyse(env)
781 # If the field is an external typedef, we cannot be sure about the type,
782 # so do conversion ourself rather than rely on the CPython mechanism (through
783 # a property; made in AnalyseDeclarationsTransform).
784 if (dest_scope.is_c_class_scope
785 and self.visibility == 'public'
786 and base_type.is_pyobject
787 and (base_type.is_builtin_type or base_type.is_extension_type)):
788 self.need_properties = []
790 visibility = 'private'
792 need_property = False
793 visibility = self.visibility
795 for declarator in self.declarators:
796 name_declarator, type = declarator.analyse(base_type, env)
797 if not type.is_complete():
798 if not (self.visibility == 'extern' and type.is_array):
799 error(declarator.pos,
800 "Variable type '%s' is incomplete" % type)
801 if self.visibility == 'extern' and type.is_pyobject:
802 error(declarator.pos,
803 "Python object cannot be declared extern")
804 name = name_declarator.name
805 cname = name_declarator.cname
807 error(declarator.pos, "Missing name in declaration.")
809 if type.is_cfunction:
810 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
811 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
813 if entry is not None:
814 entry.directive_locals = self.directive_locals
816 if self.directive_locals:
817 s.error("Decorators can only be followed by functions")
818 if self.in_pxd and self.visibility != 'extern':
820 "Only 'extern' C variable declaration allowed in .pxd file")
821 entry = dest_scope.declare_var(name, type, declarator.pos,
822 cname = cname, visibility = visibility, is_cdef = 1)
824 self.need_properties.append(entry)
825 entry.needs_property = 1
828 class CStructOrUnionDefNode(StatNode):
830 # cname string or None
831 # kind "struct" or "union"
832 # typedef_flag boolean
833 # visibility "public" or "private"
835 # attributes [CVarDefNode] or None
839 child_attrs = ["attributes"]
841 def analyse_declarations(self, env):
843 if self.visibility == 'extern' and self.packed:
844 error(self.pos, "Cannot declare extern struct as 'packed'")
845 if self.attributes is not None:
846 scope = StructOrUnionScope(self.name)
847 self.entry = env.declare_struct_or_union(
848 self.name, self.kind, scope, self.typedef_flag, self.pos,
849 self.cname, visibility = self.visibility, packed = self.packed)
850 if self.attributes is not None:
851 if self.in_pxd and not env.in_cinclude:
852 self.entry.defined_in_pxd = 1
853 for attr in self.attributes:
854 attr.analyse_declarations(env, scope)
855 if self.visibility != 'extern':
856 need_typedef_indirection = False
857 for attr in scope.var_entries:
860 type = type.base_type
861 if type == self.entry.type:
862 error(attr.pos, "Struct cannot contain itself as a member.")
863 if self.typedef_flag:
865 type = type.base_type
866 if type == self.entry.type:
867 need_typedef_indirection = True
868 if need_typedef_indirection:
869 # C can't handle typedef structs that refer to themselves.
870 struct_entry = self.entry
871 self.entry = env.declare_typedef(
872 self.name, struct_entry.type, self.pos,
873 cname = self.cname, visibility='ignore')
874 struct_entry.type.typedef_flag = False
875 # FIXME: this might be considered a hack ;-)
876 struct_entry.cname = struct_entry.type.cname = \
877 '_' + self.entry.type.typedef_cname
879 def analyse_expressions(self, env):
882 def generate_execution_code(self, code):
886 class CEnumDefNode(StatNode):
887 # name string or None
888 # cname string or None
889 # items [CEnumDefItemNode]
890 # typedef_flag boolean
891 # visibility "public" or "private"
895 child_attrs = ["items"]
897 def analyse_declarations(self, env):
898 self.entry = env.declare_enum(self.name, self.pos,
899 cname = self.cname, typedef_flag = self.typedef_flag,
900 visibility = self.visibility)
901 if self.items is not None:
902 if self.in_pxd and not env.in_cinclude:
903 self.entry.defined_in_pxd = 1
904 for item in self.items:
905 item.analyse_declarations(env, self.entry)
907 def generate_execution_code(self, code):
908 if self.visibility == 'public':
909 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
910 for item in self.entry.enum_values:
911 code.putln("%s = PyInt_FromLong(%s); %s" % (
914 code.error_goto_if_null(temp, item.pos)))
915 code.put_gotref(temp)
916 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
920 code.error_goto(item.pos)))
921 code.put_decref_clear(temp, PyrexTypes.py_object_type)
922 code.funcstate.release_temp(temp)
925 class CEnumDefItemNode(StatNode):
927 # cname string or None
928 # value ExprNode or None
930 child_attrs = ["value"]
932 def analyse_declarations(self, env, enum_entry):
934 self.value.analyse_const_expression(env)
935 if not self.value.type.is_int:
936 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
937 self.value.analyse_const_expression(env)
938 entry = env.declare_const(self.name, enum_entry.type,
939 self.value, self.pos, cname = self.cname,
940 visibility = enum_entry.visibility)
941 enum_entry.enum_values.append(entry)
944 class CTypeDefNode(StatNode):
945 # base_type CBaseTypeNode
946 # declarator CDeclaratorNode
947 # visibility "public" or "private"
950 child_attrs = ["base_type", "declarator"]
952 def analyse_declarations(self, env):
953 base = self.base_type.analyse(env)
954 name_declarator, type = self.declarator.analyse(base, env)
955 name = name_declarator.name
956 cname = name_declarator.cname
957 entry = env.declare_typedef(name, type, self.pos,
958 cname = cname, visibility = self.visibility)
959 if self.in_pxd and not env.in_cinclude:
960 entry.defined_in_pxd = 1
962 def analyse_expressions(self, env):
964 def generate_execution_code(self, code):
968 class FuncDefNode(StatNode, BlockNode):
969 # Base class for function definition nodes.
971 # return_type PyrexType
972 # #filename string C name of filename string const
974 # needs_closure boolean Whether or not this function has inner functions/classes/yield
975 # directive_locals { string : NameNode } locals defined by cython.locals(...)
979 needs_closure = False
981 def analyse_default_values(self, env):
982 genv = env.global_scope()
983 for arg in self.args:
986 arg.default.analyse_types(env)
987 arg.default = arg.default.coerce_to(arg.type, genv)
990 "This argument cannot have a default value")
993 def need_gil_acquisition(self, lenv):
996 def create_local_scope(self, env):
998 while env.is_py_class_scope or env.is_c_class_scope:
999 env = env.outer_scope
1000 if self.needs_closure:
1001 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1003 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1004 lenv.return_type = self.return_type
1005 type = self.entry.type
1006 if type.is_cfunction:
1007 lenv.nogil = type.nogil and not type.with_gil
1008 self.local_scope = lenv
1009 lenv.directives = env.directives
1012 def generate_function_definitions(self, env, code):
1015 lenv = self.local_scope
1017 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1018 self.entry.scope.is_c_class_scope)
1020 # Generate C code for header and body of function
1021 code.enter_cfunc_scope()
1022 code.return_from_error_cleanup_label = code.new_label()
1024 # ----- Top-level constants used by this function
1025 code.mark_pos(self.pos)
1026 self.generate_cached_builtins_decls(lenv, code)
1027 # ----- Function header
1030 self.py_func.generate_function_header(code,
1031 with_pymethdef = env.is_py_class_scope,
1033 self.generate_function_header(code,
1034 with_pymethdef = env.is_py_class_scope)
1035 # ----- Local variable declarations
1036 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1037 self.generate_argument_declarations(lenv, code)
1038 if self.needs_closure:
1039 code.putln("/* TODO: declare and create scope object */")
1040 code.put_var_declarations(lenv.var_entries)
1042 if not self.return_type.is_void:
1043 if self.return_type.is_pyobject:
1047 (self.return_type.declaration_code(
1048 Naming.retval_cname),
1050 tempvardecl_code = code.insertion_point()
1051 self.generate_keyword_list(code)
1052 # ----- Extern library function declarations
1053 lenv.generate_library_function_declarations(code)
1054 # ----- GIL acquisition
1055 acquire_gil = self.need_gil_acquisition(lenv)
1057 env.use_utility_code(force_init_threads_utility_code)
1058 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1059 # ----- Automatic lead-ins for certain special functions
1061 code.put_setup_refcount_context(self.entry.name)
1062 if is_getbuffer_slot:
1063 self.getbuffer_init(code)
1064 # ----- Fetch arguments
1065 self.generate_argument_parsing_code(env, code)
1066 # If an argument is assigned to in the body, we must
1067 # incref it to properly keep track of refcounts.
1068 for entry in lenv.arg_entries:
1069 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1070 code.put_var_incref(entry)
1071 # ----- Initialise local variables
1072 for entry in lenv.var_entries:
1073 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1074 code.put_init_var_to_py_none(entry)
1075 # ----- Initialise local buffer auxiliary variables
1076 for entry in lenv.var_entries + lenv.arg_entries:
1077 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1078 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1079 # ----- Check and convert arguments
1080 self.generate_argument_type_tests(code)
1081 # ----- Acquire buffer arguments
1082 for entry in lenv.arg_entries:
1083 if entry.type.is_buffer:
1084 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1085 # ----- Function body
1086 self.body.generate_execution_code(code)
1087 # ----- Default return value
1089 if self.return_type.is_pyobject:
1090 #if self.return_type.is_extension_type:
1091 # lhs = "(PyObject *)%s" % Naming.retval_cname
1093 lhs = Naming.retval_cname
1094 code.put_init_to_py_none(lhs, self.return_type)
1096 val = self.return_type.default_value
1098 code.putln("%s = %s;" % (Naming.retval_cname, val))
1099 # ----- Error cleanup
1100 if code.error_label in code.labels_used:
1101 code.put_goto(code.return_label)
1102 code.put_label(code.error_label)
1103 for cname, type in code.funcstate.all_managed_temps():
1104 code.put_xdecref(cname, type)
1106 # Clean up buffers -- this calls a Python function
1107 # so need to save and restore error state
1108 buffers_present = len(lenv.buffer_entries) > 0
1110 code.globalstate.use_utility_code(restore_exception_utility_code)
1111 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1112 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1113 for entry in lenv.buffer_entries:
1114 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1115 #code.putln("%s = 0;" % entry.cname)
1116 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1118 err_val = self.error_value()
1119 exc_check = self.caller_will_check_exceptions()
1120 if err_val is not None or exc_check:
1121 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1123 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1124 % self.entry.qualified_name, 0)
1126 '__Pyx_WriteUnraisable("%s");' %
1127 self.entry.qualified_name)
1128 env.use_utility_code(unraisable_exception_utility_code)
1129 env.use_utility_code(restore_exception_utility_code)
1130 default_retval = self.return_type.default_value
1131 if err_val is None and default_retval:
1132 err_val = default_retval
1133 if err_val is not None:
1136 Naming.retval_cname,
1139 if is_getbuffer_slot:
1140 self.getbuffer_error_cleanup(code)
1142 # If we are using the non-error cleanup section we should
1143 # jump past it if we have an error. The if-test below determine
1144 # whether this section is used.
1145 if buffers_present or is_getbuffer_slot:
1146 code.put_goto(code.return_from_error_cleanup_label)
1149 # ----- Non-error return cleanup
1150 # If you add anything here, remember to add a condition to the
1151 # if-test above in the error block (so that it can jump past this
1153 code.put_label(code.return_label)
1154 for entry in lenv.buffer_entries:
1156 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1157 if is_getbuffer_slot:
1158 self.getbuffer_normal_cleanup(code)
1159 # ----- Return cleanup for both error and no-error return
1160 code.put_label(code.return_from_error_cleanup_label)
1161 if not Options.init_local_none:
1162 for entry in lenv.var_entries:
1163 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1164 entry.xdecref_cleanup = 1
1165 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1166 # Decref any increfed args
1167 for entry in lenv.arg_entries:
1168 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1169 code.put_var_decref(entry)
1171 # code.putln("/* TODO: decref scope object */")
1173 # This code is duplicated in ModuleNode.generate_module_init_func
1175 default_retval = self.return_type.default_value
1176 err_val = self.error_value()
1177 if err_val is None and default_retval:
1178 err_val = default_retval
1179 if self.return_type.is_pyobject:
1180 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1182 code.put_finish_refcount_context()
1184 if self.entry.is_special and self.entry.name == "__hash__":
1185 # Returning -1 for __hash__ is supposed to signal an error
1186 # We do as Python instances and coerce -1 into -2.
1187 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1190 code.putln("PyGILState_Release(_save);")
1192 if not self.return_type.is_void:
1193 code.putln("return %s;" % Naming.retval_cname)
1196 # ----- Go back and insert temp variable declarations
1197 tempvardecl_code.put_temp_declarations(code.funcstate)
1198 # ----- Python version
1199 code.exit_cfunc_scope()
1201 self.py_func.generate_function_definitions(env, code)
1202 self.generate_wrapper_functions(code)
1204 def declare_argument(self, env, arg):
1205 if arg.type.is_void:
1206 error(arg.pos, "Invalid use of 'void'")
1207 elif not arg.type.is_complete() and not arg.type.is_array:
1209 "Argument type '%s' is incomplete" % arg.type)
1210 return env.declare_arg(arg.name, arg.type, arg.pos)
1212 def generate_wrapper_functions(self, code):
1215 def generate_execution_code(self, code):
1216 # Evaluate and store argument default values
1217 for arg in self.args:
1218 default = arg.default
1220 if not default.is_literal:
1221 default.generate_evaluation_code(code)
1222 default.make_owned_reference(code)
1223 result = default.result_as(arg.type)
1226 arg.calculate_default_value_code(code),
1228 if arg.type.is_pyobject:
1229 code.put_giveref(default.result())
1230 default.generate_post_assignment_code(code)
1231 default.free_temps(code)
1232 # For Python class methods, create and store function object
1234 self.assmt.generate_execution_code(code)
1237 # Special code for the __getbuffer__ function
1239 def getbuffer_init(self, code):
1240 info = self.local_scope.arg_entries[1].cname
1241 # Python 3.0 betas have a bug in memoryview which makes it call
1242 # getbuffer with a NULL parameter. For now we work around this;
1243 # the following line should be removed when this bug is fixed.
1244 code.putln("if (%s == NULL) return 0;" % info)
1245 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1246 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1248 def getbuffer_error_cleanup(self, code):
1249 info = self.local_scope.arg_entries[1].cname
1250 code.put_gotref("%s->obj" % info)
1251 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1254 def getbuffer_normal_cleanup(self, code):
1255 info = self.local_scope.arg_entries[1].cname
1256 code.putln("if (%s->obj == Py_None) {" % info)
1257 code.put_gotref("Py_None")
1258 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1261 class CFuncDefNode(FuncDefNode):
1262 # C function definition.
1264 # modifiers ['inline']
1265 # visibility 'private' or 'public' or 'extern'
1266 # base_type CBaseTypeNode
1267 # declarator CDeclaratorNode
1270 # decorators [DecoratorNode] list of decorators
1272 # with_gil boolean Acquire GIL around body
1274 # py_func wrapper for calling from Python
1275 # overridable whether or not this is a cpdef function
1276 # inline_in_pxd whether this is an inline function in a pxd file
1278 child_attrs = ["base_type", "declarator", "body", "py_func"]
1280 inline_in_pxd = False
1282 directive_locals = {}
1284 def unqualified_name(self):
1285 return self.entry.name
1287 def analyse_declarations(self, env):
1288 directive_locals = self.directive_locals = env.directives['locals']
1289 base_type = self.base_type.analyse(env)
1290 # The 2 here is because we need both function and argument names.
1291 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1292 if not type.is_cfunction:
1294 "Suite attached to non-function declaration")
1295 # Remember the actual type according to the function header
1296 # written here, because the type in the symbol table entry
1297 # may be different if we're overriding a C method inherited
1298 # from the base type of an extension type.
1300 type.is_overridable = self.overridable
1301 declarator = self.declarator
1302 while not hasattr(declarator, 'args'):
1303 declarator = declarator.base
1304 self.args = declarator.args
1305 for formal_arg, type_arg in zip(self.args, type.args):
1306 formal_arg.type = type_arg.type
1307 formal_arg.name = type_arg.name
1308 formal_arg.cname = type_arg.cname
1309 name = name_declarator.name
1310 cname = name_declarator.cname
1311 self.entry = env.declare_cfunction(
1312 name, type, self.pos,
1313 cname = cname, visibility = self.visibility,
1314 defining = self.body is not None,
1315 api = self.api, modifiers = self.modifiers)
1316 self.entry.inline_func_in_pxd = self.inline_in_pxd
1317 self.return_type = type.return_type
1319 if self.overridable and not env.is_module_scope:
1320 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1321 # An error will be produced in the cdef function
1322 self.overridable = False
1324 if self.overridable:
1326 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1327 self.py_func = DefNode(pos = self.pos,
1328 name = self.entry.name,
1331 starstar_arg = None,
1333 body = py_func_body,
1335 self.py_func.is_module_scope = env.is_module_scope
1336 self.py_func.analyse_declarations(env)
1337 self.entry.as_variable = self.py_func.entry
1338 # Reset scope entry the above cfunction
1339 env.entries[name] = self.entry
1340 if not env.is_module_scope or Options.lookup_module_cpdef:
1341 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1342 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1344 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1346 args = self.type.args
1347 if omit_optional_args:
1348 args = args[:len(args) - self.type.optional_arg_count]
1349 arg_names = [arg.name for arg in args]
1351 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1353 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1354 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1355 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1356 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)
1357 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1359 def declare_arguments(self, env):
1360 for arg in self.type.args:
1362 error(arg.pos, "Missing argument name")
1363 self.declare_argument(env, arg)
1365 def need_gil_acquisition(self, lenv):
1366 return self.type.with_gil
1368 def gil_check(self, env):
1370 with_gil = type.with_gil
1371 if type.nogil and not with_gil:
1372 if type.return_type.is_pyobject:
1374 "Function with Python return type cannot be declared nogil")
1375 for entry in env.var_entries:
1376 if entry.type.is_pyobject:
1377 error(self.pos, "Function declared nogil has Python locals or temporaries")
1379 def analyse_expressions(self, env):
1380 self.local_scope.directives = env.directives
1381 if self.py_func is not None:
1382 # this will also analyse the default values
1383 self.py_func.analyse_expressions(env)
1385 self.analyse_default_values(env)
1387 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1390 visibility = self.entry.visibility
1391 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1392 arg_decls.append(arg.declaration_code())
1393 if with_dispatch and self.overridable:
1394 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1395 if type.optional_arg_count and with_opt_args:
1396 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1397 if type.has_varargs:
1398 arg_decls.append("...")
1400 arg_decls = ["void"]
1402 cname = self.entry.func_cname
1403 entity = type.function_header_code(cname, ', '.join(arg_decls))
1404 if visibility == 'public':
1405 dll_linkage = "DL_EXPORT"
1408 header = self.return_type.declaration_code(entity,
1409 dll_linkage = dll_linkage)
1410 if visibility == 'extern':
1411 storage_class = "%s " % Naming.extern_c_macro
1412 elif visibility == 'public':
1415 storage_class = "static "
1416 code.putln("%s%s %s {" % (
1418 ' '.join(self.modifiers).upper(), # macro forms
1421 def generate_argument_declarations(self, env, code):
1422 for arg in self.args:
1424 result = arg.calculate_default_value_code(code)
1425 code.putln('%s = %s;' % (
1426 arg.type.declaration_code(arg.cname), result))
1428 def generate_keyword_list(self, code):
1431 def generate_argument_parsing_code(self, env, code):
1433 if self.type.optional_arg_count:
1434 code.putln('if (%s) {' % Naming.optional_args_cname)
1435 for arg in self.args:
1437 # FIXME: simple name prefixing doesn't work when
1438 # argument name mangling is in place
1439 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1440 declarator = arg.declarator
1441 while not hasattr(declarator, 'name'):
1442 declarator = declarator.base
1443 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1445 for _ in range(self.type.optional_arg_count):
1449 def generate_argument_conversion_code(self, code):
1452 def generate_argument_type_tests(self, code):
1453 # Generate type tests for args whose type in a parent
1454 # class is a supertype of the declared type.
1455 for arg in self.type.args:
1456 if arg.needs_type_test:
1457 self.generate_arg_type_test(arg, code)
1459 def generate_arg_type_test(self, arg, code):
1460 # Generate type test for one argument.
1461 if arg.type.typeobj_is_available():
1462 typeptr_cname = arg.type.typeptr_cname
1463 arg_code = "((PyObject *)%s)" % arg.cname
1465 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1470 type.is_builtin_type,
1471 code.error_goto(arg.pos)))
1473 error(arg.pos, "Cannot test type of extern C class "
1474 "without type object name specification")
1476 def error_value(self):
1477 if self.return_type.is_pyobject:
1481 return self.entry.type.exception_value
1483 def caller_will_check_exceptions(self):
1484 return self.entry.type.exception_check
1486 def generate_wrapper_functions(self, code):
1487 # If the C signature of a function has changed, we need to generate
1488 # wrappers to put in the slots here.
1491 func_type = entry.type
1492 while entry.prev_entry is not None:
1494 entry = entry.prev_entry
1495 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1497 self.generate_function_header(code,
1499 with_dispatch = entry.type.is_overridable,
1500 with_opt_args = entry.type.optional_arg_count,
1501 cname = entry.func_cname)
1502 if not self.return_type.is_void:
1504 args = self.type.args
1505 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1506 if entry.type.is_overridable:
1507 arglist.append(Naming.skip_dispatch_cname)
1508 elif func_type.is_overridable:
1510 if entry.type.optional_arg_count:
1511 arglist.append(Naming.optional_args_cname)
1512 elif func_type.optional_arg_count:
1513 arglist.append('NULL')
1514 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1518 class PyArgDeclNode(Node):
1519 # Argument which must be a Python object (used
1520 # for * and ** arguments).
1523 # entry Symtab.Entry
1527 class DecoratorNode(Node):
1530 # decorator NameNode or CallNode
1531 child_attrs = ['decorator']
1534 class DefNode(FuncDefNode):
1535 # A Python function definition.
1537 # name string the Python name of the function
1538 # decorators [DecoratorNode] list of decorators
1539 # args [CArgDeclNode] formal arguments
1540 # star_arg PyArgDeclNode or None * argument
1541 # starstar_arg PyArgDeclNode or None ** argument
1542 # doc EncodedString or None
1545 # The following subnode is constructed internally
1546 # when the def statement is inside a Python class definition.
1548 # assmt AssignmentNode Function construction/assignment
1550 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1554 num_required_kw_args = 0
1555 reqd_kw_flags_cname = "0"
1561 def __init__(self, pos, **kwds):
1562 FuncDefNode.__init__(self, pos, **kwds)
1564 for arg in self.args:
1571 self.num_kwonly_args = k
1572 self.num_required_kw_args = rk
1573 self.num_required_args = r
1575 def as_cfunction(self, cfunc=None, scope=None):
1577 error(self.star_arg.pos, "cdef function cannot have star argument")
1578 if self.starstar_arg:
1579 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1582 for formal_arg in self.args:
1583 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1584 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1586 type = py_object_type,
1587 pos = formal_arg.pos))
1588 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1590 has_varargs = False,
1591 exception_value = None,
1592 exception_check = False,
1595 is_overridable = True)
1596 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1598 cfunc_type = cfunc.type
1599 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1600 error(self.pos, "wrong number of arguments")
1601 error(declarator.pos, "previous declaration here")
1602 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1603 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1604 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1605 formal_arg.type = type_arg.type
1606 formal_arg.name_declarator = name_declarator
1608 if cfunc_type.exception_value is None:
1609 exception_value = None
1611 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1612 declarator = CFuncDeclaratorNode(self.pos,
1613 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1615 has_varargs = False,
1616 exception_check = cfunc_type.exception_check,
1617 exception_value = exception_value,
1618 with_gil = cfunc_type.with_gil,
1619 nogil = cfunc_type.nogil)
1620 return CFuncDefNode(self.pos,
1622 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1623 declarator = declarator,
1626 overridable = cfunc_type.is_overridable,
1628 with_gil = cfunc_type.with_gil,
1629 nogil = cfunc_type.nogil,
1630 visibility = 'private',
1632 directive_locals = getattr(cfunc, 'directive_locals', {}))
1634 def analyse_declarations(self, env):
1635 directive_locals = self.directive_locals = env.directives['locals']
1636 for arg in self.args:
1637 if hasattr(arg, 'name'):
1639 name_declarator = None
1641 base_type = arg.base_type.analyse(env)
1642 name_declarator, type = \
1643 arg.declarator.analyse(base_type, env)
1644 arg.name = name_declarator.name
1645 if arg.name in directive_locals:
1646 type_node = directive_locals[arg.name]
1647 other_type = type_node.analyse_as_type(env)
1648 if other_type is None:
1649 error(type_node.pos, "Not a type")
1650 elif (type is not PyrexTypes.py_object_type
1651 and not type.same_as(other_type)):
1652 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1653 error(type_node.pos, "Previous declaration here")
1656 if name_declarator and name_declarator.cname:
1658 "Python function argument cannot have C name specification")
1659 arg.type = type.as_argument_type()
1661 arg.needs_conversion = 0
1662 arg.needs_type_test = 0
1664 if arg.not_none and not arg.type.is_extension_type:
1666 "Only extension type arguments can have 'not None'")
1667 self.declare_pyfunction(env)
1668 self.analyse_signature(env)
1669 self.return_type = self.entry.signature.return_type()
1671 def analyse_signature(self, env):
1672 any_type_tests_needed = 0
1673 if self.entry.is_special:
1674 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1675 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1676 # Use the simpler calling signature for zero- and one-argument functions.
1677 if self.entry.signature is TypeSlots.pyfunction_signature:
1678 if len(self.args) == 0:
1679 self.entry.signature = TypeSlots.pyfunction_noargs
1680 elif len(self.args) == 1:
1681 if self.args[0].default is None and not self.args[0].kw_only:
1682 self.entry.signature = TypeSlots.pyfunction_onearg
1683 elif self.entry.signature is TypeSlots.pymethod_signature:
1684 if len(self.args) == 1:
1685 self.entry.signature = TypeSlots.unaryfunc
1686 elif len(self.args) == 2:
1687 if self.args[1].default is None and not self.args[1].kw_only:
1688 self.entry.signature = TypeSlots.ibinaryfunc
1689 sig = self.entry.signature
1690 nfixed = sig.num_fixed_args()
1691 for i in range(nfixed):
1692 if i < len(self.args):
1695 if sig.is_self_arg(i):
1697 arg.hdr_type = arg.type = env.parent_type
1698 arg.needs_conversion = 0
1700 arg.hdr_type = sig.fixed_arg_type(i)
1701 if not arg.type.same_as(arg.hdr_type):
1702 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1703 arg.needs_type_test = 1
1704 any_type_tests_needed = 1
1706 arg.needs_conversion = 1
1707 if arg.needs_conversion:
1708 arg.hdr_cname = Naming.arg_prefix + arg.name
1710 arg.hdr_cname = Naming.var_prefix + arg.name
1712 self.bad_signature()
1714 if nfixed < len(self.args):
1715 if not sig.has_generic_args:
1716 self.bad_signature()
1717 for arg in self.args:
1718 if arg.is_generic and \
1719 (arg.type.is_extension_type or arg.type.is_builtin_type):
1720 arg.needs_type_test = 1
1721 any_type_tests_needed = 1
1722 if any_type_tests_needed:
1723 env.use_utility_code(arg_type_test_utility_code)
1725 def bad_signature(self):
1726 sig = self.entry.signature
1727 expected_str = "%d" % sig.num_fixed_args()
1728 if sig.has_generic_args:
1729 expected_str = expected_str + " or more"
1731 if name.startswith("__") and name.endswith("__"):
1732 desc = "Special method"
1736 "%s %s has wrong number of arguments "
1737 "(%d declared, %s expected)" % (
1738 desc, self.name, len(self.args), expected_str))
1740 def signature_has_nongeneric_args(self):
1741 argcount = len(self.args)
1742 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1746 def signature_has_generic_args(self):
1747 return self.entry.signature.has_generic_args
1749 def declare_pyfunction(self, env):
1750 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1752 entry = env.lookup_here(self.name)
1753 if entry and entry.type.is_cfunction and not self.is_wrapper:
1754 warning(self.pos, "Overriding cdef method with def method.", 5)
1755 entry = env.declare_pyfunction(self.name, self.pos)
1757 prefix = env.scope_prefix
1758 entry.func_cname = \
1759 Naming.pyfunc_prefix + prefix + name
1760 entry.pymethdef_cname = \
1761 Naming.pymethdef_prefix + prefix + name
1762 if Options.docstrings:
1763 entry.doc = embed_position(self.pos, self.doc)
1765 Naming.funcdoc_prefix + prefix + name
1769 def declare_arguments(self, env):
1770 for arg in self.args:
1772 error(arg.pos, "Missing argument name")
1773 if arg.needs_conversion:
1774 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1775 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1776 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1777 if arg.type.is_pyobject:
1778 arg.entry.init = "0"
1779 arg.entry.init_to_none = 0
1781 arg.entry = self.declare_argument(env, arg)
1783 arg.entry.is_self_arg = arg.is_self_arg
1785 if arg.is_self_arg or \
1786 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1787 arg.entry.is_declared_generic = 1
1788 self.declare_python_arg(env, self.star_arg)
1789 self.declare_python_arg(env, self.starstar_arg)
1791 def declare_python_arg(self, env, arg):
1793 entry = env.declare_var(arg.name,
1794 PyrexTypes.py_object_type, arg.pos)
1797 entry.init_to_none = 0
1798 entry.xdecref_cleanup = 1
1800 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1802 def analyse_expressions(self, env):
1803 self.local_scope.directives = env.directives
1804 self.analyse_default_values(env)
1805 if env.is_py_class_scope:
1806 self.synthesize_assignment_node(env)
1808 def synthesize_assignment_node(self, env):
1810 self.assmt = SingleAssignmentNode(self.pos,
1811 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1812 rhs = ExprNodes.UnboundMethodNode(self.pos,
1813 function = ExprNodes.PyCFunctionNode(self.pos,
1814 pymethdef_cname = self.entry.pymethdef_cname)))
1815 self.assmt.analyse_declarations(env)
1816 self.assmt.analyse_expressions(env)
1818 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1820 sig = self.entry.signature
1821 if sig.has_dummy_arg:
1822 arg_code_list.append(
1823 "PyObject *%s" % Naming.self_cname)
1824 for arg in self.args:
1825 if not arg.is_generic:
1827 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1829 arg_code_list.append(
1830 arg.hdr_type.declaration_code(arg.hdr_cname))
1831 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1832 arg_code_list.append("PyObject *unused")
1833 if sig.has_generic_args:
1834 arg_code_list.append(
1835 "PyObject *%s, PyObject *%s"
1836 % (Naming.args_cname, Naming.kwds_cname))
1837 arg_code = ", ".join(arg_code_list)
1838 dc = self.return_type.declaration_code(self.entry.func_cname)
1839 header = "static %s(%s)" % (dc, arg_code)
1840 code.putln("%s; /*proto*/" % header)
1843 if self.entry.doc and Options.docstrings:
1844 docstr = self.entry.doc
1845 if not isinstance(docstr, str):
1846 docstr = docstr.utf8encode()
1848 'static char %s[] = "%s";' % (
1849 self.entry.doc_cname,
1850 split_docstring(escape_byte_string(docstr))))
1853 "static PyMethodDef %s = " %
1854 self.entry.pymethdef_cname)
1855 code.put_pymethoddef(self.entry, ";")
1856 code.putln("%s {" % header)
1858 def generate_argument_declarations(self, env, code):
1859 for arg in self.args:
1860 if arg.is_generic: # or arg.needs_conversion:
1861 if arg.needs_conversion:
1862 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1864 code.put_var_declaration(arg.entry)
1866 def generate_keyword_list(self, code):
1867 if self.signature_has_generic_args() and \
1868 self.signature_has_nongeneric_args():
1870 "static PyObject **%s[] = {" %
1871 Naming.pykwdlist_cname)
1872 for arg in self.args:
1874 pystring_cname = code.intern_identifier(arg.name)
1875 code.put('&%s,' % pystring_cname)
1878 def generate_argument_parsing_code(self, env, code):
1879 # Generate PyArg_ParseTuple call for generic
1880 # arguments, if any.
1881 if self.entry.signature.has_dummy_arg:
1882 # get rid of unused argument warning
1883 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1885 old_error_label = code.new_error_label()
1886 our_error_label = code.error_label
1887 end_label = code.new_label("argument_unpacking_done")
1889 has_kwonly_args = self.num_kwonly_args > 0
1890 has_star_or_kw_args = self.star_arg is not None \
1891 or self.starstar_arg is not None or has_kwonly_args
1893 for arg in self.args:
1894 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1895 arg.type.create_from_py_utility_code(env)
1897 if not self.signature_has_generic_args():
1898 if has_star_or_kw_args:
1899 error(self.pos, "This method cannot have * or keyword arguments")
1900 self.generate_argument_conversion_code(code)
1902 elif not self.signature_has_nongeneric_args():
1903 # func(*args) or func(**kw) or func(*args, **kw)
1904 self.generate_stararg_copy_code(code)
1907 positional_args = []
1910 for arg in self.args:
1911 arg_entry = arg.entry
1915 if not arg.is_self_arg:
1917 kw_only_args.append(arg)
1919 positional_args.append(arg)
1921 kw_only_args.append(arg)
1924 error(arg.pos, "Non-default argument following default argument")
1925 elif not arg.is_self_arg:
1926 positional_args.append(arg)
1928 self.generate_tuple_and_keyword_parsing_code(
1929 positional_args, kw_only_args, end_label, code)
1931 code.error_label = old_error_label
1932 if code.label_used(our_error_label):
1933 if not code.label_used(end_label):
1934 code.put_goto(end_label)
1935 code.put_label(our_error_label)
1936 if has_star_or_kw_args:
1937 self.generate_arg_decref(self.star_arg, code)
1938 if self.starstar_arg:
1939 if self.starstar_arg.entry.xdecref_cleanup:
1940 code.put_var_xdecref(self.starstar_arg.entry)
1942 code.put_var_decref(self.starstar_arg.entry)
1943 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1944 code.putln("return %s;" % self.error_value())
1945 if code.label_used(end_label):
1946 code.put_label(end_label)
1948 def generate_arg_assignment(self, arg, item, code):
1949 if arg.type.is_pyobject:
1951 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1952 code.putln("%s = %s;" % (arg.entry.cname, item))
1954 func = arg.type.from_py_function
1956 code.putln("%s = %s(%s); %s" % (
1960 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1962 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1964 def generate_arg_xdecref(self, arg, code):
1966 code.put_var_xdecref(arg.entry)
1968 def generate_arg_decref(self, arg, code):
1970 code.put_var_decref(arg.entry)
1972 def generate_stararg_copy_code(self, code):
1973 if not self.star_arg:
1974 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1975 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1977 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1978 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1981 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1983 if self.starstar_arg:
1985 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1987 kwarg_check = "%s" % Naming.kwds_cname
1989 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1990 Naming.kwds_cname, Naming.kwds_cname)
1992 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1993 kwarg_check, Naming.kwds_cname, self.name,
1994 bool(self.starstar_arg), self.error_value()))
1996 if self.starstar_arg:
1997 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1998 self.starstar_arg.entry.cname,
2001 code.putln("if (unlikely(!%s)) return %s;" % (
2002 self.starstar_arg.entry.cname, self.error_value()))
2003 self.starstar_arg.entry.xdecref_cleanup = 0
2004 code.put_gotref(self.starstar_arg.entry.cname)
2008 code.put_incref(Naming.args_cname, py_object_type)
2009 code.putln("%s = %s;" % (
2010 self.star_arg.entry.cname,
2012 self.star_arg.entry.xdecref_cleanup = 0
2014 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2015 kw_only_args, success_label, code):
2016 argtuple_error_label = code.new_label("argtuple_error")
2018 min_positional_args = self.num_required_args - self.num_required_kw_args
2019 if len(self.args) > 0 and self.args[0].is_self_arg:
2020 min_positional_args -= 1
2021 max_positional_args = len(positional_args)
2022 has_fixed_positional_count = not self.star_arg and \
2023 min_positional_args == max_positional_args
2025 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2026 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2027 if self.num_required_kw_args:
2028 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2030 if self.starstar_arg or self.star_arg:
2031 self.generate_stararg_init_code(max_positional_args, code)
2033 # --- optimised code when we receive keyword arguments
2034 if self.num_required_kw_args:
2035 likely_hint = "likely"
2037 likely_hint = "unlikely"
2038 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2039 self.generate_keyword_unpacking_code(
2040 min_positional_args, max_positional_args,
2041 has_fixed_positional_count,
2042 positional_args, kw_only_args, argtuple_error_label, code)
2044 # --- optimised code when we do not receive any keyword arguments
2045 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2046 # Python raises arg tuple related errors first, so we must
2047 # check the length here
2048 if min_positional_args == max_positional_args and not self.star_arg:
2052 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2053 Naming.args_cname, compare, min_positional_args))
2054 code.put_goto(argtuple_error_label)
2056 if self.num_required_kw_args:
2057 # pure error case: keywords required but not passed
2058 if max_positional_args > min_positional_args and not self.star_arg:
2059 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2060 Naming.args_cname, max_positional_args))
2061 code.put_goto(argtuple_error_label)
2062 code.putln('} else {')
2063 for i, arg in enumerate(kw_only_args):
2065 pystring_cname = code.intern_identifier(arg.name)
2066 # required keyword-only argument missing
2067 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2068 self.name.utf8encode(),
2070 code.putln(code.error_goto(self.pos))
2073 elif min_positional_args == max_positional_args:
2074 # parse the exact number of positional arguments from the
2076 code.putln('} else {')
2077 for i, arg in enumerate(positional_args):
2078 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2079 self.generate_arg_assignment(arg, item, code)
2080 self.generate_arg_default_assignments(code)
2083 # parse the positional arguments from the variable length
2085 code.putln('} else {')
2086 self.generate_arg_default_assignments(code)
2087 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2089 code.putln('default:')
2090 reversed_args = list(enumerate(positional_args))[::-1]
2091 for i, arg in reversed_args:
2092 if i >= min_positional_args-1:
2093 if min_positional_args > 1:
2094 code.putln('case %2d:' % (i+1)) # pure code beautification
2096 code.put('case %2d: ' % (i+1))
2097 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2098 self.generate_arg_assignment(arg, item, code)
2099 if min_positional_args == 0:
2100 code.put('case 0: ')
2101 code.putln('break;')
2103 if min_positional_args:
2104 for i in range(min_positional_args-1, -1, -1):
2105 code.putln('case %2d:' % i)
2106 code.put_goto(argtuple_error_label)
2108 code.put('default: ')
2109 code.put_goto(argtuple_error_label)
2114 if code.label_used(argtuple_error_label):
2115 code.put_goto(success_label)
2116 code.put_label(argtuple_error_label)
2117 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2118 self.name.utf8encode(), has_fixed_positional_count,
2119 min_positional_args, max_positional_args,
2121 code.putln(code.error_goto(self.pos))
2123 def generate_arg_default_assignments(self, code):
2124 for arg in self.args:
2125 if arg.is_generic and arg.default:
2129 arg.calculate_default_value_code(code)))
2131 def generate_stararg_init_code(self, max_positional_args, code):
2132 if self.starstar_arg:
2133 self.starstar_arg.entry.xdecref_cleanup = 0
2134 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2135 self.starstar_arg.entry.cname,
2136 self.starstar_arg.entry.cname,
2137 self.error_value()))
2138 code.put_gotref(self.starstar_arg.entry.cname)
2140 self.star_arg.entry.xdecref_cleanup = 0
2141 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2143 max_positional_args))
2144 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2145 self.star_arg.entry.cname, Naming.args_cname,
2146 max_positional_args, Naming.args_cname))
2147 code.put_gotref(self.star_arg.entry.cname)
2148 if self.starstar_arg:
2150 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2151 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2152 code.putln('return %s;' % self.error_value())
2155 code.putln("if (unlikely(!%s)) return %s;" % (
2156 self.star_arg.entry.cname, self.error_value()))
2157 code.putln('} else {')
2158 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2159 code.put_incref(Naming.empty_tuple, py_object_type)
2162 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2163 has_fixed_positional_count, positional_args,
2164 kw_only_args, argtuple_error_label, code):
2165 all_args = tuple(positional_args) + tuple(kw_only_args)
2166 max_args = len(all_args)
2169 for i, arg in enumerate(all_args):
2170 if arg.default and arg.type.is_pyobject:
2171 default_value = arg.calculate_default_value_code(code)
2172 if arg.type is not PyrexTypes.py_object_type:
2173 default_value = "(PyObject*)"+default_value
2174 default_args.append((i, default_value))
2176 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2178 # it looks funny to separate the init-to-0 from setting the
2179 # default value, but C89 needs this
2180 code.putln("PyObject* values[%d] = {%s};" % (
2181 max_args, ','.join(['0']*max_args)))
2182 for i, default_value in default_args:
2183 code.putln('values[%d] = %s;' % (i, default_value))
2185 # parse the tuple and check that it's not too long
2186 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2188 code.putln('default:')
2189 for i in range(max_positional_args-1, -1, -1):
2190 code.put('case %2d: ' % (i+1))
2191 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2192 i, Naming.args_cname, i))
2193 code.putln('case 0: break;')
2194 if not self.star_arg:
2195 code.put('default: ') # more arguments than allowed
2196 code.put_goto(argtuple_error_label)
2199 # now fill up the positional/required arguments with values
2201 if self.num_required_args or max_positional_args > 0:
2202 last_required_arg = -1
2203 for i, arg in enumerate(all_args):
2205 last_required_arg = i
2206 if last_required_arg < max_positional_args:
2207 last_required_arg = max_positional_args-1
2208 num_required_args = self.num_required_args
2209 if max_positional_args > 0:
2210 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2211 for i, arg in enumerate(all_args[:last_required_arg+1]):
2212 if max_positional_args > 0 and i <= max_positional_args:
2213 if self.star_arg and i == max_positional_args:
2214 code.putln('default:')
2216 code.putln('case %2d:' % i)
2217 pystring_cname = code.intern_identifier(arg.name)
2220 # handled separately below
2222 code.putln('if (kw_args > %d) {' % num_required_args)
2223 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2224 Naming.kwds_cname, pystring_cname))
2225 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2228 num_required_args -= 1
2229 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2230 i, Naming.kwds_cname, pystring_cname))
2231 code.putln('if (likely(values[%d])) kw_args--;' % i);
2232 if i < min_positional_args:
2234 # special case: we know arg 0 is missing
2236 code.put_goto(argtuple_error_label)
2238 # print the correct number of values (args or
2239 # kwargs) that were passed into positional
2240 # arguments up to this point
2241 code.putln('else {')
2242 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2243 self.name.utf8encode(), has_fixed_positional_count,
2244 min_positional_args, max_positional_args, i))
2245 code.putln(code.error_goto(self.pos))
2248 code.putln('else {')
2249 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2250 self.name.utf8encode(), pystring_cname))
2251 code.putln(code.error_goto(self.pos))
2253 if max_positional_args > 0:
2256 if kw_only_args and not self.starstar_arg:
2257 # unpack optional keyword-only arguments
2258 # checking for interned strings in a dict is faster than iterating
2259 # but it's too likely that we must iterate if we expect **kwargs
2261 for i, arg in enumerate(all_args[max_positional_args:]):
2262 if not arg.kw_only or not arg.default:
2264 optional_args.append((i+max_positional_args, arg))
2266 # this mimics an unrolled loop so that we can "break" out of it
2267 code.putln('while (kw_args > 0) {')
2268 code.putln('PyObject* value;')
2269 for i, arg in optional_args:
2270 pystring_cname = code.intern_identifier(arg.name)
2272 'value = PyDict_GetItem(%s, %s);' % (
2273 Naming.kwds_cname, pystring_cname))
2275 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2276 code.putln('break;')
2279 code.putln('if (unlikely(kw_args > 0)) {')
2280 # non-positional/-required kw args left in dict: default args,
2281 # kw-only args, **kwargs or error
2283 # This is sort of a catch-all: except for checking required
2284 # arguments, this will always do the right thing for unpacking
2285 # keyword arguments, so that we can concentrate on optimising
2286 # common cases above.
2287 if max_positional_args == 0:
2290 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2291 Naming.args_cname, max_positional_args,
2292 Naming.args_cname, max_positional_args))
2293 pos_arg_count = "used_pos_args"
2295 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2296 code.globalstate.use_utility_code(parse_keywords_utility_code)
2298 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2300 Naming.pykwdlist_cname,
2301 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2303 self.name.utf8encode()))
2304 code.putln(code.error_goto(self.pos))
2307 # convert arg values to their final type and assign them
2308 for i, arg in enumerate(all_args):
2309 if arg.default and not arg.type.is_pyobject:
2310 code.putln("if (values[%d]) {" % i)
2311 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2312 if arg.default and not arg.type.is_pyobject:
2313 code.putln('} else {')
2317 arg.calculate_default_value_code(code)))
2320 def generate_argument_conversion_code(self, code):
2321 # Generate code to convert arguments from
2322 # signature type to declared type, if needed.
2323 for arg in self.args:
2324 if arg.needs_conversion:
2325 self.generate_arg_conversion(arg, code)
2327 def generate_arg_conversion(self, arg, code):
2328 # Generate conversion code for one argument.
2329 old_type = arg.hdr_type
2331 if old_type.is_pyobject:
2333 code.putln("if (%s) {" % arg.hdr_cname)
2335 code.putln("assert(%s); {" % arg.hdr_cname)
2336 self.generate_arg_conversion_from_pyobject(arg, code)
2338 elif new_type.is_pyobject:
2339 self.generate_arg_conversion_to_pyobject(arg, code)
2341 if new_type.assignable_from(old_type):
2343 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2346 "Cannot convert 1 argument from '%s' to '%s'" %
2347 (old_type, new_type))
2349 def generate_arg_conversion_from_pyobject(self, arg, code):
2351 func = new_type.from_py_function
2352 # copied from CoerceFromPyTypeNode
2354 code.putln("%s = %s(%s); %s" % (
2358 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2361 "Cannot convert Python object argument to type '%s'"
2364 def generate_arg_conversion_to_pyobject(self, arg, code):
2365 old_type = arg.hdr_type
2366 func = old_type.to_py_function
2368 code.putln("%s = %s(%s); %s" % (
2372 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2373 code.put_var_gotref(arg.entry)
2376 "Cannot convert argument of type '%s' to Python object"
2379 def generate_argument_type_tests(self, code):
2380 # Generate type tests for args whose signature
2381 # type is PyObject * and whose declared type is
2382 # a subtype thereof.
2383 for arg in self.args:
2384 if arg.needs_type_test:
2385 self.generate_arg_type_test(arg, code)
2387 def generate_arg_type_test(self, arg, code):
2388 # Generate type test for one argument.
2389 if arg.type.typeobj_is_available():
2390 typeptr_cname = arg.type.typeptr_cname
2391 arg_code = "((PyObject *)%s)" % arg.entry.cname
2393 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2398 arg.type.is_builtin_type,
2399 code.error_goto(arg.pos)))
2401 error(arg.pos, "Cannot test type of extern C class "
2402 "without type object name specification")
2404 def error_value(self):
2405 return self.entry.signature.error_value
2407 def caller_will_check_exceptions(self):
2410 class OverrideCheckNode(StatNode):
2411 # A Node for dispatching to the def method if it
2420 child_attrs = ['body']
2424 def analyse_expressions(self, env):
2425 self.args = env.arg_entries
2426 if self.py_func.is_module_scope:
2431 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2432 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2433 call_node = ExprNodes.SimpleCallNode(self.pos,
2434 function=self.func_node,
2435 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2436 self.body = ReturnStatNode(self.pos, value=call_node)
2437 self.body.analyse_expressions(env)
2439 def generate_execution_code(self, code):
2440 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2441 # Check to see if we are an extension type
2442 if self.py_func.is_module_scope:
2443 self_arg = "((PyObject *)%s)" % Naming.module_cname
2445 self_arg = "((PyObject *)%s)" % self.args[0].cname
2446 code.putln("/* Check if called by wrapper */")
2447 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2448 code.putln("/* Check if overriden in Python */")
2449 if self.py_func.is_module_scope:
2450 code.putln("else {")
2452 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2453 self.func_node.allocate(code)
2454 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2455 # need to get attribute manually--scope would return cdef method
2456 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2457 self.func_node.result(), self_arg, interned_attr_cname, err))
2458 code.put_gotref(self.func_node.py_result())
2459 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2460 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2461 self.func_node.result(), self.py_func.entry.func_cname)
2462 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2463 self.body.generate_execution_code(code)
2465 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2467 self.func_node.release(code)
2469 class ClassDefNode(StatNode, BlockNode):
2472 class PyClassDefNode(ClassDefNode):
2473 # A Python class definition.
2475 # name EncodedString Name of the class
2476 # doc string or None
2477 # body StatNode Attribute definition code
2478 # entry Symtab.Entry
2479 # scope PyClassScope
2481 # The following subnodes are constructed internally:
2483 # dict DictNode Class dictionary
2484 # classobj ClassNode Class object
2485 # target NameNode Variable to assign class object to
2487 child_attrs = ["body", "dict", "classobj", "target"]
2489 def __init__(self, pos, name, bases, doc, body):
2490 StatNode.__init__(self, pos)
2495 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2496 if self.doc and Options.docstrings:
2497 doc = embed_position(self.pos, self.doc)
2498 doc_node = ExprNodes.StringNode(pos, value = doc)
2501 self.classobj = ExprNodes.ClassNode(pos, name = name,
2502 bases = bases, dict = self.dict, doc = doc_node)
2503 self.target = ExprNodes.NameNode(pos, name = name)
2505 def as_cclass(self):
2507 Return this node as if it were declared as an extension class
2509 bases = self.classobj.bases.args
2511 base_class_name = None
2512 base_class_module = None
2513 elif len(bases) == 1:
2516 from ExprNodes import AttributeNode, NameNode
2517 while isinstance(base, AttributeNode):
2518 path.insert(0, base.attribute)
2520 if isinstance(base, NameNode):
2521 path.insert(0, base.name)
2522 base_class_name = path[-1]
2524 base_class_module = u'.'.join(path[:-1])
2526 base_class_module = None
2528 error(self.classobj.bases.args.pos, "Invalid base class")
2530 error(self.classobj.bases.args.pos, "C class may only have one base class")
2533 return CClassDefNode(self.pos,
2534 visibility = 'private',
2536 class_name = self.name,
2537 base_class_module = base_class_module,
2538 base_class_name = base_class_name,
2543 def create_scope(self, env):
2545 while env.is_py_class_scope or env.is_c_class_scope:
2546 env = env.outer_scope
2547 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2550 def analyse_declarations(self, env):
2551 self.target.analyse_target_declaration(env)
2552 cenv = self.create_scope(env)
2553 cenv.directives = env.directives
2554 cenv.class_obj_cname = self.target.entry.cname
2555 self.body.analyse_declarations(cenv)
2557 def analyse_expressions(self, env):
2558 self.dict.analyse_expressions(env)
2559 self.classobj.analyse_expressions(env)
2560 genv = env.global_scope()
2562 self.body.analyse_expressions(cenv)
2563 self.target.analyse_target_expression(env, self.classobj)
2565 def generate_function_definitions(self, env, code):
2566 self.body.generate_function_definitions(self.scope, code)
2568 def generate_execution_code(self, code):
2569 code.pyclass_stack.append(self)
2571 self.dict.generate_evaluation_code(code)
2572 self.classobj.generate_evaluation_code(code)
2573 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2574 self.body.generate_execution_code(code)
2575 self.target.generate_assignment_code(self.classobj, code)
2576 self.dict.generate_disposal_code(code)
2577 self.dict.free_temps(code)
2578 code.pyclass_stack.pop()
2581 class CClassDefNode(ClassDefNode):
2582 # An extension type definition.
2584 # visibility 'private' or 'public' or 'extern'
2585 # typedef_flag boolean
2587 # module_name string or None For import of extern type objects
2588 # class_name string Unqualified name of class
2589 # as_name string or None Name to declare as in this scope
2590 # base_class_module string or None Module containing the base class
2591 # base_class_name string or None Name of the base class
2592 # objstruct_name string or None Specified C name of object struct
2593 # typeobj_name string or None Specified C name of type object
2594 # in_pxd boolean Is in a .pxd file
2595 # doc string or None
2596 # body StatNode or None
2597 # entry Symtab.Entry
2598 # base_type PyExtensionType or None
2599 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2600 # buffer_defaults_pos
2602 child_attrs = ["body"]
2603 buffer_defaults_node = None
2604 buffer_defaults_pos = None
2605 typedef_flag = False
2607 objstruct_name = None
2610 def analyse_declarations(self, env):
2611 #print "CClassDefNode.analyse_declarations:", self.class_name
2612 #print "...visibility =", self.visibility
2613 #print "...module_name =", self.module_name
2616 if self.buffer_defaults_node:
2617 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2618 env, [], self.buffer_defaults_node,
2619 need_complete=False)
2621 buffer_defaults = None
2623 if env.in_cinclude and not self.objstruct_name:
2624 error(self.pos, "Object struct name specification required for "
2625 "C class defined in 'extern from' block")
2626 self.base_type = None
2627 # Now that module imports are cached, we need to
2628 # import the modules for extern classes.
2629 if self.module_name:
2631 for module in env.cimported_modules:
2632 if module.name == self.module_name:
2633 self.module = module
2634 if self.module is None:
2635 self.module = ModuleScope(self.module_name, None, env.context)
2636 self.module.has_extern_class = 1
2637 env.add_imported_module(self.module)
2639 if self.base_class_name:
2640 if self.base_class_module:
2641 base_class_scope = env.find_module(self.base_class_module, self.pos)
2643 base_class_scope = env
2644 if self.base_class_name == 'object':
2645 # extension classes are special and don't need to inherit from object
2646 if base_class_scope is None or base_class_scope.lookup('object') is None:
2647 self.base_class_name = None
2648 self.base_class_module = None
2649 base_class_scope = None
2650 if base_class_scope:
2651 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2652 if base_class_entry:
2653 if not base_class_entry.is_type:
2654 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2655 elif not base_class_entry.type.is_extension_type:
2656 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2657 elif not base_class_entry.type.is_complete():
2658 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2660 self.base_type = base_class_entry.type
2661 has_body = self.body is not None
2662 if self.module_name and self.visibility != 'extern':
2663 module_path = self.module_name.split(".")
2664 home_scope = env.find_imported_module(module_path, self.pos)
2670 if self.visibility == 'extern':
2671 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2672 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2674 self.entry = home_scope.declare_c_class(
2675 name = self.class_name,
2677 defining = has_body and self.in_pxd,
2678 implementing = has_body and not self.in_pxd,
2679 module_name = self.module_name,
2680 base_type = self.base_type,
2681 objstruct_cname = self.objstruct_name,
2682 typeobj_cname = self.typeobj_name,
2683 visibility = self.visibility,
2684 typedef_flag = self.typedef_flag,
2686 buffer_defaults = buffer_defaults)
2687 if home_scope is not env and self.visibility == 'extern':
2688 env.add_imported_entry(self.class_name, self.entry, pos)
2689 scope = self.entry.type.scope
2690 if scope is not None:
2691 scope.directives = env.directives
2693 if self.doc and Options.docstrings:
2694 scope.doc = embed_position(self.pos, self.doc)
2697 self.body.analyse_declarations(scope)
2701 scope.implemented = 1
2702 env.allocate_vtable_names(self.entry)
2704 def analyse_expressions(self, env):
2706 scope = self.entry.type.scope
2707 self.body.analyse_expressions(scope)
2709 def generate_function_definitions(self, env, code):
2711 self.body.generate_function_definitions(
2712 self.entry.type.scope, code)
2714 def generate_execution_code(self, code):
2715 # This is needed to generate evaluation code for
2716 # default values of method arguments.
2718 self.body.generate_execution_code(code)
2720 def annotate(self, code):
2722 self.body.annotate(code)
2725 class PropertyNode(StatNode):
2726 # Definition of a property in an extension type.
2729 # doc EncodedString or None Doc string
2732 child_attrs = ["body"]
2734 def analyse_declarations(self, env):
2735 entry = env.declare_property(self.name, self.doc, self.pos)
2737 entry.scope.directives = env.directives
2738 self.body.analyse_declarations(entry.scope)
2740 def analyse_expressions(self, env):
2741 self.body.analyse_expressions(env)
2743 def generate_function_definitions(self, env, code):
2744 self.body.generate_function_definitions(env, code)
2746 def generate_execution_code(self, code):
2749 def annotate(self, code):
2750 self.body.annotate(code)
2753 class GlobalNode(StatNode):
2754 # Global variable declaration.
2760 def analyse_declarations(self, env):
2761 for name in self.names:
2762 env.declare_global(name, self.pos)
2764 def analyse_expressions(self, env):
2767 def generate_execution_code(self, code):
2771 class ExprStatNode(StatNode):
2772 # Expression used as a statement.
2776 child_attrs = ["expr"]
2778 def analyse_declarations(self, env):
2780 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2781 func = self.expr.function.as_cython_attribute()
2782 if func == u'declare':
2783 args, kwds = self.expr.explicit_args_kwds()
2785 error(self.expr.pos, "Variable names must be specified.")
2786 for var, type_node in kwds.key_value_pairs:
2787 type = type_node.analyse_as_type(env)
2789 error(type_node.pos, "Unknown type")
2791 env.declare_var(var.value, type, var.pos, is_cdef = True)
2792 self.__class__ = PassStatNode
2794 def analyse_expressions(self, env):
2795 self.expr.analyse_expressions(env)
2797 def generate_execution_code(self, code):
2798 self.expr.generate_evaluation_code(code)
2799 if not self.expr.is_temp and self.expr.result():
2800 code.putln("%s;" % self.expr.result())
2801 self.expr.generate_disposal_code(code)
2802 self.expr.free_temps(code)
2804 def annotate(self, code):
2805 self.expr.annotate(code)
2808 class AssignmentNode(StatNode):
2809 # Abstract base class for assignment nodes.
2811 # The analyse_expressions and generate_execution_code
2812 # phases of assignments are split into two sub-phases
2813 # each, to enable all the right hand sides of a
2814 # parallel assignment to be evaluated before assigning
2815 # to any of the left hand sides.
2817 def analyse_expressions(self, env):
2818 self.analyse_types(env)
2820 # def analyse_expressions(self, env):
2821 # self.analyse_expressions_1(env)
2822 # self.analyse_expressions_2(env)
2824 def generate_execution_code(self, code):
2825 self.generate_rhs_evaluation_code(code)
2826 self.generate_assignment_code(code)
2829 class SingleAssignmentNode(AssignmentNode):
2830 # The simplest case:
2834 # lhs ExprNode Left hand side
2835 # rhs ExprNode Right hand side
2836 # first bool Is this guaranteed the first assignment to lhs?
2838 child_attrs = ["lhs", "rhs"]
2840 declaration_only = False
2842 def analyse_declarations(self, env):
2845 # handle declarations of the form x = cython.foo()
2846 if isinstance(self.rhs, ExprNodes.CallNode):
2847 func_name = self.rhs.function.as_cython_attribute()
2849 args, kwds = self.rhs.explicit_args_kwds()
2851 if func_name in ['declare', 'typedef']:
2852 if len(args) > 2 or kwds is not None:
2853 error(rhs.pos, "Can only declare one type at a time.")
2855 type = args[0].analyse_as_type(env)
2857 error(args[0].pos, "Unknown type")
2860 if func_name == 'declare':
2861 if isinstance(lhs, ExprNodes.NameNode):
2862 vars = [(lhs.name, lhs.pos)]
2863 elif isinstance(lhs, ExprNodes.TupleNode):
2864 vars = [(var.name, var.pos) for var in lhs.args]
2866 error(lhs.pos, "Invalid declaration")
2868 for var, pos in vars:
2869 env.declare_var(var, type, pos, is_cdef = True)
2874 self.declaration_only = True
2876 self.declaration_only = True
2877 if not isinstance(lhs, ExprNodes.NameNode):
2878 error(lhs.pos, "Invalid declaration.")
2879 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2881 elif func_name in ['struct', 'union']:
2882 self.declaration_only = True
2883 if len(args) > 0 or kwds is None:
2884 error(rhs.pos, "Struct or union members must be given by name.")
2887 for member, type_node in kwds.key_value_pairs:
2888 type = type_node.analyse_as_type(env)
2890 error(type_node.pos, "Unknown type")
2892 members.append((member.value, type, member.pos))
2893 if len(members) < len(kwds.key_value_pairs):
2895 if not isinstance(self.lhs, ExprNodes.NameNode):
2896 error(self.lhs.pos, "Invalid declaration.")
2897 name = self.lhs.name
2898 scope = StructOrUnionScope(name)
2899 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2900 for member, type, pos in members:
2901 scope.declare_var(member, type, pos)
2903 if self.declaration_only:
2906 self.lhs.analyse_target_declaration(env)
2908 def analyse_types(self, env, use_temp = 0):
2909 self.rhs.analyse_types(env)
2910 self.lhs.analyse_target_types(env)
2911 self.lhs.gil_assignment_check(env)
2912 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2914 self.rhs = self.rhs.coerce_to_temp(env)
2916 def generate_rhs_evaluation_code(self, code):
2917 self.rhs.generate_evaluation_code(code)
2919 def generate_assignment_code(self, code):
2920 self.lhs.generate_assignment_code(self.rhs, code)
2922 def annotate(self, code):
2923 self.lhs.annotate(code)
2924 self.rhs.annotate(code)
2927 class CascadedAssignmentNode(AssignmentNode):
2928 # An assignment with multiple left hand sides:
2932 # lhs_list [ExprNode] Left hand sides
2933 # rhs ExprNode Right hand sides
2937 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2939 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2940 coerced_rhs_list = None
2942 def analyse_declarations(self, env):
2943 for lhs in self.lhs_list:
2944 lhs.analyse_target_declaration(env)
2946 def analyse_types(self, env, use_temp = 0):
2947 self.rhs.analyse_types(env)
2949 self.rhs = self.rhs.coerce_to_temp(env)
2951 self.rhs = self.rhs.coerce_to_simple(env)
2952 from ExprNodes import CloneNode
2953 self.coerced_rhs_list = []
2954 for lhs in self.lhs_list:
2955 lhs.analyse_target_types(env)
2956 lhs.gil_assignment_check(env)
2957 rhs = CloneNode(self.rhs)
2958 rhs = rhs.coerce_to(lhs.type, env)
2959 self.coerced_rhs_list.append(rhs)
2961 def generate_rhs_evaluation_code(self, code):
2962 self.rhs.generate_evaluation_code(code)
2964 def generate_assignment_code(self, code):
2965 for i in range(len(self.lhs_list)):
2966 lhs = self.lhs_list[i]
2967 rhs = self.coerced_rhs_list[i]
2968 rhs.generate_evaluation_code(code)
2969 lhs.generate_assignment_code(rhs, code)
2970 # Assignment has disposed of the cloned RHS
2971 self.rhs.generate_disposal_code(code)
2972 self.rhs.free_temps(code)
2974 def annotate(self, code):
2975 for i in range(len(self.lhs_list)):
2976 lhs = self.lhs_list[i].annotate(code)
2977 rhs = self.coerced_rhs_list[i].annotate(code)
2978 self.rhs.annotate(code)
2981 class ParallelAssignmentNode(AssignmentNode):
2982 # A combined packing/unpacking assignment:
2986 # This has been rearranged by the parser into
2988 # a = d ; b = e ; c = f
2990 # but we must evaluate all the right hand sides
2991 # before assigning to any of the left hand sides.
2993 # stats [AssignmentNode] The constituent assignments
2995 child_attrs = ["stats"]
2997 def analyse_declarations(self, env):
2998 for stat in self.stats:
2999 stat.analyse_declarations(env)
3001 def analyse_expressions(self, env):
3002 for stat in self.stats:
3003 stat.analyse_types(env, use_temp = 1)
3005 # def analyse_expressions(self, env):
3006 # for stat in self.stats:
3007 # stat.analyse_expressions_1(env, use_temp = 1)
3008 # for stat in self.stats:
3009 # stat.analyse_expressions_2(env)
3011 def generate_execution_code(self, code):
3012 for stat in self.stats:
3013 stat.generate_rhs_evaluation_code(code)
3014 for stat in self.stats:
3015 stat.generate_assignment_code(code)
3017 def annotate(self, code):
3018 for stat in self.stats:
3022 class InPlaceAssignmentNode(AssignmentNode):
3023 # An in place arithmatic operand:
3029 # lhs ExprNode Left hand side
3030 # rhs ExprNode Right hand side
3031 # op char one of "+-*/%^&|"
3032 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3034 # This code is a bit tricky because in order to obey Python
3035 # semantics the sub-expressions (e.g. indices) of the lhs must
3036 # not be evaluated twice. So we must re-use the values calculated
3037 # in evaluation phase for the assignment phase as well.
3038 # Fortunately, the type of the lhs node is fairly constrained
3039 # (it must be a NameNode, AttributeNode, or IndexNode).
3041 child_attrs = ["lhs", "rhs"]
3044 def analyse_declarations(self, env):
3045 self.lhs.analyse_target_declaration(env)
3047 def analyse_types(self, env):
3048 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3049 self.rhs.analyse_types(env)
3050 self.lhs.analyse_target_types(env)
3051 if Options.incref_local_binop and self.dup.type.is_pyobject:
3052 self.dup = self.dup.coerce_to_temp(env)
3054 if self.lhs.type.is_pyobject:
3055 self.rhs = self.rhs.coerce_to_pyobject(env)
3056 elif self.rhs.type.is_pyobject:
3057 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3058 if self.lhs.type.is_pyobject:
3059 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3060 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3062 def generate_execution_code(self, code):
3064 self.rhs.generate_evaluation_code(code)
3065 self.dup.generate_subexpr_evaluation_code(code)
3066 if self.dup.is_temp:
3067 self.dup.allocate_temp_result(code)
3068 # self.dup.generate_result_code is run only if it is not buffer access
3069 if self.operator == "**":
3073 if self.lhs.type.is_pyobject:
3074 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3075 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3076 self.dup.generate_result_code(code)
3077 self.result_value_temp.allocate(code)
3079 "%s = %s(%s, %s%s); %s" % (
3080 self.result_value.result(),
3081 self.py_operation_function(),
3082 self.dup.py_result(),
3083 self.rhs.py_result(),
3085 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3086 code.put_gotref(self.result_value.py_result())
3087 self.result_value.generate_evaluation_code(code) # May be a type check...
3088 self.rhs.generate_disposal_code(code)
3089 self.rhs.free_temps(code)
3090 self.dup.generate_disposal_code(code)
3091 self.dup.free_temps(code)
3092 self.lhs.generate_assignment_code(self.result_value, code)
3093 self.result_value_temp.release(code)
3095 c_op = self.operator
3099 error(self.pos, "No C inplace power operator")
3100 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3101 error(self.pos, "Inplace operators not implemented for complex types.")
3103 # have to do assignment directly to avoid side-effects
3104 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3105 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3107 self.dup.generate_result_code(code)
3108 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3109 self.rhs.generate_disposal_code(code)
3110 self.rhs.free_temps(code)
3111 if self.dup.is_temp:
3112 self.dup.generate_subexpr_disposal_code(code)
3113 self.dup.free_subexpr_temps(code)
3115 def create_dup_node(self, env):
3118 self.dup.analyse_types(env)
3119 if isinstance(self.lhs, ExprNodes.NameNode):
3120 target_lhs = ExprNodes.NameNode(self.dup.pos,
3121 name = self.dup.name,
3122 is_temp = self.dup.is_temp,
3123 entry = self.dup.entry)
3124 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3125 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3126 obj = ExprNodes.CloneNode(self.lhs.obj),
3127 attribute = self.dup.attribute,
3128 is_temp = self.dup.is_temp)
3129 elif isinstance(self.lhs, ExprNodes.IndexNode):
3131 index = ExprNodes.CloneNode(self.lhs.index)
3134 if self.lhs.indices:
3135 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3138 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3139 base = ExprNodes.CloneNode(self.dup.base),
3142 is_temp = self.dup.is_temp)
3145 self.lhs = target_lhs
3148 def py_operation_function(self):
3149 return self.py_functions[self.operator]
3152 "|": "PyNumber_InPlaceOr",
3153 "^": "PyNumber_InPlaceXor",
3154 "&": "PyNumber_InPlaceAnd",
3155 "+": "PyNumber_InPlaceAdd",
3156 "-": "PyNumber_InPlaceSubtract",
3157 "*": "PyNumber_InPlaceMultiply",
3158 "/": "PyNumber_InPlaceDivide",
3159 "%": "PyNumber_InPlaceRemainder",
3160 "<<": "PyNumber_InPlaceLshift",
3161 ">>": "PyNumber_InPlaceRshift",
3162 "**": "PyNumber_InPlacePower",
3163 "//": "PyNumber_InPlaceFloorDivide",
3166 def annotate(self, code):
3167 self.lhs.annotate(code)
3168 self.rhs.annotate(code)
3169 self.dup.annotate(code)
3172 class PrintStatNode(StatNode):
3175 # arg_tuple TupleNode
3176 # append_newline boolean
3178 child_attrs = ["arg_tuple"]
3180 def analyse_expressions(self, env):
3181 self.arg_tuple.analyse_expressions(env)
3182 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3183 env.use_utility_code(printing_utility_code)
3184 if len(self.arg_tuple.args) == 1 and self.append_newline:
3185 env.use_utility_code(printing_one_utility_code)
3187 gil_check = StatNode._gil_check
3188 gil_message = "Python print statement"
3190 def generate_execution_code(self, code):
3191 if len(self.arg_tuple.args) == 1 and self.append_newline:
3192 arg = self.arg_tuple.args[0]
3193 arg.generate_evaluation_code(code)
3196 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3198 code.error_goto(self.pos)))
3199 arg.generate_disposal_code(code)
3200 arg.free_temps(code)
3202 self.arg_tuple.generate_evaluation_code(code)
3204 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3205 self.arg_tuple.py_result(),
3206 self.append_newline,
3207 code.error_goto(self.pos)))
3208 self.arg_tuple.generate_disposal_code(code)
3209 self.arg_tuple.free_temps(code)
3211 def annotate(self, code):
3212 self.arg_tuple.annotate(code)
3215 class ExecStatNode(StatNode):
3220 child_attrs = ["args"]
3222 def analyse_expressions(self, env):
3223 for i, arg in enumerate(self.args):
3224 arg.analyse_expressions(env)
3225 arg = arg.coerce_to_pyobject(env)
3227 env.use_utility_code(Builtin.pyexec_utility_code)
3229 gil_check = StatNode._gil_check
3230 gil_message = "Python exec statement"
3232 def generate_execution_code(self, code):
3234 for arg in self.args:
3235 arg.generate_evaluation_code(code)
3236 args.append( arg.py_result() )
3237 args = tuple(args + ['0', '0'][:3-len(args)])
3238 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3239 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3240 (temp_result,) + args))
3241 for arg in self.args:
3242 arg.generate_disposal_code(code)
3243 arg.free_temps(code)
3245 code.error_goto_if_null(temp_result, self.pos))
3246 code.put_gotref(temp_result)
3247 code.put_decref_clear(temp_result, py_object_type)
3248 code.funcstate.release_temp(temp_result)
3250 def annotate(self, code):
3251 for arg in self.args:
3255 class DelStatNode(StatNode):
3260 child_attrs = ["args"]
3262 def analyse_declarations(self, env):
3263 for arg in self.args:
3264 arg.analyse_target_declaration(env)
3266 def analyse_expressions(self, env):
3267 for arg in self.args:
3268 arg.analyse_target_expression(env, None)
3269 if not arg.type.is_pyobject:
3270 error(arg.pos, "Deletion of non-Python object")
3271 #arg.release_target_temp(env)
3273 def gil_check(self, env):
3274 for arg in self.args:
3275 if arg.type.is_pyobject:
3276 self._gil_check(env)
3278 gil_message = "Deleting Python object"
3280 def generate_execution_code(self, code):
3281 for arg in self.args:
3282 if arg.type.is_pyobject:
3283 arg.generate_deletion_code(code)
3284 # else error reported earlier
3286 def annotate(self, code):
3287 for arg in self.args:
3291 class PassStatNode(StatNode):
3296 def analyse_expressions(self, env):
3299 def generate_execution_code(self, code):
3303 class BreakStatNode(StatNode):
3307 def analyse_expressions(self, env):
3310 def generate_execution_code(self, code):
3311 if not code.break_label:
3312 error(self.pos, "break statement not inside loop")
3314 code.put_goto(code.break_label)
3317 class ContinueStatNode(StatNode):
3321 def analyse_expressions(self, env):
3324 def generate_execution_code(self, code):
3325 if code.funcstate.in_try_finally:
3326 error(self.pos, "continue statement inside try of try...finally")
3327 elif not code.continue_label:
3328 error(self.pos, "continue statement not inside loop")
3330 code.put_goto(code.continue_label)
3333 class ReturnStatNode(StatNode):
3336 # value ExprNode or None
3337 # return_type PyrexType
3339 child_attrs = ["value"]
3341 def analyse_expressions(self, env):
3342 return_type = env.return_type
3343 self.return_type = return_type
3345 error(self.pos, "Return not inside a function body")
3348 self.value.analyse_types(env)
3349 if return_type.is_void or return_type.is_returncode:
3350 error(self.value.pos,
3351 "Return with value in void function")
3353 self.value = self.value.coerce_to(env.return_type, env)
3355 if (not return_type.is_void
3356 and not return_type.is_pyobject
3357 and not return_type.is_returncode):
3358 error(self.pos, "Return value required")
3360 def gil_check(self, env):
3361 if self.return_type.is_pyobject:
3362 self._gil_check(env)
3364 gil_message = "Returning Python object"
3366 def generate_execution_code(self, code):
3367 code.mark_pos(self.pos)
3368 if not self.return_type:
3369 # error reported earlier
3371 if self.return_type.is_pyobject:
3372 code.put_xdecref(Naming.retval_cname,
3375 self.value.generate_evaluation_code(code)
3376 self.value.make_owned_reference(code)
3379 Naming.retval_cname,
3380 self.value.result_as(self.return_type)))
3381 self.value.generate_post_assignment_code(code)
3382 self.value.free_temps(code)
3384 if self.return_type.is_pyobject:
3385 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3386 elif self.return_type.is_returncode:
3389 Naming.retval_cname,
3390 self.return_type.default_value))
3391 for cname, type in code.funcstate.temps_holding_reference():
3392 code.put_decref_clear(cname, type)
3393 code.put_goto(code.return_label)
3395 def annotate(self, code):
3397 self.value.annotate(code)
3400 class RaiseStatNode(StatNode):
3403 # exc_type ExprNode or None
3404 # exc_value ExprNode or None
3405 # exc_tb ExprNode or None
3407 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3409 def analyse_expressions(self, env):
3411 self.exc_type.analyse_types(env)
3412 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3414 self.exc_value.analyse_types(env)
3415 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3417 self.exc_tb.analyse_types(env)
3418 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3419 env.use_utility_code(raise_utility_code)
3420 env.use_utility_code(restore_exception_utility_code)
3422 gil_check = StatNode._gil_check
3423 gil_message = "Raising exception"
3425 def generate_execution_code(self, code):
3427 self.exc_type.generate_evaluation_code(code)
3428 type_code = self.exc_type.py_result()
3432 self.exc_value.generate_evaluation_code(code)
3433 value_code = self.exc_value.py_result()
3437 self.exc_tb.generate_evaluation_code(code)
3438 tb_code = self.exc_tb.py_result()
3441 if self.exc_type or self.exc_value or self.exc_tb:
3443 "__Pyx_Raise(%s, %s, %s);" % (
3450 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3452 obj.generate_disposal_code(code)
3453 obj.free_temps(code)
3455 code.error_goto(self.pos))
3457 def annotate(self, code):
3459 self.exc_type.annotate(code)
3461 self.exc_value.annotate(code)
3463 self.exc_tb.annotate(code)
3466 class ReraiseStatNode(StatNode):
3470 def analyse_expressions(self, env):
3471 env.use_utility_code(raise_utility_code)
3472 env.use_utility_code(restore_exception_utility_code)
3474 gil_check = StatNode._gil_check
3475 gil_message = "Raising exception"
3477 def generate_execution_code(self, code):
3478 vars = code.funcstate.exc_vars
3480 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3481 code.putln(code.error_goto(self.pos))
3483 error(self.pos, "Reraise not inside except clause")
3486 class AssertStatNode(StatNode):
3490 # value ExprNode or None
3492 child_attrs = ["cond", "value"]
3494 def analyse_expressions(self, env):
3495 self.cond = self.cond.analyse_boolean_expression(env)
3497 self.value.analyse_types(env)
3498 self.value = self.value.coerce_to_pyobject(env)
3500 gil_check = StatNode._gil_check
3501 gil_message = "Raising exception"
3503 def generate_execution_code(self, code):
3504 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3505 self.cond.generate_evaluation_code(code)
3507 "if (unlikely(!%s)) {" %
3510 self.value.generate_evaluation_code(code)
3512 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3513 self.value.py_result())
3514 self.value.generate_disposal_code(code)
3515 self.value.free_temps(code)
3518 "PyErr_SetNone(PyExc_AssertionError);")
3520 code.error_goto(self.pos))
3523 self.cond.generate_disposal_code(code)
3524 self.cond.free_temps(code)
3525 code.putln("#endif")
3527 def annotate(self, code):
3528 self.cond.annotate(code)
3530 self.value.annotate(code)
3533 class IfStatNode(StatNode):
3536 # if_clauses [IfClauseNode]
3537 # else_clause StatNode or None
3539 child_attrs = ["if_clauses", "else_clause"]
3541 def analyse_control_flow(self, env):
3542 env.start_branching(self.pos)
3543 for if_clause in self.if_clauses:
3544 if_clause.analyse_control_flow(env)
3545 env.next_branch(if_clause.end_pos())
3546 if self.else_clause:
3547 self.else_clause.analyse_control_flow(env)
3548 env.finish_branching(self.end_pos())
3550 def analyse_declarations(self, env):
3551 for if_clause in self.if_clauses:
3552 if_clause.analyse_declarations(env)
3553 if self.else_clause:
3554 self.else_clause.analyse_declarations(env)
3556 def analyse_expressions(self, env):
3557 for if_clause in self.if_clauses:
3558 if_clause.analyse_expressions(env)
3559 if self.else_clause:
3560 self.else_clause.analyse_expressions(env)
3562 def generate_execution_code(self, code):
3563 code.mark_pos(self.pos)
3564 end_label = code.new_label()
3565 for if_clause in self.if_clauses:
3566 if_clause.generate_execution_code(code, end_label)
3567 if self.else_clause:
3568 code.putln("/*else*/ {")
3569 self.else_clause.generate_execution_code(code)
3571 code.put_label(end_label)
3573 def annotate(self, code):
3574 for if_clause in self.if_clauses:
3575 if_clause.annotate(code)
3576 if self.else_clause:
3577 self.else_clause.annotate(code)
3580 class IfClauseNode(Node):
3581 # if or elif clause in an if statement
3583 # condition ExprNode
3586 child_attrs = ["condition", "body"]
3588 def analyse_control_flow(self, env):
3589 self.body.analyse_control_flow(env)
3591 def analyse_declarations(self, env):
3592 self.condition.analyse_declarations(env)
3593 self.body.analyse_declarations(env)
3595 def analyse_expressions(self, env):
3597 self.condition.analyse_temp_boolean_expression(env)
3598 self.body.analyse_expressions(env)
3600 def generate_execution_code(self, code, end_label):
3601 self.condition.generate_evaluation_code(code)
3604 self.condition.result())
3605 self.condition.generate_disposal_code(code)
3606 self.condition.free_temps(code)
3607 self.body.generate_execution_code(code)
3611 code.put_goto(end_label)
3614 def annotate(self, code):
3615 self.condition.annotate(code)
3616 self.body.annotate(code)
3619 class SwitchCaseNode(StatNode):
3620 # Generated in the optimization of an if-elif-else node
3622 # conditions [ExprNode]
3625 child_attrs = ['conditions', 'body']
3627 def generate_execution_code(self, code):
3628 for cond in self.conditions:
3629 code.mark_pos(cond.pos)
3630 cond.generate_evaluation_code(code)
3631 code.putln("case %s:" % cond.result())
3632 self.body.generate_execution_code(code)
3633 code.putln("break;")
3635 def annotate(self, code):
3636 for cond in self.conditions:
3638 self.body.annotate(code)
3640 class SwitchStatNode(StatNode):
3641 # Generated in the optimization of an if-elif-else node
3644 # cases [SwitchCaseNode]
3645 # else_clause StatNode or None
3647 child_attrs = ['test', 'cases', 'else_clause']
3649 def generate_execution_code(self, code):
3650 code.putln("switch (%s) {" % self.test.result())
3651 for case in self.cases:
3652 case.generate_execution_code(code)
3653 if self.else_clause is not None:
3654 code.putln("default:")
3655 self.else_clause.generate_execution_code(code)
3656 code.putln("break;")
3659 def annotate(self, code):
3660 self.test.annotate(code)
3661 for case in self.cases:
3663 if self.else_clause is not None:
3664 self.else_clause.annotate(code)
3666 class LoopNode(object):
3668 def analyse_control_flow(self, env):
3669 env.start_branching(self.pos)
3670 self.body.analyse_control_flow(env)
3671 env.next_branch(self.body.end_pos())
3672 if self.else_clause:
3673 self.else_clause.analyse_control_flow(env)
3674 env.finish_branching(self.end_pos())
3677 class WhileStatNode(LoopNode, StatNode):
3680 # condition ExprNode
3682 # else_clause StatNode
3684 child_attrs = ["condition", "body", "else_clause"]
3686 def analyse_declarations(self, env):
3687 self.body.analyse_declarations(env)
3688 if self.else_clause:
3689 self.else_clause.analyse_declarations(env)
3691 def analyse_expressions(self, env):
3693 self.condition.analyse_temp_boolean_expression(env)
3694 self.body.analyse_expressions(env)
3695 if self.else_clause:
3696 self.else_clause.analyse_expressions(env)
3698 def generate_execution_code(self, code):
3699 old_loop_labels = code.new_loop_labels()
3702 self.condition.generate_evaluation_code(code)
3703 self.condition.generate_disposal_code(code)
3706 self.condition.result())
3707 self.condition.free_temps(code)
3708 self.body.generate_execution_code(code)
3709 code.put_label(code.continue_label)
3711 break_label = code.break_label
3712 code.set_loop_labels(old_loop_labels)
3713 if self.else_clause:
3714 code.putln("/*else*/ {")
3715 self.else_clause.generate_execution_code(code)
3717 code.put_label(break_label)
3719 def annotate(self, code):
3720 self.condition.annotate(code)
3721 self.body.annotate(code)
3722 if self.else_clause:
3723 self.else_clause.annotate(code)
3726 def ForStatNode(pos, **kw):
3727 if 'iterator' in kw:
3728 return ForInStatNode(pos, **kw)
3730 return ForFromStatNode(pos, **kw)
3732 class ForInStatNode(LoopNode, StatNode):
3736 # iterator IteratorNode
3738 # else_clause StatNode
3739 # item NextNode used internally
3741 child_attrs = ["target", "iterator", "body", "else_clause"]
3744 def analyse_declarations(self, env):
3745 self.target.analyse_target_declaration(env)
3746 self.body.analyse_declarations(env)
3747 if self.else_clause:
3748 self.else_clause.analyse_declarations(env)
3750 def analyse_expressions(self, env):
3752 self.target.analyse_target_types(env)
3753 self.iterator.analyse_expressions(env)
3754 self.item = ExprNodes.NextNode(self.iterator, env)
3755 self.item = self.item.coerce_to(self.target.type, env)
3756 self.body.analyse_expressions(env)
3757 if self.else_clause:
3758 self.else_clause.analyse_expressions(env)
3760 def generate_execution_code(self, code):
3761 old_loop_labels = code.new_loop_labels()
3762 self.iterator.allocate_counter_temp(code)
3763 self.iterator.generate_evaluation_code(code)
3766 self.item.generate_evaluation_code(code)
3767 self.target.generate_assignment_code(self.item, code)
3768 self.body.generate_execution_code(code)
3769 code.put_label(code.continue_label)
3772 break_label = code.break_label
3773 code.set_loop_labels(old_loop_labels)
3774 if self.else_clause:
3775 code.putln("/*else*/ {")
3776 self.else_clause.generate_execution_code(code)
3778 code.put_label(break_label)
3779 self.iterator.release_counter_temp(code)
3780 self.iterator.generate_disposal_code(code)
3781 self.iterator.free_temps(code)
3783 def annotate(self, code):
3784 self.target.annotate(code)
3785 self.iterator.annotate(code)
3786 self.body.annotate(code)
3787 if self.else_clause:
3788 self.else_clause.annotate(code)
3789 self.item.annotate(code)
3792 class ForFromStatNode(LoopNode, StatNode):
3793 # for name from expr rel name rel expr
3800 # step ExprNode or None
3802 # else_clause StatNode or None
3808 # loopvar_node ExprNode (usually a NameNode or temp node)
3809 # py_loopvar_node PyTempNode or None
3810 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3812 is_py_target = False
3814 py_loopvar_node = None
3817 def analyse_declarations(self, env):
3818 self.target.analyse_target_declaration(env)
3819 self.body.analyse_declarations(env)
3820 if self.else_clause:
3821 self.else_clause.analyse_declarations(env)
3823 def analyse_expressions(self, env):
3825 self.target.analyse_target_types(env)
3826 self.bound1.analyse_types(env)
3827 self.bound2.analyse_types(env)
3828 if self.step is not None:
3829 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3830 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3831 self.step.analyse_types(env)
3833 target_type = self.target.type
3834 if self.target.type.is_numeric:
3835 loop_type = self.target.type
3837 loop_type = PyrexTypes.c_int_type
3838 if not self.bound1.type.is_pyobject:
3839 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3840 if not self.bound2.type.is_pyobject:
3841 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3842 if self.step is not None and not self.step.type.is_pyobject:
3843 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3844 self.bound1 = self.bound1.coerce_to(loop_type, env)
3845 self.bound2 = self.bound2.coerce_to(loop_type, env)
3846 if not self.bound2.is_literal:
3847 self.bound2 = self.bound2.coerce_to_temp(env)
3848 if self.step is not None:
3849 self.step = self.step.coerce_to(loop_type, env)
3850 if not self.step.is_literal:
3851 self.step = self.step.coerce_to_temp(env)
3853 target_type = self.target.type
3854 if not (target_type.is_pyobject or target_type.is_numeric):
3855 error(self.target.pos,
3856 "for-from loop variable must be c numeric type or Python object")
3857 if target_type.is_numeric:
3858 self.is_py_target = False
3859 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3860 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3861 self.loopvar_node = self.target
3862 self.py_loopvar_node = None
3864 self.is_py_target = True
3865 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3866 self.loopvar_node = c_loopvar_node
3867 self.py_loopvar_node = \
3868 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3869 self.body.analyse_expressions(env)
3870 if self.else_clause:
3871 self.else_clause.analyse_expressions(env)
3873 def generate_execution_code(self, code):
3874 old_loop_labels = code.new_loop_labels()
3875 from_range = self.from_range
3876 self.bound1.generate_evaluation_code(code)
3877 self.bound2.generate_evaluation_code(code)
3878 offset, incop = self.relation_table[self.relation1]
3879 if self.step is not None:
3880 self.step.generate_evaluation_code(code)
3881 step = self.step.result()
3882 incop = "%s=%s" % (incop[0], step)
3884 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3885 self.loopvar_node.allocate(code)
3886 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3887 self.py_loopvar_node.allocate(code)
3889 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3891 loopvar_name = self.loopvar_node.result()
3893 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3895 self.bound1.result(), offset,
3896 loopvar_name, self.relation2, self.bound2.result(),
3897 loopvar_name, incop))
3898 if self.py_loopvar_node:
3899 self.py_loopvar_node.generate_evaluation_code(code)
3900 self.target.generate_assignment_code(self.py_loopvar_node, code)
3902 code.putln("%s = %s;" % (
3903 self.target.result(), loopvar_name))
3904 self.body.generate_execution_code(code)
3905 code.put_label(code.continue_label)
3906 if self.py_loopvar_node:
3907 # This mess is to make for..from loops with python targets behave
3908 # exactly like those with C targets with regards to re-assignment
3909 # of the loop variable.
3911 if self.target.entry.is_pyglobal:
3912 # We know target is a NameNode, this is the only ugly case.
3913 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3914 target_node.allocate(code)
3915 interned_cname = code.intern_identifier(self.target.entry.name)
3916 code.putln("/*here*/")
3917 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3918 target_node.result(),
3919 Naming.module_cname,
3921 code.error_goto_if_null(target_node.result(), self.target.pos)))
3922 code.put_gotref(target_node.result())
3924 target_node = self.target
3925 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3926 from_py_node.temp_code = loopvar_name
3927 from_py_node.generate_result_code(code)
3928 if self.target.entry.is_pyglobal:
3929 code.put_decref(target_node.result(), target_node.type)
3930 target_node.release(code)
3932 if self.py_loopvar_node:
3933 # This is potentially wasteful, but we don't want the semantics to
3934 # depend on whether or not the loop is a python type.
3935 self.py_loopvar_node.generate_evaluation_code(code)
3936 self.target.generate_assignment_code(self.py_loopvar_node, code)
3937 break_label = code.break_label
3938 code.set_loop_labels(old_loop_labels)
3939 if self.else_clause:
3940 code.putln("/*else*/ {")
3941 self.else_clause.generate_execution_code(code)
3943 code.put_label(break_label)
3944 self.bound1.generate_disposal_code(code)
3945 self.bound1.free_temps(code)
3946 self.bound2.generate_disposal_code(code)
3947 self.bound2.free_temps(code)
3948 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3949 self.loopvar_node.release(code)
3950 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3951 self.py_loopvar_node.release(code)
3952 if self.step is not None:
3953 self.step.generate_disposal_code(code)
3954 self.step.free_temps(code)
3957 # {relop : (initial offset, increment op)}
3964 def annotate(self, code):
3965 self.target.annotate(code)
3966 self.bound1.annotate(code)
3967 self.bound2.annotate(code)
3969 self.bound2.annotate(code)
3970 self.body.annotate(code)
3971 if self.else_clause:
3972 self.else_clause.annotate(code)
3975 class WithStatNode(StatNode):
3977 Represents a Python with statement.
3979 This is only used at parse tree level; and is not present in
3980 analysis or generation phases.
3982 # manager The with statement manager object
3983 # target Node (lhs expression)
3985 child_attrs = ["manager", "target", "body"]
3987 class TryExceptStatNode(StatNode):
3988 # try .. except statement
3991 # except_clauses [ExceptClauseNode]
3992 # else_clause StatNode or None
3994 child_attrs = ["body", "except_clauses", "else_clause"]
3996 def analyse_control_flow(self, env):
3997 env.start_branching(self.pos)
3998 self.body.analyse_control_flow(env)
3999 successful_try = env.control_flow # grab this for later
4000 env.next_branch(self.body.end_pos())
4001 env.finish_branching(self.body.end_pos())
4003 env.start_branching(self.except_clauses[0].pos)
4004 for except_clause in self.except_clauses:
4005 except_clause.analyse_control_flow(env)
4006 env.next_branch(except_clause.end_pos())
4008 # the else cause it executed only when the try clause finishes
4009 env.control_flow.incoming = successful_try
4010 if self.else_clause:
4011 self.else_clause.analyse_control_flow(env)
4012 env.finish_branching(self.end_pos())
4014 def analyse_declarations(self, env):
4015 self.body.analyse_declarations(env)
4016 for except_clause in self.except_clauses:
4017 except_clause.analyse_declarations(env)
4018 if self.else_clause:
4019 self.else_clause.analyse_declarations(env)
4020 env.use_utility_code(reset_exception_utility_code)
4022 def analyse_expressions(self, env):
4023 self.body.analyse_expressions(env)
4024 default_clause_seen = 0
4025 for except_clause in self.except_clauses:
4026 except_clause.analyse_expressions(env)
4027 if default_clause_seen:
4028 error(except_clause.pos, "default 'except:' must be last")
4029 if not except_clause.pattern:
4030 default_clause_seen = 1
4031 self.has_default_clause = default_clause_seen
4032 if self.else_clause:
4033 self.else_clause.analyse_expressions(env)
4035 gil_check = StatNode._gil_check
4036 gil_message = "Try-except statement"
4038 def generate_execution_code(self, code):
4039 old_return_label = code.return_label
4040 old_break_label = code.break_label
4041 old_continue_label = code.continue_label
4042 old_error_label = code.new_error_label()
4043 our_error_label = code.error_label
4044 except_end_label = code.new_label('exception_handled')
4045 except_error_label = code.new_label('except_error')
4046 except_return_label = code.new_label('except_return')
4047 try_return_label = code.new_label('try_return')
4048 try_break_label = code.new_label('try_break')
4049 try_continue_label = code.new_label('try_continue')
4050 try_end_label = code.new_label('try_end')
4053 code.putln("PyObject %s;" %
4054 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4055 code.putln("__Pyx_ExceptionSave(%s);" %
4056 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4057 for var in Naming.exc_save_vars:
4058 code.put_xgotref(var)
4061 code.return_label = try_return_label
4062 code.break_label = try_break_label
4063 code.continue_label = try_continue_label
4064 self.body.generate_execution_code(code)
4067 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4068 code.error_label = except_error_label
4069 code.return_label = except_return_label
4070 if self.else_clause:
4073 self.else_clause.generate_execution_code(code)
4076 for var in Naming.exc_save_vars:
4077 code.put_xdecref_clear(var, py_object_type)
4078 code.put_goto(try_end_label)
4079 if code.label_used(try_return_label):
4080 code.put_label(try_return_label)
4081 for var in Naming.exc_save_vars:
4082 code.put_xdecref_clear(var, py_object_type)
4083 code.put_goto(old_return_label)
4084 code.put_label(our_error_label)
4085 for temp_name, type in temps_to_clean_up:
4086 code.put_xdecref_clear(temp_name, type)
4087 for except_clause in self.except_clauses:
4088 except_clause.generate_handling_code(code, except_end_label)
4090 error_label_used = code.label_used(except_error_label)
4091 if error_label_used or not self.has_default_clause:
4092 if error_label_used:
4093 code.put_label(except_error_label)
4094 for var in Naming.exc_save_vars:
4095 code.put_xdecref(var, py_object_type)
4096 code.put_goto(old_error_label)
4098 if code.label_used(try_break_label):
4099 code.put_label(try_break_label)
4100 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4101 code.putln("__Pyx_ExceptionReset(%s);" %
4102 ', '.join(Naming.exc_save_vars))
4103 code.put_goto(old_break_label)
4105 if code.label_used(try_continue_label):
4106 code.put_label(try_continue_label)
4107 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4108 code.putln("__Pyx_ExceptionReset(%s);" %
4109 ', '.join(Naming.exc_save_vars))
4110 code.put_goto(old_continue_label)
4112 if code.label_used(except_return_label):
4113 code.put_label(except_return_label)
4114 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4115 code.putln("__Pyx_ExceptionReset(%s);" %
4116 ', '.join(Naming.exc_save_vars))
4117 code.put_goto(old_return_label)
4119 if code.label_used(except_end_label):
4120 code.put_label(except_end_label)
4121 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4122 code.putln("__Pyx_ExceptionReset(%s);" %
4123 ', '.join(Naming.exc_save_vars))
4124 code.put_label(try_end_label)
4127 code.return_label = old_return_label
4128 code.break_label = old_break_label
4129 code.continue_label = old_continue_label
4130 code.error_label = old_error_label
4132 def annotate(self, code):
4133 self.body.annotate(code)
4134 for except_node in self.except_clauses:
4135 except_node.annotate(code)
4136 if self.else_clause:
4137 self.else_clause.annotate(code)
4140 class ExceptClauseNode(Node):
4141 # Part of try ... except statement.
4144 # target ExprNode or None
4146 # excinfo_target NameNode or None optional target for exception info
4147 # match_flag string result of exception match
4148 # exc_value ExcValueNode used internally
4149 # function_name string qualified name of enclosing function
4150 # exc_vars (string * 3) local exception variables
4152 # excinfo_target is never set by the parser, but can be set by a transform
4153 # in order to extract more extensive information about the exception as a
4154 # sys.exc_info()-style tuple into a target variable
4156 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4159 excinfo_target = None
4161 def analyse_declarations(self, env):
4163 self.target.analyse_target_declaration(env)
4164 if self.excinfo_target is not None:
4165 self.excinfo_target.analyse_target_declaration(env)
4166 self.body.analyse_declarations(env)
4168 def analyse_expressions(self, env):
4170 genv = env.global_scope()
4171 self.function_name = env.qualified_name
4173 self.pattern.analyse_expressions(env)
4174 self.pattern = self.pattern.coerce_to_pyobject(env)
4177 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4178 self.target.analyse_target_expression(env, self.exc_value)
4179 if self.excinfo_target is not None:
4181 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4182 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4183 self.excinfo_tuple.analyse_expressions(env)
4184 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4186 self.body.analyse_expressions(env)
4188 def generate_handling_code(self, code, end_label):
4189 code.mark_pos(self.pos)
4191 self.pattern.generate_evaluation_code(code)
4193 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4195 "%s = PyErr_ExceptionMatches(%s);" % (
4197 self.pattern.py_result()))
4198 self.pattern.generate_disposal_code(code)
4199 self.pattern.free_temps(code)
4203 code.funcstate.release_temp(match_flag)
4205 code.putln("/*except:*/ {")
4207 if not getattr(self.body, 'stats', True):
4208 # most simple case: no exception variable, empty body (pass)
4209 # => reset the exception state, done
4210 code.putln("PyErr_Restore(0,0,0);")
4211 code.put_goto(end_label)
4215 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4218 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4219 # We always have to fetch the exception value even if
4220 # there is no target, because this also normalises the
4221 # exception and stores it in the thread state.
4222 code.globalstate.use_utility_code(get_exception_utility_code)
4223 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4224 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4225 code.error_goto(self.pos)))
4229 self.exc_value.set_var(exc_vars[1])
4230 self.exc_value.generate_evaluation_code(code)
4231 self.target.generate_assignment_code(self.exc_value, code)
4232 if self.excinfo_target is not None:
4233 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4234 node.set_var(tempvar)
4235 self.excinfo_tuple.generate_evaluation_code(code)
4236 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4238 old_break_label, old_continue_label = code.break_label, code.continue_label
4239 code.break_label = code.new_label('except_break')
4240 code.continue_label = code.new_label('except_continue')
4242 old_exc_vars = code.funcstate.exc_vars
4243 code.funcstate.exc_vars = exc_vars
4244 self.body.generate_execution_code(code)
4245 code.funcstate.exc_vars = old_exc_vars
4246 for var in exc_vars:
4247 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4248 code.put_goto(end_label)
4250 if code.label_used(code.break_label):
4251 code.put_label(code.break_label)
4252 for var in exc_vars:
4253 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4254 code.put_goto(old_break_label)
4255 code.break_label = old_break_label
4257 if code.label_used(code.continue_label):
4258 code.put_label(code.continue_label)
4259 for var in exc_vars:
4260 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4261 code.put_goto(old_continue_label)
4262 code.continue_label = old_continue_label
4264 for temp in exc_vars:
4265 code.funcstate.release_temp(temp)
4270 def annotate(self, code):
4272 self.pattern.annotate(code)
4274 self.target.annotate(code)
4275 self.body.annotate(code)
4278 class TryFinallyStatNode(StatNode):
4279 # try ... finally statement
4282 # finally_clause StatNode
4284 # The plan is that we funnel all continue, break
4285 # return and error gotos into the beginning of the
4286 # finally block, setting a variable to remember which
4287 # one we're doing. At the end of the finally block, we
4288 # switch on the variable to figure out where to go.
4289 # In addition, if we're doing an error, we save the
4290 # exception on entry to the finally block and restore
4293 child_attrs = ["body", "finally_clause"]
4295 preserve_exception = 1
4297 disallow_continue_in_try_finally = 0
4298 # There doesn't seem to be any point in disallowing
4299 # continue in the try block, since we have no problem
4302 def create_analysed(pos, env, body, finally_clause):
4303 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4305 create_analysed = staticmethod(create_analysed)
4307 def analyse_control_flow(self, env):
4308 env.start_branching(self.pos)
4309 self.body.analyse_control_flow(env)
4310 env.next_branch(self.body.end_pos())
4311 env.finish_branching(self.body.end_pos())
4312 self.finally_clause.analyse_control_flow(env)
4314 def analyse_declarations(self, env):
4315 self.body.analyse_declarations(env)
4316 self.finally_clause.analyse_declarations(env)
4318 def analyse_expressions(self, env):
4319 self.body.analyse_expressions(env)
4320 self.finally_clause.analyse_expressions(env)
4322 gil_check = StatNode._gil_check
4323 gil_message = "Try-finally statement"
4325 def generate_execution_code(self, code):
4326 old_error_label = code.error_label
4327 old_labels = code.all_new_labels()
4328 new_labels = code.get_all_labels()
4329 new_error_label = code.error_label
4330 catch_label = code.new_label()
4333 if self.disallow_continue_in_try_finally:
4334 was_in_try_finally = code.funcstate.in_try_finally
4335 code.funcstate.in_try_finally = 1
4336 self.body.generate_execution_code(code)
4337 if self.disallow_continue_in_try_finally:
4338 code.funcstate.in_try_finally = was_in_try_finally
4341 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4345 error_label_used = 0
4346 for i, new_label in enumerate(new_labels):
4347 if new_label in code.labels_used:
4348 cases_used.append(i)
4349 if new_label == new_error_label:
4350 error_label_used = 1
4351 error_label_case = i
4355 if error_label_used and self.preserve_exception:
4357 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4359 "int %s;" % Naming.exc_lineno_name)
4360 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4361 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4362 code.putln(exc_var_init_zero)
4364 exc_var_init_zero = None
4365 code.use_label(catch_label)
4367 "__pyx_why = 0; goto %s;" % catch_label)
4368 for i in cases_used:
4369 new_label = new_labels[i]
4370 #if new_label and new_label != "<try>":
4371 if new_label == new_error_label and self.preserve_exception:
4372 self.put_error_catcher(code,
4373 new_error_label, i+1, catch_label, temps_to_clean_up)
4375 code.put('%s: ' % new_label)
4376 if exc_var_init_zero:
4377 code.putln(exc_var_init_zero)
4378 code.putln("__pyx_why = %s; goto %s;" % (
4381 code.put_label(catch_label)
4382 code.set_all_labels(old_labels)
4383 if error_label_used:
4384 code.new_error_label()
4385 finally_error_label = code.error_label
4386 self.finally_clause.generate_execution_code(code)
4387 if error_label_used:
4388 if finally_error_label in code.labels_used and self.preserve_exception:
4389 over_label = code.new_label()
4390 code.put_goto(over_label);
4391 code.put_label(finally_error_label)
4392 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4393 for var in Naming.exc_vars:
4394 code.putln("Py_XDECREF(%s);" % var)
4396 code.put_goto(old_error_label)
4397 code.put_label(over_label)
4398 code.error_label = old_error_label
4401 "switch (__pyx_why) {")
4402 for i in cases_used:
4403 old_label = old_labels[i]
4404 if old_label == old_error_label and self.preserve_exception:
4405 self.put_error_uncatcher(code, i+1, old_error_label)
4407 code.use_label(old_label)
4409 "case %s: goto %s;" % (
4417 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4418 code.globalstate.use_utility_code(restore_exception_utility_code)
4425 for temp_name, type in temps_to_clean_up:
4426 code.put_xdecref_clear(temp_name, type)
4428 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4432 Naming.exc_lineno_name, Naming.lineno_cname))
4436 code.put_goto(catch_label)
4440 def put_error_uncatcher(self, code, i, error_label):
4441 code.globalstate.use_utility_code(restore_exception_utility_code)
4446 "__Pyx_ErrRestore(%s, %s, %s);" %
4450 Naming.lineno_cname, Naming.exc_lineno_name))
4451 for var in Naming.exc_vars:
4455 code.put_goto(error_label)
4459 def annotate(self, code):
4460 self.body.annotate(code)
4461 self.finally_clause.annotate(code)
4464 class GILStatNode(TryFinallyStatNode):
4465 # 'with gil' or 'with nogil' statement
4467 # state string 'gil' or 'nogil'
4471 preserve_exception = 0
4473 def __init__(self, pos, state, body):
4475 TryFinallyStatNode.__init__(self, pos,
4477 finally_clause = GILExitNode(pos, state = state))
4479 def analyse_expressions(self, env):
4480 env.use_utility_code(force_init_threads_utility_code)
4481 was_nogil = env.nogil
4483 TryFinallyStatNode.analyse_expressions(self, env)
4484 env.nogil = was_nogil
4486 def gil_check(self, env):
4489 def generate_execution_code(self, code):
4490 code.mark_pos(self.pos)
4491 if self.state == 'gil':
4492 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4494 code.putln("{ PyThreadState *_save;")
4495 code.putln("Py_UNBLOCK_THREADS")
4496 TryFinallyStatNode.generate_execution_code(self, code)
4500 class GILExitNode(StatNode):
4501 # Used as the 'finally' block in a GILStatNode
4503 # state string 'gil' or 'nogil'
4507 def analyse_expressions(self, env):
4510 def generate_execution_code(self, code):
4511 if self.state == 'gil':
4512 code.putln("PyGILState_Release();")
4514 code.putln("Py_BLOCK_THREADS")
4517 class CImportStatNode(StatNode):
4520 # module_name string Qualified name of module being imported
4521 # as_name string or None Name specified in "as" clause, if any
4525 def analyse_declarations(self, env):
4526 if not env.is_module_scope:
4527 error(self.pos, "cimport only allowed at module level")
4529 module_scope = env.find_module(self.module_name, self.pos)
4530 if "." in self.module_name:
4531 names = [EncodedString(name) for name in self.module_name.split(".")]
4533 top_module_scope = env.context.find_submodule(top_name)
4534 module_scope = top_module_scope
4535 for name in names[1:]:
4536 submodule_scope = module_scope.find_submodule(name)
4537 module_scope.declare_module(name, submodule_scope, self.pos)
4538 module_scope = submodule_scope
4540 env.declare_module(self.as_name, module_scope, self.pos)
4542 env.declare_module(top_name, top_module_scope, self.pos)
4544 name = self.as_name or self.module_name
4545 env.declare_module(name, module_scope, self.pos)
4547 def analyse_expressions(self, env):
4550 def generate_execution_code(self, code):
4554 class FromCImportStatNode(StatNode):
4555 # from ... cimport statement
4557 # module_name string Qualified name of module
4558 # imported_names [(pos, name, as_name, kind)] Names to be imported
4562 def analyse_declarations(self, env):
4563 if not env.is_module_scope:
4564 error(self.pos, "cimport only allowed at module level")
4566 module_scope = env.find_module(self.module_name, self.pos)
4567 env.add_imported_module(module_scope)
4568 for pos, name, as_name, kind in self.imported_names:
4570 for local_name, entry in module_scope.entries.items():
4571 env.add_imported_entry(local_name, entry, pos)
4573 entry = module_scope.lookup(name)
4575 if kind and not self.declaration_matches(entry, kind):
4576 entry.redeclared(pos)
4578 if kind == 'struct' or kind == 'union':
4579 entry = module_scope.declare_struct_or_union(name,
4580 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4581 elif kind == 'class':
4582 entry = module_scope.declare_c_class(name, pos = pos,
4583 module_name = self.module_name)
4585 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4586 if submodule_scope.parent_module is module_scope:
4587 env.declare_module(as_name or name, submodule_scope, self.pos)
4589 error(pos, "Name '%s' not declared in module '%s'"
4590 % (name, self.module_name))
4593 local_name = as_name or name
4594 env.add_imported_entry(local_name, entry, pos)
4596 def declaration_matches(self, entry, kind):
4597 if not entry.is_type:
4601 if not type.is_extension_type:
4604 if not type.is_struct_or_union:
4606 if kind != type.kind:
4610 def analyse_expressions(self, env):
4613 def generate_execution_code(self, code):
4617 class FromImportStatNode(StatNode):
4618 # from ... import statement
4621 # items [(string, NameNode)]
4622 # interned_items [(string, NameNode, ExprNode)]
4623 # item PyTempNode used internally
4624 # import_star boolean used internally
4626 child_attrs = ["module"]
4629 def analyse_declarations(self, env):
4630 for name, target in self.items:
4632 if not env.is_module_scope:
4633 error(self.pos, "import * only allowed at module level")
4635 env.has_import_star = 1
4636 self.import_star = 1
4638 target.analyse_target_declaration(env)
4640 def analyse_expressions(self, env):
4642 self.module.analyse_expressions(env)
4643 self.item = ExprNodes.PyTempNode(self.pos, env)
4644 self.interned_items = []
4645 for name, target in self.items:
4647 for _, entry in env.entries.items():
4648 if not entry.is_type and entry.type.is_extension_type:
4649 env.use_utility_code(ExprNodes.type_test_utility_code)
4652 entry = env.lookup(target.name)
4653 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4654 continue # already cimported
4655 target.analyse_target_expression(env, None)
4656 if target.type is py_object_type:
4659 coerced_item = self.item.coerce_to(target.type, env)
4660 self.interned_items.append(
4661 (name, target, coerced_item))
4663 def generate_execution_code(self, code):
4664 self.module.generate_evaluation_code(code)
4665 if self.import_star:
4667 'if (%s(%s) < 0) %s;' % (
4669 self.module.py_result(),
4670 code.error_goto(self.pos)))
4671 self.item.allocate(code)
4672 for name, target, coerced_item in self.interned_items:
4673 cname = code.intern_identifier(name)
4675 '%s = PyObject_GetAttr(%s, %s); %s' % (
4677 self.module.py_result(),
4679 code.error_goto_if_null(self.item.result(), self.pos)))
4680 code.put_gotref(self.item.py_result())
4681 if coerced_item is None:
4682 target.generate_assignment_code(self.item, code)
4684 coerced_item.allocate_temp_result(code)
4685 coerced_item.generate_result_code(code)
4686 target.generate_assignment_code(coerced_item, code)
4687 if self.item.result() != coerced_item.result():
4688 code.put_decref_clear(self.item.result(), self.item.type)
4689 self.item.release(code)
4690 self.module.generate_disposal_code(code)
4691 self.module.free_temps(code)
4695 #------------------------------------------------------------------------------------
4697 # Runtime support code
4699 #------------------------------------------------------------------------------------
4701 utility_function_predeclarations = \
4704 #define INLINE __inline__
4706 #define INLINE __inline
4711 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4715 static int %(skip_dispatch_cname)s = 0;
4717 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4719 if Options.gcc_branch_hints:
4720 branch_prediction_macros = \
4723 /* Test for GCC > 2.95 */
4724 #if __GNUC__ > 2 || \
4725 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4726 #define likely(x) __builtin_expect(!!(x), 1)
4727 #define unlikely(x) __builtin_expect(!!(x), 0)
4728 #else /* __GNUC__ > 2 ... */
4729 #define likely(x) (x)
4730 #define unlikely(x) (x)
4731 #endif /* __GNUC__ > 2 ... */
4732 #else /* __GNUC__ */
4733 #define likely(x) (x)
4734 #define unlikely(x) (x)
4735 #endif /* __GNUC__ */
4738 branch_prediction_macros = \
4740 #define likely(x) (x)
4741 #define unlikely(x) (x)
4744 #get_name_predeclaration = \
4745 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4747 #get_name_interned_predeclaration = \
4748 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4750 #------------------------------------------------------------------------------------
4752 printing_utility_code = UtilityCode(
4754 static int __Pyx_Print(PyObject *, int); /*proto*/
4755 #if PY_MAJOR_VERSION >= 3
4756 static PyObject* %s = 0;
4757 static PyObject* %s = 0;
4759 """ % (Naming.print_function, Naming.print_function_kwargs),
4761 #if PY_MAJOR_VERSION < 3
4762 static PyObject *__Pyx_GetStdout(void) {
4763 PyObject *f = PySys_GetObject((char *)"stdout");
4765 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4770 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4775 if (!(f = __Pyx_GetStdout()))
4777 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4778 if (PyFile_SoftSpace(f, 1)) {
4779 if (PyFile_WriteString(" ", f) < 0)
4782 v = PyTuple_GET_ITEM(arg_tuple, i);
4783 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4785 if (PyString_Check(v)) {
4786 char *s = PyString_AsString(v);
4787 Py_ssize_t len = PyString_Size(v);
4789 isspace(Py_CHARMASK(s[len-1])) &&
4791 PyFile_SoftSpace(f, 0);
4795 if (PyFile_WriteString("\n", f) < 0)
4797 PyFile_SoftSpace(f, 0);
4802 #else /* Python 3 has a print function */
4804 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4805 PyObject* kwargs = 0;
4806 PyObject* result = 0;
4807 PyObject* end_string;
4808 if (!%(PRINT_FUNCTION)s) {
4809 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4810 if (!%(PRINT_FUNCTION)s)
4814 if (!%(PRINT_KWARGS)s) {
4815 %(PRINT_KWARGS)s = PyDict_New();
4816 if (!%(PRINT_KWARGS)s)
4818 end_string = PyUnicode_FromStringAndSize(" ", 1);
4821 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4822 Py_DECREF(end_string);
4825 Py_DECREF(end_string);
4827 kwargs = %(PRINT_KWARGS)s;
4829 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4837 """ % {'BUILTINS' : Naming.builtins_cname,
4838 'PRINT_FUNCTION' : Naming.print_function,
4839 'PRINT_KWARGS' : Naming.print_function_kwargs}
4843 printing_one_utility_code = UtilityCode(
4845 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4848 #if PY_MAJOR_VERSION < 3
4850 static int __Pyx_PrintOne(PyObject *o) {
4852 if (!(f = __Pyx_GetStdout()))
4854 if (PyFile_SoftSpace(f, 0)) {
4855 if (PyFile_WriteString(" ", f) < 0)
4858 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4860 if (PyFile_WriteString("\n", f) < 0)
4863 /* the line below is just to avoid compiler
4864 * compiler warnings about unused functions */
4865 return __Pyx_Print(NULL, 0);
4868 #else /* Python 3 has a print function */
4870 static int __Pyx_PrintOne(PyObject *o) {
4872 PyObject* arg_tuple = PyTuple_New(1);
4873 if (unlikely(!arg_tuple))
4876 PyTuple_SET_ITEM(arg_tuple, 0, o);
4877 res = __Pyx_Print(arg_tuple, 1);
4878 Py_DECREF(arg_tuple);
4884 requires=[printing_utility_code])
4888 #------------------------------------------------------------------------------------
4890 # The following function is based on do_raise() from ceval.c.
4892 raise_utility_code = UtilityCode(
4894 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4897 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4901 /* First, check the traceback argument, replacing None with NULL. */
4902 if (tb == Py_None) {
4906 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4907 PyErr_SetString(PyExc_TypeError,
4908 "raise: arg 3 must be a traceback or None");
4911 /* Next, replace a missing value with None */
4912 if (value == NULL) {
4916 #if PY_VERSION_HEX < 0x02050000
4917 if (!PyClass_Check(type))
4919 if (!PyType_Check(type))
4922 /* Raising an instance. The value should be a dummy. */
4923 if (value != Py_None) {
4924 PyErr_SetString(PyExc_TypeError,
4925 "instance exception may not have a separate value");
4928 /* Normalize to raise <class>, <instance> */
4931 #if PY_VERSION_HEX < 0x02050000
4932 if (PyInstance_Check(type)) {
4933 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4938 PyErr_SetString(PyExc_TypeError,
4939 "raise: exception must be an old-style class or instance");
4943 type = (PyObject*) Py_TYPE(type);
4945 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4946 PyErr_SetString(PyExc_TypeError,
4947 "raise: exception class must be a subclass of BaseException");
4952 __Pyx_ErrRestore(type, value, tb);
4962 #------------------------------------------------------------------------------------
4964 reraise_utility_code = UtilityCode(
4966 static void __Pyx_ReRaise(void); /*proto*/
4969 static void __Pyx_ReRaise(void) {
4970 PyThreadState *tstate = PyThreadState_GET();
4971 PyObject* tmp_type = tstate->curexc_type;
4972 PyObject* tmp_value = tstate->curexc_value;
4973 PyObject* tmp_tb = tstate->curexc_traceback;
4974 tstate->curexc_type = tstate->exc_type;
4975 tstate->curexc_value = tstate->exc_value;
4976 tstate->curexc_traceback = tstate->exc_traceback;
4977 tstate->exc_type = 0;
4978 tstate->exc_value = 0;
4979 tstate->exc_traceback = 0;
4980 Py_XDECREF(tmp_type);
4981 Py_XDECREF(tmp_value);
4986 #------------------------------------------------------------------------------------
4988 arg_type_test_utility_code = UtilityCode(
4990 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4991 const char *name, int exact); /*proto*/
4994 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4995 const char *name, int exact)
4998 PyErr_Format(PyExc_SystemError, "Missing type object");
5001 if (none_allowed && obj == Py_None) return 1;
5003 if (Py_TYPE(obj) == type) return 1;
5006 if (PyObject_TypeCheck(obj, type)) return 1;
5008 PyErr_Format(PyExc_TypeError,
5009 "Argument '%s' has incorrect type (expected %s, got %s)",
5010 name, type->tp_name, Py_TYPE(obj)->tp_name);
5015 #------------------------------------------------------------------------------------
5017 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5018 # many or too few positional arguments were found. This handles
5019 # Py_ssize_t formatting correctly.
5021 raise_argtuple_invalid_utility_code = UtilityCode(
5023 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5024 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5027 static void __Pyx_RaiseArgtupleInvalid(
5028 const char* func_name,
5032 Py_ssize_t num_found)
5034 Py_ssize_t num_expected;
5035 const char *number, *more_or_less;
5037 if (num_found < num_min) {
5038 num_expected = num_min;
5039 more_or_less = "at least";
5041 num_expected = num_max;
5042 more_or_less = "at most";
5045 more_or_less = "exactly";
5047 number = (num_expected == 1) ? "" : "s";
5048 PyErr_Format(PyExc_TypeError,
5049 #if PY_VERSION_HEX < 0x02050000
5050 "%s() takes %s %d positional argument%s (%d given)",
5052 "%s() takes %s %zd positional argument%s (%zd given)",
5054 func_name, more_or_less, num_expected, number, num_found);
5058 raise_keyword_required_utility_code = UtilityCode(
5060 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5063 static INLINE void __Pyx_RaiseKeywordRequired(
5064 const char* func_name,
5067 PyErr_Format(PyExc_TypeError,
5068 #if PY_MAJOR_VERSION >= 3
5069 "%s() needs keyword-only argument %U", func_name, kw_name);
5071 "%s() needs keyword-only argument %s", func_name,
5072 PyString_AS_STRING(kw_name));
5077 raise_double_keywords_utility_code = UtilityCode(
5079 static void __Pyx_RaiseDoubleKeywordsError(
5080 const char* func_name, PyObject* kw_name); /*proto*/
5083 static void __Pyx_RaiseDoubleKeywordsError(
5084 const char* func_name,
5087 PyErr_Format(PyExc_TypeError,
5088 #if PY_MAJOR_VERSION >= 3
5089 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5091 "%s() got multiple values for keyword argument '%s'", func_name,
5092 PyString_AS_STRING(kw_name));
5097 #------------------------------------------------------------------------------------
5099 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5100 # were passed to a function, or if any keywords were passed to a
5101 # function that does not accept them.
5103 keyword_string_check_utility_code = UtilityCode(
5105 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5106 const char* function_name, int kw_allowed); /*proto*/
5109 static INLINE int __Pyx_CheckKeywordStrings(
5111 const char* function_name,
5116 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5117 #if PY_MAJOR_VERSION < 3
5118 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5120 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5122 goto invalid_keyword_type;
5124 if ((!kw_allowed) && unlikely(key))
5125 goto invalid_keyword;
5127 invalid_keyword_type:
5128 PyErr_Format(PyExc_TypeError,
5129 "%s() keywords must be strings", function_name);
5132 PyErr_Format(PyExc_TypeError,
5133 #if PY_MAJOR_VERSION < 3
5134 "%s() got an unexpected keyword argument '%s'",
5135 function_name, PyString_AsString(key));
5137 "%s() got an unexpected keyword argument '%U'",
5138 function_name, key);
5144 #------------------------------------------------------------------------------------
5146 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5147 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5148 # keywords will raise an invalid keyword error.
5150 # Three kinds of errors are checked: 1) non-string keywords, 2)
5151 # unexpected keywords and 3) overlap with positional arguments.
5153 # If num_posargs is greater 0, it denotes the number of positional
5154 # arguments that were passed and that must therefore not appear
5155 # amongst the keywords as well.
5157 # This method does not check for required keyword arguments.
5160 parse_keywords_utility_code = UtilityCode(
5162 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5163 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5164 const char* function_name); /*proto*/
5167 static int __Pyx_ParseOptionalKeywords(
5169 PyObject **argnames[],
5172 Py_ssize_t num_pos_args,
5173 const char* function_name)
5175 PyObject *key = 0, *value = 0;
5178 PyObject*** first_kw_arg = argnames + num_pos_args;
5180 while (PyDict_Next(kwds, &pos, &key, &value)) {
5181 name = first_kw_arg;
5182 while (*name && (**name != key)) name++;
5184 values[name-argnames] = value;
5186 #if PY_MAJOR_VERSION < 3
5187 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5189 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5191 goto invalid_keyword_type;
5193 for (name = first_kw_arg; *name; name++) {
5194 #if PY_MAJOR_VERSION >= 3
5195 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5196 PyUnicode_Compare(**name, key) == 0) break;
5198 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5199 _PyString_Eq(**name, key)) break;
5203 values[name-argnames] = value;
5205 /* unexpected keyword found */
5206 for (name=argnames; name != first_kw_arg; name++) {
5207 if (**name == key) goto arg_passed_twice;
5208 #if PY_MAJOR_VERSION >= 3
5209 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5210 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5212 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5213 _PyString_Eq(**name, key)) goto arg_passed_twice;
5217 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5219 goto invalid_keyword;
5227 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5229 invalid_keyword_type:
5230 PyErr_Format(PyExc_TypeError,
5231 "%s() keywords must be strings", function_name);
5234 PyErr_Format(PyExc_TypeError,
5235 #if PY_MAJOR_VERSION < 3
5236 "%s() got an unexpected keyword argument '%s'",
5237 function_name, PyString_AsString(key));
5239 "%s() got an unexpected keyword argument '%U'",
5240 function_name, key);
5247 #------------------------------------------------------------------------------------
5249 traceback_utility_code = UtilityCode(
5251 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5254 #include "compile.h"
5255 #include "frameobject.h"
5256 #include "traceback.h"
5258 static void __Pyx_AddTraceback(const char *funcname) {
5259 PyObject *py_srcfile = 0;
5260 PyObject *py_funcname = 0;
5261 PyObject *py_globals = 0;
5262 PyObject *empty_string = 0;
5263 PyCodeObject *py_code = 0;
5264 PyFrameObject *py_frame = 0;
5266 #if PY_MAJOR_VERSION < 3
5267 py_srcfile = PyString_FromString(%(FILENAME)s);
5269 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5271 if (!py_srcfile) goto bad;
5273 #if PY_MAJOR_VERSION < 3
5274 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5276 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5280 #if PY_MAJOR_VERSION < 3
5281 py_funcname = PyString_FromString(funcname);
5283 py_funcname = PyUnicode_FromString(funcname);
5286 if (!py_funcname) goto bad;
5287 py_globals = PyModule_GetDict(%(GLOBALS)s);
5288 if (!py_globals) goto bad;
5289 #if PY_MAJOR_VERSION < 3
5290 empty_string = PyString_FromStringAndSize("", 0);
5292 empty_string = PyBytes_FromStringAndSize("", 0);
5294 if (!empty_string) goto bad;
5295 py_code = PyCode_New(
5296 0, /*int argcount,*/
5297 #if PY_MAJOR_VERSION >= 3
5298 0, /*int kwonlyargcount,*/
5301 0, /*int stacksize,*/
5303 empty_string, /*PyObject *code,*/
5304 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5305 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5306 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5307 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5308 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5309 py_srcfile, /*PyObject *filename,*/
5310 py_funcname, /*PyObject *name,*/
5311 %(LINENO)s, /*int firstlineno,*/
5312 empty_string /*PyObject *lnotab*/
5314 if (!py_code) goto bad;
5315 py_frame = PyFrame_New(
5316 PyThreadState_GET(), /*PyThreadState *tstate,*/
5317 py_code, /*PyCodeObject *code,*/
5318 py_globals, /*PyObject *globals,*/
5319 0 /*PyObject *locals*/
5321 if (!py_frame) goto bad;
5322 py_frame->f_lineno = %(LINENO)s;
5323 PyTraceBack_Here(py_frame);
5325 Py_XDECREF(py_srcfile);
5326 Py_XDECREF(py_funcname);
5327 Py_XDECREF(empty_string);
5328 Py_XDECREF(py_code);
5329 Py_XDECREF(py_frame);
5332 'FILENAME': Naming.filename_cname,
5333 'LINENO': Naming.lineno_cname,
5334 'CFILENAME': Naming.cfilenm_cname,
5335 'CLINENO': Naming.clineno_cname,
5336 'GLOBALS': Naming.module_cname,
5337 'EMPTY_TUPLE' : Naming.empty_tuple,
5340 restore_exception_utility_code = UtilityCode(
5342 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5343 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5346 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5347 PyObject *tmp_type, *tmp_value, *tmp_tb;
5348 PyThreadState *tstate = PyThreadState_GET();
5350 #if PY_MAJOR_VERSION >= 3
5351 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5352 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5353 tmp_type = tstate->exc_type;
5354 tmp_value = tstate->exc_value;
5355 tmp_tb = tstate->exc_traceback;
5356 PyErr_NormalizeException(&type, &value, &tb);
5357 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5358 tstate->exc_type = 0;
5359 tstate->exc_value = 0;
5360 tstate->exc_traceback = 0;
5361 PyException_SetContext(value, tmp_value);
5362 Py_DECREF(tmp_type);
5367 tmp_type = tstate->curexc_type;
5368 tmp_value = tstate->curexc_value;
5369 tmp_tb = tstate->curexc_traceback;
5370 tstate->curexc_type = type;
5371 tstate->curexc_value = value;
5372 tstate->curexc_traceback = tb;
5373 Py_XDECREF(tmp_type);
5374 Py_XDECREF(tmp_value);
5378 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5379 PyThreadState *tstate = PyThreadState_GET();
5380 *type = tstate->curexc_type;
5381 *value = tstate->curexc_value;
5382 *tb = tstate->curexc_traceback;
5384 tstate->curexc_type = 0;
5385 tstate->curexc_value = 0;
5386 tstate->curexc_traceback = 0;
5391 #------------------------------------------------------------------------------------
5393 unraisable_exception_utility_code = UtilityCode(
5395 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5398 static void __Pyx_WriteUnraisable(const char *name) {
5399 PyObject *old_exc, *old_val, *old_tb;
5401 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5402 #if PY_MAJOR_VERSION < 3
5403 ctx = PyString_FromString(name);
5405 ctx = PyUnicode_FromString(name);
5407 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5409 PyErr_WriteUnraisable(Py_None);
5411 PyErr_WriteUnraisable(ctx);
5416 requires=[restore_exception_utility_code])
5418 #------------------------------------------------------------------------------------
5420 set_vtable_utility_code = UtilityCode(
5422 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5425 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5426 PyObject *pycobj = 0;
5429 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5432 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5445 #------------------------------------------------------------------------------------
5447 get_vtable_utility_code = UtilityCode(
5449 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5452 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5456 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5459 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5460 if (!*(void **)vtabptr)
5473 #------------------------------------------------------------------------------------
5475 init_string_tab_utility_code = UtilityCode(
5477 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5480 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5482 #if PY_MAJOR_VERSION < 3
5483 if (t->is_unicode && (!t->is_identifier)) {
5484 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5485 } else if (t->intern) {
5486 *t->p = PyString_InternFromString(t->s);
5488 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5490 #else /* Python 3+ has unicode identifiers */
5491 if (t->is_identifier || (t->is_unicode && t->intern)) {
5492 *t->p = PyUnicode_InternFromString(t->s);
5493 } else if (t->is_unicode) {
5494 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5496 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5507 #------------------------------------------------------------------------------------
5509 get_exception_utility_code = UtilityCode(
5511 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5514 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5515 PyObject *tmp_type, *tmp_value, *tmp_tb;
5516 PyThreadState *tstate = PyThreadState_GET();
5517 *type = tstate->curexc_type;
5518 *value = tstate->curexc_value;
5519 *tb = tstate->curexc_traceback;
5520 tstate->curexc_type = 0;
5521 tstate->curexc_value = 0;
5522 tstate->curexc_traceback = 0;
5523 PyErr_NormalizeException(type, value, tb);
5524 if (PyErr_Occurred())
5529 tmp_type = tstate->exc_type;
5530 tmp_value = tstate->exc_value;
5531 tmp_tb = tstate->exc_traceback;
5532 tstate->exc_type = *type;
5533 tstate->exc_value = *value;
5534 tstate->exc_traceback = *tb;
5535 /* Make sure tstate is in a consistent state when we XDECREF
5536 these objects (XDECREF may run arbitrary code). */
5537 Py_XDECREF(tmp_type);
5538 Py_XDECREF(tmp_value);
5550 #------------------------------------------------------------------------------------
5552 reset_exception_utility_code = UtilityCode(
5554 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5555 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5558 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5559 PyThreadState *tstate = PyThreadState_GET();
5560 *type = tstate->exc_type;
5561 *value = tstate->exc_value;
5562 *tb = tstate->exc_traceback;
5568 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5569 PyObject *tmp_type, *tmp_value, *tmp_tb;
5570 PyThreadState *tstate = PyThreadState_GET();
5571 tmp_type = tstate->exc_type;
5572 tmp_value = tstate->exc_value;
5573 tmp_tb = tstate->exc_traceback;
5574 tstate->exc_type = type;
5575 tstate->exc_value = value;
5576 tstate->exc_traceback = tb;
5577 Py_XDECREF(tmp_type);
5578 Py_XDECREF(tmp_value);
5583 #------------------------------------------------------------------------------------
5585 force_init_threads_utility_code = UtilityCode(
5587 #ifndef __PYX_FORCE_INIT_THREADS
5588 #if PY_VERSION_HEX < 0x02040200
5589 #define __PYX_FORCE_INIT_THREADS 1
5591 #define __PYX_FORCE_INIT_THREADS 0
5596 #------------------------------------------------------------------------------------