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 need_property = False
782 if (dest_scope.is_c_class_scope
783 and self.visibility == 'public'
784 and base_type.is_pyobject
785 and (base_type.is_builtin_type or base_type.is_extension_type)):
786 # If the field is settable and extension type, then the CPython mechanism does
787 # not do enough type-checking for us.
789 elif (base_type.is_typedef and base_type.typedef_is_external
790 and (self.visibility in ('public', 'readonly'))):
791 # If the field is an external typedef, we cannot be sure about the type,
792 # so do conversion ourself rather than rely on the CPython mechanism (through
793 # a property; made in AnalyseDeclarationsTransform).
797 visibility = 'private'
798 self.need_properties = []
800 visibility = self.visibility
802 for declarator in self.declarators:
803 name_declarator, type = declarator.analyse(base_type, env)
804 if not type.is_complete():
805 if not (self.visibility == 'extern' and type.is_array):
806 error(declarator.pos,
807 "Variable type '%s' is incomplete" % type)
808 if self.visibility == 'extern' and type.is_pyobject:
809 error(declarator.pos,
810 "Python object cannot be declared extern")
811 name = name_declarator.name
812 cname = name_declarator.cname
814 error(declarator.pos, "Missing name in declaration.")
816 if type.is_cfunction:
817 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
818 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
820 if entry is not None:
821 entry.directive_locals = self.directive_locals
823 if self.directive_locals:
824 s.error("Decorators can only be followed by functions")
825 if self.in_pxd and self.visibility != 'extern':
827 "Only 'extern' C variable declaration allowed in .pxd file")
828 entry = dest_scope.declare_var(name, type, declarator.pos,
829 cname = cname, visibility = visibility, is_cdef = 1)
831 self.need_properties.append(entry)
832 entry.needs_property = 1
835 class CStructOrUnionDefNode(StatNode):
837 # cname string or None
838 # kind "struct" or "union"
839 # typedef_flag boolean
840 # visibility "public" or "private"
842 # attributes [CVarDefNode] or None
846 child_attrs = ["attributes"]
848 def analyse_declarations(self, env):
850 if self.visibility == 'extern' and self.packed:
851 error(self.pos, "Cannot declare extern struct as 'packed'")
852 if self.attributes is not None:
853 scope = StructOrUnionScope(self.name)
854 self.entry = env.declare_struct_or_union(
855 self.name, self.kind, scope, self.typedef_flag, self.pos,
856 self.cname, visibility = self.visibility, packed = self.packed)
857 if self.attributes is not None:
858 if self.in_pxd and not env.in_cinclude:
859 self.entry.defined_in_pxd = 1
860 for attr in self.attributes:
861 attr.analyse_declarations(env, scope)
862 if self.visibility != 'extern':
863 need_typedef_indirection = False
864 for attr in scope.var_entries:
867 type = type.base_type
868 if type == self.entry.type:
869 error(attr.pos, "Struct cannot contain itself as a member.")
870 if self.typedef_flag:
872 type = type.base_type
873 if type == self.entry.type:
874 need_typedef_indirection = True
875 if need_typedef_indirection:
876 # C can't handle typedef structs that refer to themselves.
877 struct_entry = self.entry
878 self.entry = env.declare_typedef(
879 self.name, struct_entry.type, self.pos,
880 cname = self.cname, visibility='ignore')
881 struct_entry.type.typedef_flag = False
882 # FIXME: this might be considered a hack ;-)
883 struct_entry.cname = struct_entry.type.cname = \
884 '_' + self.entry.type.typedef_cname
886 def analyse_expressions(self, env):
889 def generate_execution_code(self, code):
893 class CEnumDefNode(StatNode):
894 # name string or None
895 # cname string or None
896 # items [CEnumDefItemNode]
897 # typedef_flag boolean
898 # visibility "public" or "private"
902 child_attrs = ["items"]
904 def analyse_declarations(self, env):
905 self.entry = env.declare_enum(self.name, self.pos,
906 cname = self.cname, typedef_flag = self.typedef_flag,
907 visibility = self.visibility)
908 if self.items is not None:
909 if self.in_pxd and not env.in_cinclude:
910 self.entry.defined_in_pxd = 1
911 for item in self.items:
912 item.analyse_declarations(env, self.entry)
914 def generate_execution_code(self, code):
915 if self.visibility == 'public':
916 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
917 for item in self.entry.enum_values:
918 code.putln("%s = PyInt_FromLong(%s); %s" % (
921 code.error_goto_if_null(temp, item.pos)))
922 code.put_gotref(temp)
923 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
927 code.error_goto(item.pos)))
928 code.put_decref_clear(temp, PyrexTypes.py_object_type)
929 code.funcstate.release_temp(temp)
932 class CEnumDefItemNode(StatNode):
934 # cname string or None
935 # value ExprNode or None
937 child_attrs = ["value"]
939 def analyse_declarations(self, env, enum_entry):
941 self.value.analyse_const_expression(env)
942 if not self.value.type.is_int:
943 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
944 self.value.analyse_const_expression(env)
945 entry = env.declare_const(self.name, enum_entry.type,
946 self.value, self.pos, cname = self.cname,
947 visibility = enum_entry.visibility)
948 enum_entry.enum_values.append(entry)
951 class CTypeDefNode(StatNode):
952 # base_type CBaseTypeNode
953 # declarator CDeclaratorNode
954 # visibility "public" or "private"
957 child_attrs = ["base_type", "declarator"]
959 def analyse_declarations(self, env):
960 base = self.base_type.analyse(env)
961 name_declarator, type = self.declarator.analyse(base, env)
962 name = name_declarator.name
963 cname = name_declarator.cname
964 entry = env.declare_typedef(name, type, self.pos,
965 cname = cname, visibility = self.visibility)
966 if self.in_pxd and not env.in_cinclude:
967 entry.defined_in_pxd = 1
969 def analyse_expressions(self, env):
971 def generate_execution_code(self, code):
975 class FuncDefNode(StatNode, BlockNode):
976 # Base class for function definition nodes.
978 # return_type PyrexType
979 # #filename string C name of filename string const
981 # needs_closure boolean Whether or not this function has inner functions/classes/yield
982 # directive_locals { string : NameNode } locals defined by cython.locals(...)
986 needs_closure = False
988 def analyse_default_values(self, env):
989 genv = env.global_scope()
990 for arg in self.args:
993 arg.default.analyse_types(env)
994 arg.default = arg.default.coerce_to(arg.type, genv)
997 "This argument cannot have a default value")
1000 def need_gil_acquisition(self, lenv):
1003 def create_local_scope(self, env):
1005 while env.is_py_class_scope or env.is_c_class_scope:
1006 env = env.outer_scope
1007 if self.needs_closure:
1008 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1010 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1011 lenv.return_type = self.return_type
1012 type = self.entry.type
1013 if type.is_cfunction:
1014 lenv.nogil = type.nogil and not type.with_gil
1015 self.local_scope = lenv
1016 lenv.directives = env.directives
1019 def generate_function_definitions(self, env, code):
1022 lenv = self.local_scope
1024 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1025 self.entry.scope.is_c_class_scope)
1027 # Generate C code for header and body of function
1028 code.enter_cfunc_scope()
1029 code.return_from_error_cleanup_label = code.new_label()
1031 # ----- Top-level constants used by this function
1032 code.mark_pos(self.pos)
1033 self.generate_cached_builtins_decls(lenv, code)
1034 # ----- Function header
1037 self.py_func.generate_function_header(code,
1038 with_pymethdef = env.is_py_class_scope,
1040 self.generate_function_header(code,
1041 with_pymethdef = env.is_py_class_scope)
1042 # ----- Local variable declarations
1043 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1044 self.generate_argument_declarations(lenv, code)
1045 if self.needs_closure:
1046 code.putln("/* TODO: declare and create scope object */")
1047 code.put_var_declarations(lenv.var_entries)
1049 if not self.return_type.is_void:
1050 if self.return_type.is_pyobject:
1054 (self.return_type.declaration_code(
1055 Naming.retval_cname),
1057 tempvardecl_code = code.insertion_point()
1058 self.generate_keyword_list(code)
1059 # ----- Extern library function declarations
1060 lenv.generate_library_function_declarations(code)
1061 # ----- GIL acquisition
1062 acquire_gil = self.need_gil_acquisition(lenv)
1064 env.use_utility_code(force_init_threads_utility_code)
1065 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1066 # ----- Automatic lead-ins for certain special functions
1068 code.put_setup_refcount_context(self.entry.name)
1069 if is_getbuffer_slot:
1070 self.getbuffer_init(code)
1071 # ----- Fetch arguments
1072 self.generate_argument_parsing_code(env, code)
1073 # If an argument is assigned to in the body, we must
1074 # incref it to properly keep track of refcounts.
1075 for entry in lenv.arg_entries:
1076 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1077 code.put_var_incref(entry)
1078 # ----- Initialise local variables
1079 for entry in lenv.var_entries:
1080 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1081 code.put_init_var_to_py_none(entry)
1082 # ----- Initialise local buffer auxiliary variables
1083 for entry in lenv.var_entries + lenv.arg_entries:
1084 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1085 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1086 # ----- Check and convert arguments
1087 self.generate_argument_type_tests(code)
1088 # ----- Acquire buffer arguments
1089 for entry in lenv.arg_entries:
1090 if entry.type.is_buffer:
1091 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1092 # ----- Function body
1093 self.body.generate_execution_code(code)
1094 # ----- Default return value
1096 if self.return_type.is_pyobject:
1097 #if self.return_type.is_extension_type:
1098 # lhs = "(PyObject *)%s" % Naming.retval_cname
1100 lhs = Naming.retval_cname
1101 code.put_init_to_py_none(lhs, self.return_type)
1103 val = self.return_type.default_value
1105 code.putln("%s = %s;" % (Naming.retval_cname, val))
1106 # ----- Error cleanup
1107 if code.error_label in code.labels_used:
1108 code.put_goto(code.return_label)
1109 code.put_label(code.error_label)
1110 for cname, type in code.funcstate.all_managed_temps():
1111 code.put_xdecref(cname, type)
1113 # Clean up buffers -- this calls a Python function
1114 # so need to save and restore error state
1115 buffers_present = len(lenv.buffer_entries) > 0
1117 code.globalstate.use_utility_code(restore_exception_utility_code)
1118 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1119 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1120 for entry in lenv.buffer_entries:
1121 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1122 #code.putln("%s = 0;" % entry.cname)
1123 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1125 err_val = self.error_value()
1126 exc_check = self.caller_will_check_exceptions()
1127 if err_val is not None or exc_check:
1128 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1130 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1131 % self.entry.qualified_name, 0)
1133 '__Pyx_WriteUnraisable("%s");' %
1134 self.entry.qualified_name)
1135 env.use_utility_code(unraisable_exception_utility_code)
1136 env.use_utility_code(restore_exception_utility_code)
1137 default_retval = self.return_type.default_value
1138 if err_val is None and default_retval:
1139 err_val = default_retval
1140 if err_val is not None:
1143 Naming.retval_cname,
1146 if is_getbuffer_slot:
1147 self.getbuffer_error_cleanup(code)
1149 # If we are using the non-error cleanup section we should
1150 # jump past it if we have an error. The if-test below determine
1151 # whether this section is used.
1152 if buffers_present or is_getbuffer_slot:
1153 code.put_goto(code.return_from_error_cleanup_label)
1156 # ----- Non-error return cleanup
1157 # If you add anything here, remember to add a condition to the
1158 # if-test above in the error block (so that it can jump past this
1160 code.put_label(code.return_label)
1161 for entry in lenv.buffer_entries:
1163 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1164 if is_getbuffer_slot:
1165 self.getbuffer_normal_cleanup(code)
1166 # ----- Return cleanup for both error and no-error return
1167 code.put_label(code.return_from_error_cleanup_label)
1168 if not Options.init_local_none:
1169 for entry in lenv.var_entries:
1170 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1171 entry.xdecref_cleanup = 1
1172 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1173 # Decref any increfed args
1174 for entry in lenv.arg_entries:
1175 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1176 code.put_var_decref(entry)
1178 # code.putln("/* TODO: decref scope object */")
1180 # This code is duplicated in ModuleNode.generate_module_init_func
1182 default_retval = self.return_type.default_value
1183 err_val = self.error_value()
1184 if err_val is None and default_retval:
1185 err_val = default_retval
1186 if self.return_type.is_pyobject:
1187 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1189 code.put_finish_refcount_context()
1192 code.putln("PyGILState_Release(_save);")
1194 if not self.return_type.is_void:
1195 code.putln("return %s;" % Naming.retval_cname)
1198 # ----- Go back and insert temp variable declarations
1199 tempvardecl_code.put_temp_declarations(code.funcstate)
1200 # ----- Python version
1201 code.exit_cfunc_scope()
1203 self.py_func.generate_function_definitions(env, code)
1204 self.generate_wrapper_functions(code)
1206 def declare_argument(self, env, arg):
1207 if arg.type.is_void:
1208 error(arg.pos, "Invalid use of 'void'")
1209 elif not arg.type.is_complete() and not arg.type.is_array:
1211 "Argument type '%s' is incomplete" % arg.type)
1212 return env.declare_arg(arg.name, arg.type, arg.pos)
1214 def generate_wrapper_functions(self, code):
1217 def generate_execution_code(self, code):
1218 # Evaluate and store argument default values
1219 for arg in self.args:
1220 default = arg.default
1222 if not default.is_literal:
1223 default.generate_evaluation_code(code)
1224 default.make_owned_reference(code)
1225 result = default.result_as(arg.type)
1228 arg.calculate_default_value_code(code),
1230 if arg.type.is_pyobject:
1231 code.put_giveref(default.result())
1232 default.generate_post_assignment_code(code)
1233 default.free_temps(code)
1234 # For Python class methods, create and store function object
1236 self.assmt.generate_execution_code(code)
1239 # Special code for the __getbuffer__ function
1241 def getbuffer_init(self, code):
1242 info = self.local_scope.arg_entries[1].cname
1243 # Python 3.0 betas have a bug in memoryview which makes it call
1244 # getbuffer with a NULL parameter. For now we work around this;
1245 # the following line should be removed when this bug is fixed.
1246 code.putln("if (%s == NULL) return 0;" % info)
1247 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1248 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1250 def getbuffer_error_cleanup(self, code):
1251 info = self.local_scope.arg_entries[1].cname
1252 code.put_gotref("%s->obj" % info)
1253 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1256 def getbuffer_normal_cleanup(self, code):
1257 info = self.local_scope.arg_entries[1].cname
1258 code.putln("if (%s->obj == Py_None) {" % info)
1259 code.put_gotref("Py_None")
1260 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1263 class CFuncDefNode(FuncDefNode):
1264 # C function definition.
1266 # modifiers ['inline']
1267 # visibility 'private' or 'public' or 'extern'
1268 # base_type CBaseTypeNode
1269 # declarator CDeclaratorNode
1272 # decorators [DecoratorNode] list of decorators
1274 # with_gil boolean Acquire GIL around body
1276 # py_func wrapper for calling from Python
1277 # overridable whether or not this is a cpdef function
1278 # inline_in_pxd whether this is an inline function in a pxd file
1280 child_attrs = ["base_type", "declarator", "body", "py_func"]
1282 inline_in_pxd = False
1284 directive_locals = {}
1286 def unqualified_name(self):
1287 return self.entry.name
1289 def analyse_declarations(self, env):
1290 directive_locals = self.directive_locals = env.directives['locals']
1291 base_type = self.base_type.analyse(env)
1292 # The 2 here is because we need both function and argument names.
1293 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1294 if not type.is_cfunction:
1296 "Suite attached to non-function declaration")
1297 # Remember the actual type according to the function header
1298 # written here, because the type in the symbol table entry
1299 # may be different if we're overriding a C method inherited
1300 # from the base type of an extension type.
1302 type.is_overridable = self.overridable
1303 declarator = self.declarator
1304 while not hasattr(declarator, 'args'):
1305 declarator = declarator.base
1306 self.args = declarator.args
1307 for formal_arg, type_arg in zip(self.args, type.args):
1308 formal_arg.type = type_arg.type
1309 formal_arg.name = type_arg.name
1310 formal_arg.cname = type_arg.cname
1311 name = name_declarator.name
1312 cname = name_declarator.cname
1313 self.entry = env.declare_cfunction(
1314 name, type, self.pos,
1315 cname = cname, visibility = self.visibility,
1316 defining = self.body is not None,
1317 api = self.api, modifiers = self.modifiers)
1318 self.entry.inline_func_in_pxd = self.inline_in_pxd
1319 self.return_type = type.return_type
1321 if self.overridable and not env.is_module_scope:
1322 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1323 # An error will be produced in the cdef function
1324 self.overridable = False
1326 if self.overridable:
1328 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1329 self.py_func = DefNode(pos = self.pos,
1330 name = self.entry.name,
1333 starstar_arg = None,
1335 body = py_func_body,
1337 self.py_func.is_module_scope = env.is_module_scope
1338 self.py_func.analyse_declarations(env)
1339 self.entry.as_variable = self.py_func.entry
1340 # Reset scope entry the above cfunction
1341 env.entries[name] = self.entry
1342 if not env.is_module_scope or Options.lookup_module_cpdef:
1343 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1344 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1346 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1348 args = self.type.args
1349 if omit_optional_args:
1350 args = args[:len(args) - self.type.optional_arg_count]
1351 arg_names = [arg.name for arg in args]
1353 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1355 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1356 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1357 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1358 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)
1359 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1361 def declare_arguments(self, env):
1362 for arg in self.type.args:
1364 error(arg.pos, "Missing argument name")
1365 self.declare_argument(env, arg)
1367 def need_gil_acquisition(self, lenv):
1368 return self.type.with_gil
1370 def gil_check(self, env):
1372 with_gil = type.with_gil
1373 if type.nogil and not with_gil:
1374 if type.return_type.is_pyobject:
1376 "Function with Python return type cannot be declared nogil")
1377 for entry in env.var_entries:
1378 if entry.type.is_pyobject:
1379 error(self.pos, "Function declared nogil has Python locals or temporaries")
1381 def analyse_expressions(self, env):
1382 self.local_scope.directives = env.directives
1383 if self.py_func is not None:
1384 # this will also analyse the default values
1385 self.py_func.analyse_expressions(env)
1387 self.analyse_default_values(env)
1389 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1392 visibility = self.entry.visibility
1393 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1394 arg_decls.append(arg.declaration_code())
1395 if with_dispatch and self.overridable:
1396 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1397 if type.optional_arg_count and with_opt_args:
1398 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1399 if type.has_varargs:
1400 arg_decls.append("...")
1402 arg_decls = ["void"]
1404 cname = self.entry.func_cname
1405 entity = type.function_header_code(cname, ', '.join(arg_decls))
1406 if visibility == 'public':
1407 dll_linkage = "DL_EXPORT"
1410 header = self.return_type.declaration_code(entity,
1411 dll_linkage = dll_linkage)
1412 if visibility == 'extern':
1413 storage_class = "%s " % Naming.extern_c_macro
1414 elif visibility == 'public':
1417 storage_class = "static "
1418 code.putln("%s%s %s {" % (
1420 ' '.join(self.modifiers).upper(), # macro forms
1423 def generate_argument_declarations(self, env, code):
1424 for arg in self.args:
1426 result = arg.calculate_default_value_code(code)
1427 code.putln('%s = %s;' % (
1428 arg.type.declaration_code(arg.cname), result))
1430 def generate_keyword_list(self, code):
1433 def generate_argument_parsing_code(self, env, code):
1435 if self.type.optional_arg_count:
1436 code.putln('if (%s) {' % Naming.optional_args_cname)
1437 for arg in self.args:
1439 # FIXME: simple name prefixing doesn't work when
1440 # argument name mangling is in place
1441 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1442 declarator = arg.declarator
1443 while not hasattr(declarator, 'name'):
1444 declarator = declarator.base
1445 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1447 for _ in range(self.type.optional_arg_count):
1451 def generate_argument_conversion_code(self, code):
1454 def generate_argument_type_tests(self, code):
1455 # Generate type tests for args whose type in a parent
1456 # class is a supertype of the declared type.
1457 for arg in self.type.args:
1458 if arg.needs_type_test:
1459 self.generate_arg_type_test(arg, code)
1461 def generate_arg_type_test(self, arg, code):
1462 # Generate type test for one argument.
1463 if arg.type.typeobj_is_available():
1464 typeptr_cname = arg.type.typeptr_cname
1465 arg_code = "((PyObject *)%s)" % arg.cname
1467 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1472 type.is_builtin_type,
1473 code.error_goto(arg.pos)))
1475 error(arg.pos, "Cannot test type of extern C class "
1476 "without type object name specification")
1478 def error_value(self):
1479 if self.return_type.is_pyobject:
1483 return self.entry.type.exception_value
1485 def caller_will_check_exceptions(self):
1486 return self.entry.type.exception_check
1488 def generate_wrapper_functions(self, code):
1489 # If the C signature of a function has changed, we need to generate
1490 # wrappers to put in the slots here.
1493 func_type = entry.type
1494 while entry.prev_entry is not None:
1496 entry = entry.prev_entry
1497 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1499 self.generate_function_header(code,
1501 with_dispatch = entry.type.is_overridable,
1502 with_opt_args = entry.type.optional_arg_count,
1503 cname = entry.func_cname)
1504 if not self.return_type.is_void:
1506 args = self.type.args
1507 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1508 if entry.type.is_overridable:
1509 arglist.append(Naming.skip_dispatch_cname)
1510 elif func_type.is_overridable:
1512 if entry.type.optional_arg_count:
1513 arglist.append(Naming.optional_args_cname)
1514 elif func_type.optional_arg_count:
1515 arglist.append('NULL')
1516 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1520 class PyArgDeclNode(Node):
1521 # Argument which must be a Python object (used
1522 # for * and ** arguments).
1525 # entry Symtab.Entry
1529 class DecoratorNode(Node):
1532 # decorator NameNode or CallNode
1533 child_attrs = ['decorator']
1536 class DefNode(FuncDefNode):
1537 # A Python function definition.
1539 # name string the Python name of the function
1540 # decorators [DecoratorNode] list of decorators
1541 # args [CArgDeclNode] formal arguments
1542 # star_arg PyArgDeclNode or None * argument
1543 # starstar_arg PyArgDeclNode or None ** argument
1544 # doc EncodedString or None
1547 # The following subnode is constructed internally
1548 # when the def statement is inside a Python class definition.
1550 # assmt AssignmentNode Function construction/assignment
1552 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1556 num_required_kw_args = 0
1557 reqd_kw_flags_cname = "0"
1563 def __init__(self, pos, **kwds):
1564 FuncDefNode.__init__(self, pos, **kwds)
1566 for arg in self.args:
1573 self.num_kwonly_args = k
1574 self.num_required_kw_args = rk
1575 self.num_required_args = r
1577 def as_cfunction(self, cfunc=None, scope=None):
1579 error(self.star_arg.pos, "cdef function cannot have star argument")
1580 if self.starstar_arg:
1581 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1584 for formal_arg in self.args:
1585 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1586 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1588 type = py_object_type,
1589 pos = formal_arg.pos))
1590 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1592 has_varargs = False,
1593 exception_value = None,
1594 exception_check = False,
1597 is_overridable = True)
1598 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1600 cfunc_type = cfunc.type
1601 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1602 error(self.pos, "wrong number of arguments")
1603 error(declarator.pos, "previous declaration here")
1604 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1605 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1606 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1607 formal_arg.type = type_arg.type
1608 formal_arg.name_declarator = name_declarator
1610 if cfunc_type.exception_value is None:
1611 exception_value = None
1613 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1614 declarator = CFuncDeclaratorNode(self.pos,
1615 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1617 has_varargs = False,
1618 exception_check = cfunc_type.exception_check,
1619 exception_value = exception_value,
1620 with_gil = cfunc_type.with_gil,
1621 nogil = cfunc_type.nogil)
1622 return CFuncDefNode(self.pos,
1624 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1625 declarator = declarator,
1628 overridable = cfunc_type.is_overridable,
1630 with_gil = cfunc_type.with_gil,
1631 nogil = cfunc_type.nogil,
1632 visibility = 'private',
1634 directive_locals = getattr(cfunc, 'directive_locals', {}))
1636 def analyse_declarations(self, env):
1637 directive_locals = self.directive_locals = env.directives['locals']
1638 for arg in self.args:
1639 if hasattr(arg, 'name'):
1641 name_declarator = None
1643 base_type = arg.base_type.analyse(env)
1644 name_declarator, type = \
1645 arg.declarator.analyse(base_type, env)
1646 arg.name = name_declarator.name
1647 if arg.name in directive_locals:
1648 type_node = directive_locals[arg.name]
1649 other_type = type_node.analyse_as_type(env)
1650 if other_type is None:
1651 error(type_node.pos, "Not a type")
1652 elif (type is not PyrexTypes.py_object_type
1653 and not type.same_as(other_type)):
1654 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1655 error(type_node.pos, "Previous declaration here")
1658 if name_declarator and name_declarator.cname:
1660 "Python function argument cannot have C name specification")
1661 arg.type = type.as_argument_type()
1663 arg.needs_conversion = 0
1664 arg.needs_type_test = 0
1666 if arg.not_none and not arg.type.is_extension_type:
1668 "Only extension type arguments can have 'not None'")
1669 self.declare_pyfunction(env)
1670 self.analyse_signature(env)
1671 self.return_type = self.entry.signature.return_type()
1673 def analyse_signature(self, env):
1674 any_type_tests_needed = 0
1675 if self.entry.is_special:
1676 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1677 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1678 # Use the simpler calling signature for zero- and one-argument functions.
1679 if self.entry.signature is TypeSlots.pyfunction_signature:
1680 if len(self.args) == 0:
1681 self.entry.signature = TypeSlots.pyfunction_noargs
1682 elif len(self.args) == 1:
1683 if self.args[0].default is None and not self.args[0].kw_only:
1684 self.entry.signature = TypeSlots.pyfunction_onearg
1685 elif self.entry.signature is TypeSlots.pymethod_signature:
1686 if len(self.args) == 1:
1687 self.entry.signature = TypeSlots.unaryfunc
1688 elif len(self.args) == 2:
1689 if self.args[1].default is None and not self.args[1].kw_only:
1690 self.entry.signature = TypeSlots.ibinaryfunc
1691 sig = self.entry.signature
1692 nfixed = sig.num_fixed_args()
1693 for i in range(nfixed):
1694 if i < len(self.args):
1697 if sig.is_self_arg(i):
1699 arg.hdr_type = arg.type = env.parent_type
1700 arg.needs_conversion = 0
1702 arg.hdr_type = sig.fixed_arg_type(i)
1703 if not arg.type.same_as(arg.hdr_type):
1704 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1705 arg.needs_type_test = 1
1706 any_type_tests_needed = 1
1708 arg.needs_conversion = 1
1709 if arg.needs_conversion:
1710 arg.hdr_cname = Naming.arg_prefix + arg.name
1712 arg.hdr_cname = Naming.var_prefix + arg.name
1714 self.bad_signature()
1716 if nfixed < len(self.args):
1717 if not sig.has_generic_args:
1718 self.bad_signature()
1719 for arg in self.args:
1720 if arg.is_generic and \
1721 (arg.type.is_extension_type or arg.type.is_builtin_type):
1722 arg.needs_type_test = 1
1723 any_type_tests_needed = 1
1724 if any_type_tests_needed:
1725 env.use_utility_code(arg_type_test_utility_code)
1727 def bad_signature(self):
1728 sig = self.entry.signature
1729 expected_str = "%d" % sig.num_fixed_args()
1730 if sig.has_generic_args:
1731 expected_str = expected_str + " or more"
1733 if name.startswith("__") and name.endswith("__"):
1734 desc = "Special method"
1738 "%s %s has wrong number of arguments "
1739 "(%d declared, %s expected)" % (
1740 desc, self.name, len(self.args), expected_str))
1742 def signature_has_nongeneric_args(self):
1743 argcount = len(self.args)
1744 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1748 def signature_has_generic_args(self):
1749 return self.entry.signature.has_generic_args
1751 def declare_pyfunction(self, env):
1752 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1754 entry = env.lookup_here(self.name)
1755 if entry and entry.type.is_cfunction and not self.is_wrapper:
1756 warning(self.pos, "Overriding cdef method with def method.", 5)
1757 entry = env.declare_pyfunction(self.name, self.pos)
1759 prefix = env.scope_prefix
1760 entry.func_cname = \
1761 Naming.pyfunc_prefix + prefix + name
1762 entry.pymethdef_cname = \
1763 Naming.pymethdef_prefix + prefix + name
1764 if Options.docstrings:
1765 entry.doc = embed_position(self.pos, self.doc)
1767 Naming.funcdoc_prefix + prefix + name
1771 def declare_arguments(self, env):
1772 for arg in self.args:
1774 error(arg.pos, "Missing argument name")
1775 if arg.needs_conversion:
1776 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1777 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1778 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1779 if arg.type.is_pyobject:
1780 arg.entry.init = "0"
1781 arg.entry.init_to_none = 0
1783 arg.entry = self.declare_argument(env, arg)
1785 arg.entry.is_self_arg = arg.is_self_arg
1787 if arg.is_self_arg or \
1788 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1789 arg.entry.is_declared_generic = 1
1790 self.declare_python_arg(env, self.star_arg)
1791 self.declare_python_arg(env, self.starstar_arg)
1793 def declare_python_arg(self, env, arg):
1795 entry = env.declare_var(arg.name,
1796 PyrexTypes.py_object_type, arg.pos)
1799 entry.init_to_none = 0
1800 entry.xdecref_cleanup = 1
1802 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1804 def analyse_expressions(self, env):
1805 self.local_scope.directives = env.directives
1806 self.analyse_default_values(env)
1807 if env.is_py_class_scope:
1808 self.synthesize_assignment_node(env)
1810 def synthesize_assignment_node(self, env):
1812 self.assmt = SingleAssignmentNode(self.pos,
1813 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1814 rhs = ExprNodes.UnboundMethodNode(self.pos,
1815 function = ExprNodes.PyCFunctionNode(self.pos,
1816 pymethdef_cname = self.entry.pymethdef_cname)))
1817 self.assmt.analyse_declarations(env)
1818 self.assmt.analyse_expressions(env)
1820 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1822 sig = self.entry.signature
1823 if sig.has_dummy_arg:
1824 arg_code_list.append(
1825 "PyObject *%s" % Naming.self_cname)
1826 for arg in self.args:
1827 if not arg.is_generic:
1829 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1831 arg_code_list.append(
1832 arg.hdr_type.declaration_code(arg.hdr_cname))
1833 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1834 arg_code_list.append("PyObject *unused")
1835 if sig.has_generic_args:
1836 arg_code_list.append(
1837 "PyObject *%s, PyObject *%s"
1838 % (Naming.args_cname, Naming.kwds_cname))
1839 arg_code = ", ".join(arg_code_list)
1840 dc = self.return_type.declaration_code(self.entry.func_cname)
1841 header = "static %s(%s)" % (dc, arg_code)
1842 code.putln("%s; /*proto*/" % header)
1845 if self.entry.doc and Options.docstrings:
1846 docstr = self.entry.doc
1847 if not isinstance(docstr, str):
1848 docstr = docstr.utf8encode()
1850 'static char %s[] = "%s";' % (
1851 self.entry.doc_cname,
1852 split_docstring(escape_byte_string(docstr))))
1855 "static PyMethodDef %s = " %
1856 self.entry.pymethdef_cname)
1857 code.put_pymethoddef(self.entry, ";")
1858 code.putln("%s {" % header)
1860 def generate_argument_declarations(self, env, code):
1861 for arg in self.args:
1862 if arg.is_generic: # or arg.needs_conversion:
1863 if arg.needs_conversion:
1864 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1866 code.put_var_declaration(arg.entry)
1868 def generate_keyword_list(self, code):
1869 if self.signature_has_generic_args() and \
1870 self.signature_has_nongeneric_args():
1872 "static PyObject **%s[] = {" %
1873 Naming.pykwdlist_cname)
1874 for arg in self.args:
1876 pystring_cname = code.intern_identifier(arg.name)
1877 code.put('&%s,' % pystring_cname)
1880 def generate_argument_parsing_code(self, env, code):
1881 # Generate PyArg_ParseTuple call for generic
1882 # arguments, if any.
1883 if self.entry.signature.has_dummy_arg:
1884 # get rid of unused argument warning
1885 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1887 old_error_label = code.new_error_label()
1888 our_error_label = code.error_label
1889 end_label = code.new_label("argument_unpacking_done")
1891 has_kwonly_args = self.num_kwonly_args > 0
1892 has_star_or_kw_args = self.star_arg is not None \
1893 or self.starstar_arg is not None or has_kwonly_args
1895 for arg in self.args:
1896 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1897 arg.type.create_from_py_utility_code(env)
1899 if not self.signature_has_generic_args():
1900 if has_star_or_kw_args:
1901 error(self.pos, "This method cannot have * or keyword arguments")
1902 self.generate_argument_conversion_code(code)
1904 elif not self.signature_has_nongeneric_args():
1905 # func(*args) or func(**kw) or func(*args, **kw)
1906 self.generate_stararg_copy_code(code)
1909 positional_args = []
1912 for arg in self.args:
1913 arg_entry = arg.entry
1917 if not arg.is_self_arg:
1919 kw_only_args.append(arg)
1921 positional_args.append(arg)
1923 kw_only_args.append(arg)
1926 error(arg.pos, "Non-default argument following default argument")
1927 elif not arg.is_self_arg:
1928 positional_args.append(arg)
1930 self.generate_tuple_and_keyword_parsing_code(
1931 positional_args, kw_only_args, end_label, code)
1933 code.error_label = old_error_label
1934 if code.label_used(our_error_label):
1935 if not code.label_used(end_label):
1936 code.put_goto(end_label)
1937 code.put_label(our_error_label)
1938 if has_star_or_kw_args:
1939 self.generate_arg_decref(self.star_arg, code)
1940 if self.starstar_arg:
1941 if self.starstar_arg.entry.xdecref_cleanup:
1942 code.put_var_xdecref(self.starstar_arg.entry)
1944 code.put_var_decref(self.starstar_arg.entry)
1945 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1946 code.putln("return %s;" % self.error_value())
1947 if code.label_used(end_label):
1948 code.put_label(end_label)
1950 def generate_arg_assignment(self, arg, item, code):
1951 if arg.type.is_pyobject:
1953 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1954 code.putln("%s = %s;" % (arg.entry.cname, item))
1956 func = arg.type.from_py_function
1958 code.putln("%s = %s(%s); %s" % (
1962 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1964 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1966 def generate_arg_xdecref(self, arg, code):
1968 code.put_var_xdecref(arg.entry)
1970 def generate_arg_decref(self, arg, code):
1972 code.put_var_decref(arg.entry)
1974 def generate_stararg_copy_code(self, code):
1975 if not self.star_arg:
1976 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1977 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1979 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1980 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1983 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1985 if self.starstar_arg:
1987 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1989 kwarg_check = "%s" % Naming.kwds_cname
1991 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1992 Naming.kwds_cname, Naming.kwds_cname)
1994 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1995 kwarg_check, Naming.kwds_cname, self.name,
1996 bool(self.starstar_arg), self.error_value()))
1998 if self.starstar_arg:
1999 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2000 self.starstar_arg.entry.cname,
2003 code.putln("if (unlikely(!%s)) return %s;" % (
2004 self.starstar_arg.entry.cname, self.error_value()))
2005 self.starstar_arg.entry.xdecref_cleanup = 0
2006 code.put_gotref(self.starstar_arg.entry.cname)
2010 code.put_incref(Naming.args_cname, py_object_type)
2011 code.putln("%s = %s;" % (
2012 self.star_arg.entry.cname,
2014 self.star_arg.entry.xdecref_cleanup = 0
2016 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2017 kw_only_args, success_label, code):
2018 argtuple_error_label = code.new_label("argtuple_error")
2020 min_positional_args = self.num_required_args - self.num_required_kw_args
2021 if len(self.args) > 0 and self.args[0].is_self_arg:
2022 min_positional_args -= 1
2023 max_positional_args = len(positional_args)
2024 has_fixed_positional_count = not self.star_arg and \
2025 min_positional_args == max_positional_args
2027 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2028 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2029 if self.num_required_kw_args:
2030 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2032 if self.starstar_arg or self.star_arg:
2033 self.generate_stararg_init_code(max_positional_args, code)
2035 # --- optimised code when we receive keyword arguments
2036 if self.num_required_kw_args:
2037 likely_hint = "likely"
2039 likely_hint = "unlikely"
2040 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2041 self.generate_keyword_unpacking_code(
2042 min_positional_args, max_positional_args,
2043 has_fixed_positional_count,
2044 positional_args, kw_only_args, argtuple_error_label, code)
2046 # --- optimised code when we do not receive any keyword arguments
2047 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2048 # Python raises arg tuple related errors first, so we must
2049 # check the length here
2050 if min_positional_args == max_positional_args and not self.star_arg:
2054 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2055 Naming.args_cname, compare, min_positional_args))
2056 code.put_goto(argtuple_error_label)
2058 if self.num_required_kw_args:
2059 # pure error case: keywords required but not passed
2060 if max_positional_args > min_positional_args and not self.star_arg:
2061 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2062 Naming.args_cname, max_positional_args))
2063 code.put_goto(argtuple_error_label)
2064 code.putln('} else {')
2065 for i, arg in enumerate(kw_only_args):
2067 pystring_cname = code.intern_identifier(arg.name)
2068 # required keyword-only argument missing
2069 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2070 self.name.utf8encode(),
2072 code.putln(code.error_goto(self.pos))
2075 elif min_positional_args == max_positional_args:
2076 # parse the exact number of positional arguments from the
2078 code.putln('} else {')
2079 for i, arg in enumerate(positional_args):
2080 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2081 self.generate_arg_assignment(arg, item, code)
2082 self.generate_arg_default_assignments(code)
2085 # parse the positional arguments from the variable length
2087 code.putln('} else {')
2088 self.generate_arg_default_assignments(code)
2089 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2091 code.putln('default:')
2092 reversed_args = list(enumerate(positional_args))[::-1]
2093 for i, arg in reversed_args:
2094 if i >= min_positional_args-1:
2095 if min_positional_args > 1:
2096 code.putln('case %2d:' % (i+1)) # pure code beautification
2098 code.put('case %2d: ' % (i+1))
2099 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2100 self.generate_arg_assignment(arg, item, code)
2101 if min_positional_args == 0:
2102 code.put('case 0: ')
2103 code.putln('break;')
2105 if min_positional_args:
2106 for i in range(min_positional_args-1, -1, -1):
2107 code.putln('case %2d:' % i)
2108 code.put_goto(argtuple_error_label)
2110 code.put('default: ')
2111 code.put_goto(argtuple_error_label)
2116 if code.label_used(argtuple_error_label):
2117 code.put_goto(success_label)
2118 code.put_label(argtuple_error_label)
2119 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2120 self.name.utf8encode(), has_fixed_positional_count,
2121 min_positional_args, max_positional_args,
2123 code.putln(code.error_goto(self.pos))
2125 def generate_arg_default_assignments(self, code):
2126 for arg in self.args:
2127 if arg.is_generic and arg.default:
2131 arg.calculate_default_value_code(code)))
2133 def generate_stararg_init_code(self, max_positional_args, code):
2134 if self.starstar_arg:
2135 self.starstar_arg.entry.xdecref_cleanup = 0
2136 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2137 self.starstar_arg.entry.cname,
2138 self.starstar_arg.entry.cname,
2139 self.error_value()))
2140 code.put_gotref(self.starstar_arg.entry.cname)
2142 self.star_arg.entry.xdecref_cleanup = 0
2143 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2145 max_positional_args))
2146 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2147 self.star_arg.entry.cname, Naming.args_cname,
2148 max_positional_args, Naming.args_cname))
2149 code.put_gotref(self.star_arg.entry.cname)
2150 if self.starstar_arg:
2152 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2153 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2154 code.putln('return %s;' % self.error_value())
2157 code.putln("if (unlikely(!%s)) return %s;" % (
2158 self.star_arg.entry.cname, self.error_value()))
2159 code.putln('} else {')
2160 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2161 code.put_incref(Naming.empty_tuple, py_object_type)
2164 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2165 has_fixed_positional_count, positional_args,
2166 kw_only_args, argtuple_error_label, code):
2167 all_args = tuple(positional_args) + tuple(kw_only_args)
2168 max_args = len(all_args)
2171 for i, arg in enumerate(all_args):
2172 if arg.default and arg.type.is_pyobject:
2173 default_value = arg.calculate_default_value_code(code)
2174 if arg.type is not PyrexTypes.py_object_type:
2175 default_value = "(PyObject*)"+default_value
2176 default_args.append((i, default_value))
2178 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2180 # it looks funny to separate the init-to-0 from setting the
2181 # default value, but C89 needs this
2182 code.putln("PyObject* values[%d] = {%s};" % (
2183 max_args, ','.join(['0']*max_args)))
2184 for i, default_value in default_args:
2185 code.putln('values[%d] = %s;' % (i, default_value))
2187 # parse the tuple and check that it's not too long
2188 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2190 code.putln('default:')
2191 for i in range(max_positional_args-1, -1, -1):
2192 code.put('case %2d: ' % (i+1))
2193 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2194 i, Naming.args_cname, i))
2195 code.putln('case 0: break;')
2196 if not self.star_arg:
2197 code.put('default: ') # more arguments than allowed
2198 code.put_goto(argtuple_error_label)
2201 # now fill up the positional/required arguments with values
2203 if self.num_required_args or max_positional_args > 0:
2204 last_required_arg = -1
2205 for i, arg in enumerate(all_args):
2207 last_required_arg = i
2208 if last_required_arg < max_positional_args:
2209 last_required_arg = max_positional_args-1
2210 num_required_args = self.num_required_args
2211 if max_positional_args > 0:
2212 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2213 for i, arg in enumerate(all_args[:last_required_arg+1]):
2214 if max_positional_args > 0 and i <= max_positional_args:
2215 if self.star_arg and i == max_positional_args:
2216 code.putln('default:')
2218 code.putln('case %2d:' % i)
2219 pystring_cname = code.intern_identifier(arg.name)
2222 # handled separately below
2224 code.putln('if (kw_args > %d) {' % num_required_args)
2225 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2226 Naming.kwds_cname, pystring_cname))
2227 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2230 num_required_args -= 1
2231 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2232 i, Naming.kwds_cname, pystring_cname))
2233 code.putln('if (likely(values[%d])) kw_args--;' % i);
2234 if i < min_positional_args:
2236 # special case: we know arg 0 is missing
2238 code.put_goto(argtuple_error_label)
2240 # print the correct number of values (args or
2241 # kwargs) that were passed into positional
2242 # arguments up to this point
2243 code.putln('else {')
2244 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2245 self.name.utf8encode(), has_fixed_positional_count,
2246 min_positional_args, max_positional_args, i))
2247 code.putln(code.error_goto(self.pos))
2250 code.putln('else {')
2251 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2252 self.name.utf8encode(), pystring_cname))
2253 code.putln(code.error_goto(self.pos))
2255 if max_positional_args > 0:
2258 if kw_only_args and not self.starstar_arg:
2259 # unpack optional keyword-only arguments
2260 # checking for interned strings in a dict is faster than iterating
2261 # but it's too likely that we must iterate if we expect **kwargs
2263 for i, arg in enumerate(all_args[max_positional_args:]):
2264 if not arg.kw_only or not arg.default:
2266 optional_args.append((i+max_positional_args, arg))
2268 # this mimics an unrolled loop so that we can "break" out of it
2269 code.putln('while (kw_args > 0) {')
2270 code.putln('PyObject* value;')
2271 for i, arg in optional_args:
2272 pystring_cname = code.intern_identifier(arg.name)
2274 'value = PyDict_GetItem(%s, %s);' % (
2275 Naming.kwds_cname, pystring_cname))
2277 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2278 code.putln('break;')
2281 code.putln('if (unlikely(kw_args > 0)) {')
2282 # non-positional/-required kw args left in dict: default args,
2283 # kw-only args, **kwargs or error
2285 # This is sort of a catch-all: except for checking required
2286 # arguments, this will always do the right thing for unpacking
2287 # keyword arguments, so that we can concentrate on optimising
2288 # common cases above.
2289 if max_positional_args == 0:
2292 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2293 Naming.args_cname, max_positional_args,
2294 Naming.args_cname, max_positional_args))
2295 pos_arg_count = "used_pos_args"
2297 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2298 code.globalstate.use_utility_code(parse_keywords_utility_code)
2300 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2302 Naming.pykwdlist_cname,
2303 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2305 self.name.utf8encode()))
2306 code.putln(code.error_goto(self.pos))
2309 # convert arg values to their final type and assign them
2310 for i, arg in enumerate(all_args):
2311 if arg.default and not arg.type.is_pyobject:
2312 code.putln("if (values[%d]) {" % i)
2313 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2314 if arg.default and not arg.type.is_pyobject:
2315 code.putln('} else {')
2319 arg.calculate_default_value_code(code)))
2322 def generate_argument_conversion_code(self, code):
2323 # Generate code to convert arguments from
2324 # signature type to declared type, if needed.
2325 for arg in self.args:
2326 if arg.needs_conversion:
2327 self.generate_arg_conversion(arg, code)
2329 def generate_arg_conversion(self, arg, code):
2330 # Generate conversion code for one argument.
2331 old_type = arg.hdr_type
2333 if old_type.is_pyobject:
2335 code.putln("if (%s) {" % arg.hdr_cname)
2337 code.putln("assert(%s); {" % arg.hdr_cname)
2338 self.generate_arg_conversion_from_pyobject(arg, code)
2340 elif new_type.is_pyobject:
2341 self.generate_arg_conversion_to_pyobject(arg, code)
2343 if new_type.assignable_from(old_type):
2345 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2348 "Cannot convert 1 argument from '%s' to '%s'" %
2349 (old_type, new_type))
2351 def generate_arg_conversion_from_pyobject(self, arg, code):
2353 func = new_type.from_py_function
2354 # copied from CoerceFromPyTypeNode
2356 code.putln("%s = %s(%s); %s" % (
2360 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2363 "Cannot convert Python object argument to type '%s'"
2366 def generate_arg_conversion_to_pyobject(self, arg, code):
2367 old_type = arg.hdr_type
2368 func = old_type.to_py_function
2370 code.putln("%s = %s(%s); %s" % (
2374 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2375 code.put_var_gotref(arg.entry)
2378 "Cannot convert argument of type '%s' to Python object"
2381 def generate_argument_type_tests(self, code):
2382 # Generate type tests for args whose signature
2383 # type is PyObject * and whose declared type is
2384 # a subtype thereof.
2385 for arg in self.args:
2386 if arg.needs_type_test:
2387 self.generate_arg_type_test(arg, code)
2389 def generate_arg_type_test(self, arg, code):
2390 # Generate type test for one argument.
2391 if arg.type.typeobj_is_available():
2392 typeptr_cname = arg.type.typeptr_cname
2393 arg_code = "((PyObject *)%s)" % arg.entry.cname
2395 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2400 arg.type.is_builtin_type,
2401 code.error_goto(arg.pos)))
2403 error(arg.pos, "Cannot test type of extern C class "
2404 "without type object name specification")
2406 def error_value(self):
2407 return self.entry.signature.error_value
2409 def caller_will_check_exceptions(self):
2412 class OverrideCheckNode(StatNode):
2413 # A Node for dispatching to the def method if it
2422 child_attrs = ['body']
2426 def analyse_expressions(self, env):
2427 self.args = env.arg_entries
2428 if self.py_func.is_module_scope:
2433 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2434 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2435 call_node = ExprNodes.SimpleCallNode(self.pos,
2436 function=self.func_node,
2437 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2438 self.body = ReturnStatNode(self.pos, value=call_node)
2439 self.body.analyse_expressions(env)
2441 def generate_execution_code(self, code):
2442 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2443 # Check to see if we are an extension type
2444 if self.py_func.is_module_scope:
2445 self_arg = "((PyObject *)%s)" % Naming.module_cname
2447 self_arg = "((PyObject *)%s)" % self.args[0].cname
2448 code.putln("/* Check if called by wrapper */")
2449 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2450 code.putln("/* Check if overriden in Python */")
2451 if self.py_func.is_module_scope:
2452 code.putln("else {")
2454 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2455 self.func_node.allocate(code)
2456 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2457 # need to get attribute manually--scope would return cdef method
2458 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2459 self.func_node.result(), self_arg, interned_attr_cname, err))
2460 code.put_gotref(self.func_node.py_result())
2461 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2462 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2463 self.func_node.result(), self.py_func.entry.func_cname)
2464 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2465 self.body.generate_execution_code(code)
2467 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2469 self.func_node.release(code)
2471 class ClassDefNode(StatNode, BlockNode):
2474 class PyClassDefNode(ClassDefNode):
2475 # A Python class definition.
2477 # name EncodedString Name of the class
2478 # doc string or None
2479 # body StatNode Attribute definition code
2480 # entry Symtab.Entry
2481 # scope PyClassScope
2482 # decorators [DecoratorNode] list of decorators or None
2484 # The following subnodes are constructed internally:
2486 # dict DictNode Class dictionary
2487 # classobj ClassNode Class object
2488 # target NameNode Variable to assign class object to
2490 child_attrs = ["body", "dict", "classobj", "target"]
2493 def __init__(self, pos, name, bases, doc, body, decorators = None):
2494 StatNode.__init__(self, pos)
2498 self.decorators = decorators
2500 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2501 if self.doc and Options.docstrings:
2502 doc = embed_position(self.pos, self.doc)
2503 doc_node = ExprNodes.StringNode(pos, value = doc)
2506 self.classobj = ExprNodes.ClassNode(pos, name = name,
2507 bases = bases, dict = self.dict, doc = doc_node)
2508 self.target = ExprNodes.NameNode(pos, name = name)
2510 def as_cclass(self):
2512 Return this node as if it were declared as an extension class
2514 bases = self.classobj.bases.args
2516 base_class_name = None
2517 base_class_module = None
2518 elif len(bases) == 1:
2521 from ExprNodes import AttributeNode, NameNode
2522 while isinstance(base, AttributeNode):
2523 path.insert(0, base.attribute)
2525 if isinstance(base, NameNode):
2526 path.insert(0, base.name)
2527 base_class_name = path[-1]
2529 base_class_module = u'.'.join(path[:-1])
2531 base_class_module = None
2533 error(self.classobj.bases.args.pos, "Invalid base class")
2535 error(self.classobj.bases.args.pos, "C class may only have one base class")
2538 return CClassDefNode(self.pos,
2539 visibility = 'private',
2541 class_name = self.name,
2542 base_class_module = base_class_module,
2543 base_class_name = base_class_name,
2544 decorators = self.decorators,
2549 def create_scope(self, env):
2551 while env.is_py_class_scope or env.is_c_class_scope:
2552 env = env.outer_scope
2553 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2556 def analyse_declarations(self, env):
2557 self.target.analyse_target_declaration(env)
2558 cenv = self.create_scope(env)
2559 cenv.directives = env.directives
2560 cenv.class_obj_cname = self.target.entry.cname
2561 self.body.analyse_declarations(cenv)
2563 def analyse_expressions(self, env):
2564 self.dict.analyse_expressions(env)
2565 self.classobj.analyse_expressions(env)
2566 genv = env.global_scope()
2568 self.body.analyse_expressions(cenv)
2569 self.target.analyse_target_expression(env, self.classobj)
2571 def generate_function_definitions(self, env, code):
2572 self.body.generate_function_definitions(self.scope, code)
2574 def generate_execution_code(self, code):
2575 code.pyclass_stack.append(self)
2577 self.dict.generate_evaluation_code(code)
2578 self.classobj.generate_evaluation_code(code)
2579 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2580 self.body.generate_execution_code(code)
2581 self.target.generate_assignment_code(self.classobj, code)
2582 self.dict.generate_disposal_code(code)
2583 self.dict.free_temps(code)
2584 code.pyclass_stack.pop()
2587 class CClassDefNode(ClassDefNode):
2588 # An extension type definition.
2590 # visibility 'private' or 'public' or 'extern'
2591 # typedef_flag boolean
2593 # module_name string or None For import of extern type objects
2594 # class_name string Unqualified name of class
2595 # as_name string or None Name to declare as in this scope
2596 # base_class_module string or None Module containing the base class
2597 # base_class_name string or None Name of the base class
2598 # objstruct_name string or None Specified C name of object struct
2599 # typeobj_name string or None Specified C name of type object
2600 # in_pxd boolean Is in a .pxd file
2601 # decorators [DecoratorNode] list of decorators or None
2602 # doc string or None
2603 # body StatNode or None
2604 # entry Symtab.Entry
2605 # base_type PyExtensionType or None
2606 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2607 # buffer_defaults_pos
2609 child_attrs = ["body"]
2610 buffer_defaults_node = None
2611 buffer_defaults_pos = None
2612 typedef_flag = False
2614 objstruct_name = None
2618 def analyse_declarations(self, env):
2619 #print "CClassDefNode.analyse_declarations:", self.class_name
2620 #print "...visibility =", self.visibility
2621 #print "...module_name =", self.module_name
2624 if self.buffer_defaults_node:
2625 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2626 env, [], self.buffer_defaults_node,
2627 need_complete=False)
2629 buffer_defaults = None
2631 if env.in_cinclude and not self.objstruct_name:
2632 error(self.pos, "Object struct name specification required for "
2633 "C class defined in 'extern from' block")
2634 self.base_type = None
2635 # Now that module imports are cached, we need to
2636 # import the modules for extern classes.
2637 if self.module_name:
2639 for module in env.cimported_modules:
2640 if module.name == self.module_name:
2641 self.module = module
2642 if self.module is None:
2643 self.module = ModuleScope(self.module_name, None, env.context)
2644 self.module.has_extern_class = 1
2645 env.add_imported_module(self.module)
2647 if self.base_class_name:
2648 if self.base_class_module:
2649 base_class_scope = env.find_module(self.base_class_module, self.pos)
2651 base_class_scope = env
2652 if self.base_class_name == 'object':
2653 # extension classes are special and don't need to inherit from object
2654 if base_class_scope is None or base_class_scope.lookup('object') is None:
2655 self.base_class_name = None
2656 self.base_class_module = None
2657 base_class_scope = None
2658 if base_class_scope:
2659 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2660 if base_class_entry:
2661 if not base_class_entry.is_type:
2662 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2663 elif not base_class_entry.type.is_extension_type:
2664 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2665 elif not base_class_entry.type.is_complete():
2666 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2668 self.base_type = base_class_entry.type
2669 has_body = self.body is not None
2670 if self.module_name and self.visibility != 'extern':
2671 module_path = self.module_name.split(".")
2672 home_scope = env.find_imported_module(module_path, self.pos)
2678 if self.visibility == 'extern':
2679 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2680 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2682 self.entry = home_scope.declare_c_class(
2683 name = self.class_name,
2685 defining = has_body and self.in_pxd,
2686 implementing = has_body and not self.in_pxd,
2687 module_name = self.module_name,
2688 base_type = self.base_type,
2689 objstruct_cname = self.objstruct_name,
2690 typeobj_cname = self.typeobj_name,
2691 visibility = self.visibility,
2692 typedef_flag = self.typedef_flag,
2694 buffer_defaults = buffer_defaults)
2695 if home_scope is not env and self.visibility == 'extern':
2696 env.add_imported_entry(self.class_name, self.entry, pos)
2697 scope = self.entry.type.scope
2698 if scope is not None:
2699 scope.directives = env.directives
2701 if self.doc and Options.docstrings:
2702 scope.doc = embed_position(self.pos, self.doc)
2705 self.body.analyse_declarations(scope)
2709 scope.implemented = 1
2710 env.allocate_vtable_names(self.entry)
2712 def analyse_expressions(self, env):
2714 scope = self.entry.type.scope
2715 self.body.analyse_expressions(scope)
2717 def generate_function_definitions(self, env, code):
2719 self.body.generate_function_definitions(
2720 self.entry.type.scope, code)
2722 def generate_execution_code(self, code):
2723 # This is needed to generate evaluation code for
2724 # default values of method arguments.
2726 self.body.generate_execution_code(code)
2728 def annotate(self, code):
2730 self.body.annotate(code)
2733 class PropertyNode(StatNode):
2734 # Definition of a property in an extension type.
2737 # doc EncodedString or None Doc string
2740 child_attrs = ["body"]
2742 def analyse_declarations(self, env):
2743 entry = env.declare_property(self.name, self.doc, self.pos)
2745 entry.scope.directives = env.directives
2746 self.body.analyse_declarations(entry.scope)
2748 def analyse_expressions(self, env):
2749 self.body.analyse_expressions(env)
2751 def generate_function_definitions(self, env, code):
2752 self.body.generate_function_definitions(env, code)
2754 def generate_execution_code(self, code):
2757 def annotate(self, code):
2758 self.body.annotate(code)
2761 class GlobalNode(StatNode):
2762 # Global variable declaration.
2768 def analyse_declarations(self, env):
2769 for name in self.names:
2770 env.declare_global(name, self.pos)
2772 def analyse_expressions(self, env):
2775 def generate_execution_code(self, code):
2779 class ExprStatNode(StatNode):
2780 # Expression used as a statement.
2784 child_attrs = ["expr"]
2786 def analyse_declarations(self, env):
2788 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2789 func = self.expr.function.as_cython_attribute()
2790 if func == u'declare':
2791 args, kwds = self.expr.explicit_args_kwds()
2793 error(self.expr.pos, "Variable names must be specified.")
2794 for var, type_node in kwds.key_value_pairs:
2795 type = type_node.analyse_as_type(env)
2797 error(type_node.pos, "Unknown type")
2799 env.declare_var(var.value, type, var.pos, is_cdef = True)
2800 self.__class__ = PassStatNode
2802 def analyse_expressions(self, env):
2803 self.expr.analyse_expressions(env)
2805 def generate_execution_code(self, code):
2806 self.expr.generate_evaluation_code(code)
2807 if not self.expr.is_temp and self.expr.result():
2808 code.putln("%s;" % self.expr.result())
2809 self.expr.generate_disposal_code(code)
2810 self.expr.free_temps(code)
2812 def annotate(self, code):
2813 self.expr.annotate(code)
2816 class AssignmentNode(StatNode):
2817 # Abstract base class for assignment nodes.
2819 # The analyse_expressions and generate_execution_code
2820 # phases of assignments are split into two sub-phases
2821 # each, to enable all the right hand sides of a
2822 # parallel assignment to be evaluated before assigning
2823 # to any of the left hand sides.
2825 def analyse_expressions(self, env):
2826 self.analyse_types(env)
2828 # def analyse_expressions(self, env):
2829 # self.analyse_expressions_1(env)
2830 # self.analyse_expressions_2(env)
2832 def generate_execution_code(self, code):
2833 self.generate_rhs_evaluation_code(code)
2834 self.generate_assignment_code(code)
2837 class SingleAssignmentNode(AssignmentNode):
2838 # The simplest case:
2842 # lhs ExprNode Left hand side
2843 # rhs ExprNode Right hand side
2844 # first bool Is this guaranteed the first assignment to lhs?
2846 child_attrs = ["lhs", "rhs"]
2848 declaration_only = False
2850 def analyse_declarations(self, env):
2853 # handle declarations of the form x = cython.foo()
2854 if isinstance(self.rhs, ExprNodes.CallNode):
2855 func_name = self.rhs.function.as_cython_attribute()
2857 args, kwds = self.rhs.explicit_args_kwds()
2859 if func_name in ['declare', 'typedef']:
2860 if len(args) > 2 or kwds is not None:
2861 error(rhs.pos, "Can only declare one type at a time.")
2863 type = args[0].analyse_as_type(env)
2865 error(args[0].pos, "Unknown type")
2868 if func_name == 'declare':
2869 if isinstance(lhs, ExprNodes.NameNode):
2870 vars = [(lhs.name, lhs.pos)]
2871 elif isinstance(lhs, ExprNodes.TupleNode):
2872 vars = [(var.name, var.pos) for var in lhs.args]
2874 error(lhs.pos, "Invalid declaration")
2876 for var, pos in vars:
2877 env.declare_var(var, type, pos, is_cdef = True)
2882 self.declaration_only = True
2884 self.declaration_only = True
2885 if not isinstance(lhs, ExprNodes.NameNode):
2886 error(lhs.pos, "Invalid declaration.")
2887 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2889 elif func_name in ['struct', 'union']:
2890 self.declaration_only = True
2891 if len(args) > 0 or kwds is None:
2892 error(rhs.pos, "Struct or union members must be given by name.")
2895 for member, type_node in kwds.key_value_pairs:
2896 type = type_node.analyse_as_type(env)
2898 error(type_node.pos, "Unknown type")
2900 members.append((member.value, type, member.pos))
2901 if len(members) < len(kwds.key_value_pairs):
2903 if not isinstance(self.lhs, ExprNodes.NameNode):
2904 error(self.lhs.pos, "Invalid declaration.")
2905 name = self.lhs.name
2906 scope = StructOrUnionScope(name)
2907 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2908 for member, type, pos in members:
2909 scope.declare_var(member, type, pos)
2911 if self.declaration_only:
2914 self.lhs.analyse_target_declaration(env)
2916 def analyse_types(self, env, use_temp = 0):
2917 self.rhs.analyse_types(env)
2918 self.lhs.analyse_target_types(env)
2919 self.lhs.gil_assignment_check(env)
2920 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2922 self.rhs = self.rhs.coerce_to_temp(env)
2924 def generate_rhs_evaluation_code(self, code):
2925 self.rhs.generate_evaluation_code(code)
2927 def generate_assignment_code(self, code):
2928 self.lhs.generate_assignment_code(self.rhs, code)
2930 def annotate(self, code):
2931 self.lhs.annotate(code)
2932 self.rhs.annotate(code)
2935 class CascadedAssignmentNode(AssignmentNode):
2936 # An assignment with multiple left hand sides:
2940 # lhs_list [ExprNode] Left hand sides
2941 # rhs ExprNode Right hand sides
2945 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2947 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2948 coerced_rhs_list = None
2950 def analyse_declarations(self, env):
2951 for lhs in self.lhs_list:
2952 lhs.analyse_target_declaration(env)
2954 def analyse_types(self, env, use_temp = 0):
2955 self.rhs.analyse_types(env)
2957 self.rhs = self.rhs.coerce_to_temp(env)
2959 self.rhs = self.rhs.coerce_to_simple(env)
2960 from ExprNodes import CloneNode
2961 self.coerced_rhs_list = []
2962 for lhs in self.lhs_list:
2963 lhs.analyse_target_types(env)
2964 lhs.gil_assignment_check(env)
2965 rhs = CloneNode(self.rhs)
2966 rhs = rhs.coerce_to(lhs.type, env)
2967 self.coerced_rhs_list.append(rhs)
2969 def generate_rhs_evaluation_code(self, code):
2970 self.rhs.generate_evaluation_code(code)
2972 def generate_assignment_code(self, code):
2973 for i in range(len(self.lhs_list)):
2974 lhs = self.lhs_list[i]
2975 rhs = self.coerced_rhs_list[i]
2976 rhs.generate_evaluation_code(code)
2977 lhs.generate_assignment_code(rhs, code)
2978 # Assignment has disposed of the cloned RHS
2979 self.rhs.generate_disposal_code(code)
2980 self.rhs.free_temps(code)
2982 def annotate(self, code):
2983 for i in range(len(self.lhs_list)):
2984 lhs = self.lhs_list[i].annotate(code)
2985 rhs = self.coerced_rhs_list[i].annotate(code)
2986 self.rhs.annotate(code)
2989 class ParallelAssignmentNode(AssignmentNode):
2990 # A combined packing/unpacking assignment:
2994 # This has been rearranged by the parser into
2996 # a = d ; b = e ; c = f
2998 # but we must evaluate all the right hand sides
2999 # before assigning to any of the left hand sides.
3001 # stats [AssignmentNode] The constituent assignments
3003 child_attrs = ["stats"]
3005 def analyse_declarations(self, env):
3006 for stat in self.stats:
3007 stat.analyse_declarations(env)
3009 def analyse_expressions(self, env):
3010 for stat in self.stats:
3011 stat.analyse_types(env, use_temp = 1)
3013 # def analyse_expressions(self, env):
3014 # for stat in self.stats:
3015 # stat.analyse_expressions_1(env, use_temp = 1)
3016 # for stat in self.stats:
3017 # stat.analyse_expressions_2(env)
3019 def generate_execution_code(self, code):
3020 for stat in self.stats:
3021 stat.generate_rhs_evaluation_code(code)
3022 for stat in self.stats:
3023 stat.generate_assignment_code(code)
3025 def annotate(self, code):
3026 for stat in self.stats:
3030 class InPlaceAssignmentNode(AssignmentNode):
3031 # An in place arithmatic operand:
3037 # lhs ExprNode Left hand side
3038 # rhs ExprNode Right hand side
3039 # op char one of "+-*/%^&|"
3040 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3042 # This code is a bit tricky because in order to obey Python
3043 # semantics the sub-expressions (e.g. indices) of the lhs must
3044 # not be evaluated twice. So we must re-use the values calculated
3045 # in evaluation phase for the assignment phase as well.
3046 # Fortunately, the type of the lhs node is fairly constrained
3047 # (it must be a NameNode, AttributeNode, or IndexNode).
3049 child_attrs = ["lhs", "rhs"]
3052 def analyse_declarations(self, env):
3053 self.lhs.analyse_target_declaration(env)
3055 def analyse_types(self, env):
3056 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3057 self.rhs.analyse_types(env)
3058 self.lhs.analyse_target_types(env)
3059 if Options.incref_local_binop and self.dup.type.is_pyobject:
3060 self.dup = self.dup.coerce_to_temp(env)
3062 if self.lhs.type.is_pyobject:
3063 self.rhs = self.rhs.coerce_to_pyobject(env)
3064 elif self.rhs.type.is_pyobject:
3065 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3066 if self.lhs.type.is_pyobject:
3067 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3068 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3070 def generate_execution_code(self, code):
3072 self.rhs.generate_evaluation_code(code)
3073 self.dup.generate_subexpr_evaluation_code(code)
3074 if self.dup.is_temp:
3075 self.dup.allocate_temp_result(code)
3076 # self.dup.generate_result_code is run only if it is not buffer access
3077 if self.operator == "**":
3081 if self.lhs.type.is_pyobject:
3082 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3083 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3084 self.dup.generate_result_code(code)
3085 self.result_value_temp.allocate(code)
3087 "%s = %s(%s, %s%s); %s" % (
3088 self.result_value.result(),
3089 self.py_operation_function(),
3090 self.dup.py_result(),
3091 self.rhs.py_result(),
3093 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3094 code.put_gotref(self.result_value.py_result())
3095 self.result_value.generate_evaluation_code(code) # May be a type check...
3096 self.rhs.generate_disposal_code(code)
3097 self.rhs.free_temps(code)
3098 self.dup.generate_disposal_code(code)
3099 self.dup.free_temps(code)
3100 self.lhs.generate_assignment_code(self.result_value, code)
3101 self.result_value_temp.release(code)
3103 c_op = self.operator
3107 error(self.pos, "No C inplace power operator")
3108 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3109 error(self.pos, "Inplace operators not implemented for complex types.")
3111 # have to do assignment directly to avoid side-effects
3112 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3113 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3115 self.dup.generate_result_code(code)
3116 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3117 self.rhs.generate_disposal_code(code)
3118 self.rhs.free_temps(code)
3119 if self.dup.is_temp:
3120 self.dup.generate_subexpr_disposal_code(code)
3121 self.dup.free_subexpr_temps(code)
3123 def create_dup_node(self, env):
3126 self.dup.analyse_types(env)
3127 if isinstance(self.lhs, ExprNodes.NameNode):
3128 target_lhs = ExprNodes.NameNode(self.dup.pos,
3129 name = self.dup.name,
3130 is_temp = self.dup.is_temp,
3131 entry = self.dup.entry)
3132 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3133 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3134 obj = ExprNodes.CloneNode(self.lhs.obj),
3135 attribute = self.dup.attribute,
3136 is_temp = self.dup.is_temp)
3137 elif isinstance(self.lhs, ExprNodes.IndexNode):
3139 index = ExprNodes.CloneNode(self.lhs.index)
3142 if self.lhs.indices:
3143 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3146 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3147 base = ExprNodes.CloneNode(self.dup.base),
3150 is_temp = self.dup.is_temp)
3153 self.lhs = target_lhs
3156 def py_operation_function(self):
3157 return self.py_functions[self.operator]
3160 "|": "PyNumber_InPlaceOr",
3161 "^": "PyNumber_InPlaceXor",
3162 "&": "PyNumber_InPlaceAnd",
3163 "+": "PyNumber_InPlaceAdd",
3164 "-": "PyNumber_InPlaceSubtract",
3165 "*": "PyNumber_InPlaceMultiply",
3166 "/": "PyNumber_InPlaceDivide",
3167 "%": "PyNumber_InPlaceRemainder",
3168 "<<": "PyNumber_InPlaceLshift",
3169 ">>": "PyNumber_InPlaceRshift",
3170 "**": "PyNumber_InPlacePower",
3171 "//": "PyNumber_InPlaceFloorDivide",
3174 def annotate(self, code):
3175 self.lhs.annotate(code)
3176 self.rhs.annotate(code)
3177 self.dup.annotate(code)
3180 class PrintStatNode(StatNode):
3183 # arg_tuple TupleNode
3184 # append_newline boolean
3186 child_attrs = ["arg_tuple"]
3188 def analyse_expressions(self, env):
3189 self.arg_tuple.analyse_expressions(env)
3190 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3191 env.use_utility_code(printing_utility_code)
3192 if len(self.arg_tuple.args) == 1 and self.append_newline:
3193 env.use_utility_code(printing_one_utility_code)
3195 gil_check = StatNode._gil_check
3196 gil_message = "Python print statement"
3198 def generate_execution_code(self, code):
3199 if len(self.arg_tuple.args) == 1 and self.append_newline:
3200 arg = self.arg_tuple.args[0]
3201 arg.generate_evaluation_code(code)
3204 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3206 code.error_goto(self.pos)))
3207 arg.generate_disposal_code(code)
3208 arg.free_temps(code)
3210 self.arg_tuple.generate_evaluation_code(code)
3212 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3213 self.arg_tuple.py_result(),
3214 self.append_newline,
3215 code.error_goto(self.pos)))
3216 self.arg_tuple.generate_disposal_code(code)
3217 self.arg_tuple.free_temps(code)
3219 def annotate(self, code):
3220 self.arg_tuple.annotate(code)
3223 class ExecStatNode(StatNode):
3228 child_attrs = ["args"]
3230 def analyse_expressions(self, env):
3231 for i, arg in enumerate(self.args):
3232 arg.analyse_expressions(env)
3233 arg = arg.coerce_to_pyobject(env)
3235 env.use_utility_code(Builtin.pyexec_utility_code)
3237 gil_check = StatNode._gil_check
3238 gil_message = "Python exec statement"
3240 def generate_execution_code(self, code):
3242 for arg in self.args:
3243 arg.generate_evaluation_code(code)
3244 args.append( arg.py_result() )
3245 args = tuple(args + ['0', '0'][:3-len(args)])
3246 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3247 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3248 (temp_result,) + args))
3249 for arg in self.args:
3250 arg.generate_disposal_code(code)
3251 arg.free_temps(code)
3253 code.error_goto_if_null(temp_result, self.pos))
3254 code.put_gotref(temp_result)
3255 code.put_decref_clear(temp_result, py_object_type)
3256 code.funcstate.release_temp(temp_result)
3258 def annotate(self, code):
3259 for arg in self.args:
3263 class DelStatNode(StatNode):
3268 child_attrs = ["args"]
3270 def analyse_declarations(self, env):
3271 for arg in self.args:
3272 arg.analyse_target_declaration(env)
3274 def analyse_expressions(self, env):
3275 for arg in self.args:
3276 arg.analyse_target_expression(env, None)
3277 if not arg.type.is_pyobject:
3278 error(arg.pos, "Deletion of non-Python object")
3279 #arg.release_target_temp(env)
3281 def gil_check(self, env):
3282 for arg in self.args:
3283 if arg.type.is_pyobject:
3284 self._gil_check(env)
3286 gil_message = "Deleting Python object"
3288 def generate_execution_code(self, code):
3289 for arg in self.args:
3290 if arg.type.is_pyobject:
3291 arg.generate_deletion_code(code)
3292 # else error reported earlier
3294 def annotate(self, code):
3295 for arg in self.args:
3299 class PassStatNode(StatNode):
3304 def analyse_expressions(self, env):
3307 def generate_execution_code(self, code):
3311 class BreakStatNode(StatNode):
3315 def analyse_expressions(self, env):
3318 def generate_execution_code(self, code):
3319 if not code.break_label:
3320 error(self.pos, "break statement not inside loop")
3322 code.put_goto(code.break_label)
3325 class ContinueStatNode(StatNode):
3329 def analyse_expressions(self, env):
3332 def generate_execution_code(self, code):
3333 if code.funcstate.in_try_finally:
3334 error(self.pos, "continue statement inside try of try...finally")
3335 elif not code.continue_label:
3336 error(self.pos, "continue statement not inside loop")
3338 code.put_goto(code.continue_label)
3341 class ReturnStatNode(StatNode):
3344 # value ExprNode or None
3345 # return_type PyrexType
3347 child_attrs = ["value"]
3349 def analyse_expressions(self, env):
3350 return_type = env.return_type
3351 self.return_type = return_type
3353 error(self.pos, "Return not inside a function body")
3356 self.value.analyse_types(env)
3357 if return_type.is_void or return_type.is_returncode:
3358 error(self.value.pos,
3359 "Return with value in void function")
3361 self.value = self.value.coerce_to(env.return_type, env)
3363 if (not return_type.is_void
3364 and not return_type.is_pyobject
3365 and not return_type.is_returncode):
3366 error(self.pos, "Return value required")
3368 def gil_check(self, env):
3369 if self.return_type.is_pyobject:
3370 self._gil_check(env)
3372 gil_message = "Returning Python object"
3374 def generate_execution_code(self, code):
3375 code.mark_pos(self.pos)
3376 if not self.return_type:
3377 # error reported earlier
3379 if self.return_type.is_pyobject:
3380 code.put_xdecref(Naming.retval_cname,
3383 self.value.generate_evaluation_code(code)
3384 self.value.make_owned_reference(code)
3387 Naming.retval_cname,
3388 self.value.result_as(self.return_type)))
3389 self.value.generate_post_assignment_code(code)
3390 self.value.free_temps(code)
3392 if self.return_type.is_pyobject:
3393 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3394 elif self.return_type.is_returncode:
3397 Naming.retval_cname,
3398 self.return_type.default_value))
3399 for cname, type in code.funcstate.temps_holding_reference():
3400 code.put_decref_clear(cname, type)
3401 code.put_goto(code.return_label)
3403 def annotate(self, code):
3405 self.value.annotate(code)
3408 class RaiseStatNode(StatNode):
3411 # exc_type ExprNode or None
3412 # exc_value ExprNode or None
3413 # exc_tb ExprNode or None
3415 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3417 def analyse_expressions(self, env):
3419 self.exc_type.analyse_types(env)
3420 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3422 self.exc_value.analyse_types(env)
3423 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3425 self.exc_tb.analyse_types(env)
3426 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3427 env.use_utility_code(raise_utility_code)
3428 env.use_utility_code(restore_exception_utility_code)
3430 gil_check = StatNode._gil_check
3431 gil_message = "Raising exception"
3433 def generate_execution_code(self, code):
3435 self.exc_type.generate_evaluation_code(code)
3436 type_code = self.exc_type.py_result()
3440 self.exc_value.generate_evaluation_code(code)
3441 value_code = self.exc_value.py_result()
3445 self.exc_tb.generate_evaluation_code(code)
3446 tb_code = self.exc_tb.py_result()
3449 if self.exc_type or self.exc_value or self.exc_tb:
3451 "__Pyx_Raise(%s, %s, %s);" % (
3458 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3460 obj.generate_disposal_code(code)
3461 obj.free_temps(code)
3463 code.error_goto(self.pos))
3465 def annotate(self, code):
3467 self.exc_type.annotate(code)
3469 self.exc_value.annotate(code)
3471 self.exc_tb.annotate(code)
3474 class ReraiseStatNode(StatNode):
3478 def analyse_expressions(self, env):
3479 env.use_utility_code(raise_utility_code)
3480 env.use_utility_code(restore_exception_utility_code)
3482 gil_check = StatNode._gil_check
3483 gil_message = "Raising exception"
3485 def generate_execution_code(self, code):
3486 vars = code.funcstate.exc_vars
3488 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3489 code.putln(code.error_goto(self.pos))
3491 error(self.pos, "Reraise not inside except clause")
3494 class AssertStatNode(StatNode):
3498 # value ExprNode or None
3500 child_attrs = ["cond", "value"]
3502 def analyse_expressions(self, env):
3503 self.cond = self.cond.analyse_boolean_expression(env)
3505 self.value.analyse_types(env)
3506 self.value = self.value.coerce_to_pyobject(env)
3508 gil_check = StatNode._gil_check
3509 gil_message = "Raising exception"
3511 def generate_execution_code(self, code):
3512 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3513 self.cond.generate_evaluation_code(code)
3515 "if (unlikely(!%s)) {" %
3518 self.value.generate_evaluation_code(code)
3520 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3521 self.value.py_result())
3522 self.value.generate_disposal_code(code)
3523 self.value.free_temps(code)
3526 "PyErr_SetNone(PyExc_AssertionError);")
3528 code.error_goto(self.pos))
3531 self.cond.generate_disposal_code(code)
3532 self.cond.free_temps(code)
3533 code.putln("#endif")
3535 def annotate(self, code):
3536 self.cond.annotate(code)
3538 self.value.annotate(code)
3541 class IfStatNode(StatNode):
3544 # if_clauses [IfClauseNode]
3545 # else_clause StatNode or None
3547 child_attrs = ["if_clauses", "else_clause"]
3549 def analyse_control_flow(self, env):
3550 env.start_branching(self.pos)
3551 for if_clause in self.if_clauses:
3552 if_clause.analyse_control_flow(env)
3553 env.next_branch(if_clause.end_pos())
3554 if self.else_clause:
3555 self.else_clause.analyse_control_flow(env)
3556 env.finish_branching(self.end_pos())
3558 def analyse_declarations(self, env):
3559 for if_clause in self.if_clauses:
3560 if_clause.analyse_declarations(env)
3561 if self.else_clause:
3562 self.else_clause.analyse_declarations(env)
3564 def analyse_expressions(self, env):
3565 for if_clause in self.if_clauses:
3566 if_clause.analyse_expressions(env)
3567 if self.else_clause:
3568 self.else_clause.analyse_expressions(env)
3570 def generate_execution_code(self, code):
3571 code.mark_pos(self.pos)
3572 end_label = code.new_label()
3573 for if_clause in self.if_clauses:
3574 if_clause.generate_execution_code(code, end_label)
3575 if self.else_clause:
3576 code.putln("/*else*/ {")
3577 self.else_clause.generate_execution_code(code)
3579 code.put_label(end_label)
3581 def annotate(self, code):
3582 for if_clause in self.if_clauses:
3583 if_clause.annotate(code)
3584 if self.else_clause:
3585 self.else_clause.annotate(code)
3588 class IfClauseNode(Node):
3589 # if or elif clause in an if statement
3591 # condition ExprNode
3594 child_attrs = ["condition", "body"]
3596 def analyse_control_flow(self, env):
3597 self.body.analyse_control_flow(env)
3599 def analyse_declarations(self, env):
3600 self.condition.analyse_declarations(env)
3601 self.body.analyse_declarations(env)
3603 def analyse_expressions(self, env):
3605 self.condition.analyse_temp_boolean_expression(env)
3606 self.body.analyse_expressions(env)
3608 def generate_execution_code(self, code, end_label):
3609 self.condition.generate_evaluation_code(code)
3612 self.condition.result())
3613 self.condition.generate_disposal_code(code)
3614 self.condition.free_temps(code)
3615 self.body.generate_execution_code(code)
3619 code.put_goto(end_label)
3622 def annotate(self, code):
3623 self.condition.annotate(code)
3624 self.body.annotate(code)
3627 class SwitchCaseNode(StatNode):
3628 # Generated in the optimization of an if-elif-else node
3630 # conditions [ExprNode]
3633 child_attrs = ['conditions', 'body']
3635 def generate_execution_code(self, code):
3636 for cond in self.conditions:
3637 code.mark_pos(cond.pos)
3638 cond.generate_evaluation_code(code)
3639 code.putln("case %s:" % cond.result())
3640 self.body.generate_execution_code(code)
3641 code.putln("break;")
3643 def annotate(self, code):
3644 for cond in self.conditions:
3646 self.body.annotate(code)
3648 class SwitchStatNode(StatNode):
3649 # Generated in the optimization of an if-elif-else node
3652 # cases [SwitchCaseNode]
3653 # else_clause StatNode or None
3655 child_attrs = ['test', 'cases', 'else_clause']
3657 def generate_execution_code(self, code):
3658 code.putln("switch (%s) {" % self.test.result())
3659 for case in self.cases:
3660 case.generate_execution_code(code)
3661 if self.else_clause is not None:
3662 code.putln("default:")
3663 self.else_clause.generate_execution_code(code)
3664 code.putln("break;")
3667 def annotate(self, code):
3668 self.test.annotate(code)
3669 for case in self.cases:
3671 if self.else_clause is not None:
3672 self.else_clause.annotate(code)
3674 class LoopNode(object):
3676 def analyse_control_flow(self, env):
3677 env.start_branching(self.pos)
3678 self.body.analyse_control_flow(env)
3679 env.next_branch(self.body.end_pos())
3680 if self.else_clause:
3681 self.else_clause.analyse_control_flow(env)
3682 env.finish_branching(self.end_pos())
3685 class WhileStatNode(LoopNode, StatNode):
3688 # condition ExprNode
3690 # else_clause StatNode
3692 child_attrs = ["condition", "body", "else_clause"]
3694 def analyse_declarations(self, env):
3695 self.body.analyse_declarations(env)
3696 if self.else_clause:
3697 self.else_clause.analyse_declarations(env)
3699 def analyse_expressions(self, env):
3701 self.condition.analyse_temp_boolean_expression(env)
3702 self.body.analyse_expressions(env)
3703 if self.else_clause:
3704 self.else_clause.analyse_expressions(env)
3706 def generate_execution_code(self, code):
3707 old_loop_labels = code.new_loop_labels()
3710 self.condition.generate_evaluation_code(code)
3711 self.condition.generate_disposal_code(code)
3714 self.condition.result())
3715 self.condition.free_temps(code)
3716 self.body.generate_execution_code(code)
3717 code.put_label(code.continue_label)
3719 break_label = code.break_label
3720 code.set_loop_labels(old_loop_labels)
3721 if self.else_clause:
3722 code.putln("/*else*/ {")
3723 self.else_clause.generate_execution_code(code)
3725 code.put_label(break_label)
3727 def annotate(self, code):
3728 self.condition.annotate(code)
3729 self.body.annotate(code)
3730 if self.else_clause:
3731 self.else_clause.annotate(code)
3734 def ForStatNode(pos, **kw):
3735 if 'iterator' in kw:
3736 return ForInStatNode(pos, **kw)
3738 return ForFromStatNode(pos, **kw)
3740 class ForInStatNode(LoopNode, StatNode):
3744 # iterator IteratorNode
3746 # else_clause StatNode
3747 # item NextNode used internally
3749 child_attrs = ["target", "iterator", "body", "else_clause"]
3752 def analyse_declarations(self, env):
3753 self.target.analyse_target_declaration(env)
3754 self.body.analyse_declarations(env)
3755 if self.else_clause:
3756 self.else_clause.analyse_declarations(env)
3758 def analyse_expressions(self, env):
3760 self.target.analyse_target_types(env)
3761 self.iterator.analyse_expressions(env)
3762 self.item = ExprNodes.NextNode(self.iterator, env)
3763 self.item = self.item.coerce_to(self.target.type, env)
3764 self.body.analyse_expressions(env)
3765 if self.else_clause:
3766 self.else_clause.analyse_expressions(env)
3768 def generate_execution_code(self, code):
3769 old_loop_labels = code.new_loop_labels()
3770 self.iterator.allocate_counter_temp(code)
3771 self.iterator.generate_evaluation_code(code)
3774 self.item.generate_evaluation_code(code)
3775 self.target.generate_assignment_code(self.item, code)
3776 self.body.generate_execution_code(code)
3777 code.put_label(code.continue_label)
3780 break_label = code.break_label
3781 code.set_loop_labels(old_loop_labels)
3782 if self.else_clause:
3783 code.putln("/*else*/ {")
3784 self.else_clause.generate_execution_code(code)
3786 code.put_label(break_label)
3787 self.iterator.release_counter_temp(code)
3788 self.iterator.generate_disposal_code(code)
3789 self.iterator.free_temps(code)
3791 def annotate(self, code):
3792 self.target.annotate(code)
3793 self.iterator.annotate(code)
3794 self.body.annotate(code)
3795 if self.else_clause:
3796 self.else_clause.annotate(code)
3797 self.item.annotate(code)
3800 class ForFromStatNode(LoopNode, StatNode):
3801 # for name from expr rel name rel expr
3808 # step ExprNode or None
3810 # else_clause StatNode or None
3816 # loopvar_node ExprNode (usually a NameNode or temp node)
3817 # py_loopvar_node PyTempNode or None
3818 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3820 is_py_target = False
3822 py_loopvar_node = None
3825 def analyse_declarations(self, env):
3826 self.target.analyse_target_declaration(env)
3827 self.body.analyse_declarations(env)
3828 if self.else_clause:
3829 self.else_clause.analyse_declarations(env)
3831 def analyse_expressions(self, env):
3833 self.target.analyse_target_types(env)
3834 self.bound1.analyse_types(env)
3835 self.bound2.analyse_types(env)
3836 if self.step is not None:
3837 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3838 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3839 self.step.analyse_types(env)
3841 target_type = self.target.type
3842 if self.target.type.is_numeric:
3843 loop_type = self.target.type
3845 loop_type = PyrexTypes.c_int_type
3846 if not self.bound1.type.is_pyobject:
3847 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3848 if not self.bound2.type.is_pyobject:
3849 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3850 if self.step is not None and not self.step.type.is_pyobject:
3851 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3852 self.bound1 = self.bound1.coerce_to(loop_type, env)
3853 self.bound2 = self.bound2.coerce_to(loop_type, env)
3854 if not self.bound2.is_literal:
3855 self.bound2 = self.bound2.coerce_to_temp(env)
3856 if self.step is not None:
3857 self.step = self.step.coerce_to(loop_type, env)
3858 if not self.step.is_literal:
3859 self.step = self.step.coerce_to_temp(env)
3861 target_type = self.target.type
3862 if not (target_type.is_pyobject or target_type.is_numeric):
3863 error(self.target.pos,
3864 "for-from loop variable must be c numeric type or Python object")
3865 if target_type.is_numeric:
3866 self.is_py_target = False
3867 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3868 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3869 self.loopvar_node = self.target
3870 self.py_loopvar_node = None
3872 self.is_py_target = True
3873 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3874 self.loopvar_node = c_loopvar_node
3875 self.py_loopvar_node = \
3876 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3877 self.body.analyse_expressions(env)
3878 if self.else_clause:
3879 self.else_clause.analyse_expressions(env)
3881 def generate_execution_code(self, code):
3882 old_loop_labels = code.new_loop_labels()
3883 from_range = self.from_range
3884 self.bound1.generate_evaluation_code(code)
3885 self.bound2.generate_evaluation_code(code)
3886 offset, incop = self.relation_table[self.relation1]
3887 if self.step is not None:
3888 self.step.generate_evaluation_code(code)
3889 step = self.step.result()
3890 incop = "%s=%s" % (incop[0], step)
3892 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3893 self.loopvar_node.allocate(code)
3894 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3895 self.py_loopvar_node.allocate(code)
3897 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3899 loopvar_name = self.loopvar_node.result()
3901 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3903 self.bound1.result(), offset,
3904 loopvar_name, self.relation2, self.bound2.result(),
3905 loopvar_name, incop))
3906 if self.py_loopvar_node:
3907 self.py_loopvar_node.generate_evaluation_code(code)
3908 self.target.generate_assignment_code(self.py_loopvar_node, code)
3910 code.putln("%s = %s;" % (
3911 self.target.result(), loopvar_name))
3912 self.body.generate_execution_code(code)
3913 code.put_label(code.continue_label)
3914 if self.py_loopvar_node:
3915 # This mess is to make for..from loops with python targets behave
3916 # exactly like those with C targets with regards to re-assignment
3917 # of the loop variable.
3919 if self.target.entry.is_pyglobal:
3920 # We know target is a NameNode, this is the only ugly case.
3921 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3922 target_node.allocate(code)
3923 interned_cname = code.intern_identifier(self.target.entry.name)
3924 code.putln("/*here*/")
3925 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3926 target_node.result(),
3927 Naming.module_cname,
3929 code.error_goto_if_null(target_node.result(), self.target.pos)))
3930 code.put_gotref(target_node.result())
3932 target_node = self.target
3933 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3934 from_py_node.temp_code = loopvar_name
3935 from_py_node.generate_result_code(code)
3936 if self.target.entry.is_pyglobal:
3937 code.put_decref(target_node.result(), target_node.type)
3938 target_node.release(code)
3940 if self.py_loopvar_node:
3941 # This is potentially wasteful, but we don't want the semantics to
3942 # depend on whether or not the loop is a python type.
3943 self.py_loopvar_node.generate_evaluation_code(code)
3944 self.target.generate_assignment_code(self.py_loopvar_node, code)
3945 break_label = code.break_label
3946 code.set_loop_labels(old_loop_labels)
3947 if self.else_clause:
3948 code.putln("/*else*/ {")
3949 self.else_clause.generate_execution_code(code)
3951 code.put_label(break_label)
3952 self.bound1.generate_disposal_code(code)
3953 self.bound1.free_temps(code)
3954 self.bound2.generate_disposal_code(code)
3955 self.bound2.free_temps(code)
3956 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3957 self.loopvar_node.release(code)
3958 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3959 self.py_loopvar_node.release(code)
3960 if self.step is not None:
3961 self.step.generate_disposal_code(code)
3962 self.step.free_temps(code)
3965 # {relop : (initial offset, increment op)}
3972 def annotate(self, code):
3973 self.target.annotate(code)
3974 self.bound1.annotate(code)
3975 self.bound2.annotate(code)
3977 self.bound2.annotate(code)
3978 self.body.annotate(code)
3979 if self.else_clause:
3980 self.else_clause.annotate(code)
3983 class WithStatNode(StatNode):
3985 Represents a Python with statement.
3987 This is only used at parse tree level; and is not present in
3988 analysis or generation phases.
3990 # manager The with statement manager object
3991 # target Node (lhs expression)
3993 child_attrs = ["manager", "target", "body"]
3995 class TryExceptStatNode(StatNode):
3996 # try .. except statement
3999 # except_clauses [ExceptClauseNode]
4000 # else_clause StatNode or None
4002 child_attrs = ["body", "except_clauses", "else_clause"]
4004 def analyse_control_flow(self, env):
4005 env.start_branching(self.pos)
4006 self.body.analyse_control_flow(env)
4007 successful_try = env.control_flow # grab this for later
4008 env.next_branch(self.body.end_pos())
4009 env.finish_branching(self.body.end_pos())
4011 env.start_branching(self.except_clauses[0].pos)
4012 for except_clause in self.except_clauses:
4013 except_clause.analyse_control_flow(env)
4014 env.next_branch(except_clause.end_pos())
4016 # the else cause it executed only when the try clause finishes
4017 env.control_flow.incoming = successful_try
4018 if self.else_clause:
4019 self.else_clause.analyse_control_flow(env)
4020 env.finish_branching(self.end_pos())
4022 def analyse_declarations(self, env):
4023 self.body.analyse_declarations(env)
4024 for except_clause in self.except_clauses:
4025 except_clause.analyse_declarations(env)
4026 if self.else_clause:
4027 self.else_clause.analyse_declarations(env)
4028 env.use_utility_code(reset_exception_utility_code)
4030 def analyse_expressions(self, env):
4031 self.body.analyse_expressions(env)
4032 default_clause_seen = 0
4033 for except_clause in self.except_clauses:
4034 except_clause.analyse_expressions(env)
4035 if default_clause_seen:
4036 error(except_clause.pos, "default 'except:' must be last")
4037 if not except_clause.pattern:
4038 default_clause_seen = 1
4039 self.has_default_clause = default_clause_seen
4040 if self.else_clause:
4041 self.else_clause.analyse_expressions(env)
4043 gil_check = StatNode._gil_check
4044 gil_message = "Try-except statement"
4046 def generate_execution_code(self, code):
4047 old_return_label = code.return_label
4048 old_break_label = code.break_label
4049 old_continue_label = code.continue_label
4050 old_error_label = code.new_error_label()
4051 our_error_label = code.error_label
4052 except_end_label = code.new_label('exception_handled')
4053 except_error_label = code.new_label('except_error')
4054 except_return_label = code.new_label('except_return')
4055 try_return_label = code.new_label('try_return')
4056 try_break_label = code.new_label('try_break')
4057 try_continue_label = code.new_label('try_continue')
4058 try_end_label = code.new_label('try_end')
4061 code.putln("PyObject %s;" %
4062 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4063 code.putln("__Pyx_ExceptionSave(%s);" %
4064 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4065 for var in Naming.exc_save_vars:
4066 code.put_xgotref(var)
4069 code.return_label = try_return_label
4070 code.break_label = try_break_label
4071 code.continue_label = try_continue_label
4072 self.body.generate_execution_code(code)
4075 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4076 code.error_label = except_error_label
4077 code.return_label = except_return_label
4078 if self.else_clause:
4081 self.else_clause.generate_execution_code(code)
4084 for var in Naming.exc_save_vars:
4085 code.put_xdecref_clear(var, py_object_type)
4086 code.put_goto(try_end_label)
4087 if code.label_used(try_return_label):
4088 code.put_label(try_return_label)
4089 for var in Naming.exc_save_vars:
4090 code.put_xdecref_clear(var, py_object_type)
4091 code.put_goto(old_return_label)
4092 code.put_label(our_error_label)
4093 for temp_name, type in temps_to_clean_up:
4094 code.put_xdecref_clear(temp_name, type)
4095 for except_clause in self.except_clauses:
4096 except_clause.generate_handling_code(code, except_end_label)
4098 error_label_used = code.label_used(except_error_label)
4099 if error_label_used or not self.has_default_clause:
4100 if error_label_used:
4101 code.put_label(except_error_label)
4102 for var in Naming.exc_save_vars:
4103 code.put_xdecref(var, py_object_type)
4104 code.put_goto(old_error_label)
4106 if code.label_used(try_break_label):
4107 code.put_label(try_break_label)
4108 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4109 code.putln("__Pyx_ExceptionReset(%s);" %
4110 ', '.join(Naming.exc_save_vars))
4111 code.put_goto(old_break_label)
4113 if code.label_used(try_continue_label):
4114 code.put_label(try_continue_label)
4115 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4116 code.putln("__Pyx_ExceptionReset(%s);" %
4117 ', '.join(Naming.exc_save_vars))
4118 code.put_goto(old_continue_label)
4120 if code.label_used(except_return_label):
4121 code.put_label(except_return_label)
4122 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4123 code.putln("__Pyx_ExceptionReset(%s);" %
4124 ', '.join(Naming.exc_save_vars))
4125 code.put_goto(old_return_label)
4127 if code.label_used(except_end_label):
4128 code.put_label(except_end_label)
4129 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4130 code.putln("__Pyx_ExceptionReset(%s);" %
4131 ', '.join(Naming.exc_save_vars))
4132 code.put_label(try_end_label)
4135 code.return_label = old_return_label
4136 code.break_label = old_break_label
4137 code.continue_label = old_continue_label
4138 code.error_label = old_error_label
4140 def annotate(self, code):
4141 self.body.annotate(code)
4142 for except_node in self.except_clauses:
4143 except_node.annotate(code)
4144 if self.else_clause:
4145 self.else_clause.annotate(code)
4148 class ExceptClauseNode(Node):
4149 # Part of try ... except statement.
4152 # target ExprNode or None
4154 # excinfo_target NameNode or None optional target for exception info
4155 # match_flag string result of exception match
4156 # exc_value ExcValueNode used internally
4157 # function_name string qualified name of enclosing function
4158 # exc_vars (string * 3) local exception variables
4160 # excinfo_target is never set by the parser, but can be set by a transform
4161 # in order to extract more extensive information about the exception as a
4162 # sys.exc_info()-style tuple into a target variable
4164 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4167 excinfo_target = None
4169 def analyse_declarations(self, env):
4171 self.target.analyse_target_declaration(env)
4172 if self.excinfo_target is not None:
4173 self.excinfo_target.analyse_target_declaration(env)
4174 self.body.analyse_declarations(env)
4176 def analyse_expressions(self, env):
4178 genv = env.global_scope()
4179 self.function_name = env.qualified_name
4181 self.pattern.analyse_expressions(env)
4182 self.pattern = self.pattern.coerce_to_pyobject(env)
4185 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4186 self.target.analyse_target_expression(env, self.exc_value)
4187 if self.excinfo_target is not None:
4189 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4190 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4191 self.excinfo_tuple.analyse_expressions(env)
4192 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4194 self.body.analyse_expressions(env)
4196 def generate_handling_code(self, code, end_label):
4197 code.mark_pos(self.pos)
4199 self.pattern.generate_evaluation_code(code)
4201 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4203 "%s = PyErr_ExceptionMatches(%s);" % (
4205 self.pattern.py_result()))
4206 self.pattern.generate_disposal_code(code)
4207 self.pattern.free_temps(code)
4211 code.funcstate.release_temp(match_flag)
4213 code.putln("/*except:*/ {")
4215 if not getattr(self.body, 'stats', True):
4216 # most simple case: no exception variable, empty body (pass)
4217 # => reset the exception state, done
4218 code.putln("PyErr_Restore(0,0,0);")
4219 code.put_goto(end_label)
4223 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4226 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4227 # We always have to fetch the exception value even if
4228 # there is no target, because this also normalises the
4229 # exception and stores it in the thread state.
4230 code.globalstate.use_utility_code(get_exception_utility_code)
4231 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4232 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4233 code.error_goto(self.pos)))
4237 self.exc_value.set_var(exc_vars[1])
4238 self.exc_value.generate_evaluation_code(code)
4239 self.target.generate_assignment_code(self.exc_value, code)
4240 if self.excinfo_target is not None:
4241 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4242 node.set_var(tempvar)
4243 self.excinfo_tuple.generate_evaluation_code(code)
4244 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4246 old_break_label, old_continue_label = code.break_label, code.continue_label
4247 code.break_label = code.new_label('except_break')
4248 code.continue_label = code.new_label('except_continue')
4250 old_exc_vars = code.funcstate.exc_vars
4251 code.funcstate.exc_vars = exc_vars
4252 self.body.generate_execution_code(code)
4253 code.funcstate.exc_vars = old_exc_vars
4254 for var in exc_vars:
4255 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4256 code.put_goto(end_label)
4258 if code.label_used(code.break_label):
4259 code.put_label(code.break_label)
4260 for var in exc_vars:
4261 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4262 code.put_goto(old_break_label)
4263 code.break_label = old_break_label
4265 if code.label_used(code.continue_label):
4266 code.put_label(code.continue_label)
4267 for var in exc_vars:
4268 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4269 code.put_goto(old_continue_label)
4270 code.continue_label = old_continue_label
4272 for temp in exc_vars:
4273 code.funcstate.release_temp(temp)
4278 def annotate(self, code):
4280 self.pattern.annotate(code)
4282 self.target.annotate(code)
4283 self.body.annotate(code)
4286 class TryFinallyStatNode(StatNode):
4287 # try ... finally statement
4290 # finally_clause StatNode
4292 # The plan is that we funnel all continue, break
4293 # return and error gotos into the beginning of the
4294 # finally block, setting a variable to remember which
4295 # one we're doing. At the end of the finally block, we
4296 # switch on the variable to figure out where to go.
4297 # In addition, if we're doing an error, we save the
4298 # exception on entry to the finally block and restore
4301 child_attrs = ["body", "finally_clause"]
4303 preserve_exception = 1
4305 disallow_continue_in_try_finally = 0
4306 # There doesn't seem to be any point in disallowing
4307 # continue in the try block, since we have no problem
4310 def create_analysed(pos, env, body, finally_clause):
4311 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4313 create_analysed = staticmethod(create_analysed)
4315 def analyse_control_flow(self, env):
4316 env.start_branching(self.pos)
4317 self.body.analyse_control_flow(env)
4318 env.next_branch(self.body.end_pos())
4319 env.finish_branching(self.body.end_pos())
4320 self.finally_clause.analyse_control_flow(env)
4322 def analyse_declarations(self, env):
4323 self.body.analyse_declarations(env)
4324 self.finally_clause.analyse_declarations(env)
4326 def analyse_expressions(self, env):
4327 self.body.analyse_expressions(env)
4328 self.finally_clause.analyse_expressions(env)
4330 gil_check = StatNode._gil_check
4331 gil_message = "Try-finally statement"
4333 def generate_execution_code(self, code):
4334 old_error_label = code.error_label
4335 old_labels = code.all_new_labels()
4336 new_labels = code.get_all_labels()
4337 new_error_label = code.error_label
4338 catch_label = code.new_label()
4341 if self.disallow_continue_in_try_finally:
4342 was_in_try_finally = code.funcstate.in_try_finally
4343 code.funcstate.in_try_finally = 1
4344 self.body.generate_execution_code(code)
4345 if self.disallow_continue_in_try_finally:
4346 code.funcstate.in_try_finally = was_in_try_finally
4349 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4353 error_label_used = 0
4354 for i, new_label in enumerate(new_labels):
4355 if new_label in code.labels_used:
4356 cases_used.append(i)
4357 if new_label == new_error_label:
4358 error_label_used = 1
4359 error_label_case = i
4363 if error_label_used and self.preserve_exception:
4365 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4367 "int %s;" % Naming.exc_lineno_name)
4368 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4369 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4370 code.putln(exc_var_init_zero)
4372 exc_var_init_zero = None
4373 code.use_label(catch_label)
4375 "__pyx_why = 0; goto %s;" % catch_label)
4376 for i in cases_used:
4377 new_label = new_labels[i]
4378 #if new_label and new_label != "<try>":
4379 if new_label == new_error_label and self.preserve_exception:
4380 self.put_error_catcher(code,
4381 new_error_label, i+1, catch_label, temps_to_clean_up)
4383 code.put('%s: ' % new_label)
4384 if exc_var_init_zero:
4385 code.putln(exc_var_init_zero)
4386 code.putln("__pyx_why = %s; goto %s;" % (
4389 code.put_label(catch_label)
4390 code.set_all_labels(old_labels)
4391 if error_label_used:
4392 code.new_error_label()
4393 finally_error_label = code.error_label
4394 self.finally_clause.generate_execution_code(code)
4395 if error_label_used:
4396 if finally_error_label in code.labels_used and self.preserve_exception:
4397 over_label = code.new_label()
4398 code.put_goto(over_label);
4399 code.put_label(finally_error_label)
4400 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4401 for var in Naming.exc_vars:
4402 code.putln("Py_XDECREF(%s);" % var)
4404 code.put_goto(old_error_label)
4405 code.put_label(over_label)
4406 code.error_label = old_error_label
4409 "switch (__pyx_why) {")
4410 for i in cases_used:
4411 old_label = old_labels[i]
4412 if old_label == old_error_label and self.preserve_exception:
4413 self.put_error_uncatcher(code, i+1, old_error_label)
4415 code.use_label(old_label)
4417 "case %s: goto %s;" % (
4425 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4426 code.globalstate.use_utility_code(restore_exception_utility_code)
4433 for temp_name, type in temps_to_clean_up:
4434 code.put_xdecref_clear(temp_name, type)
4436 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4440 Naming.exc_lineno_name, Naming.lineno_cname))
4444 code.put_goto(catch_label)
4448 def put_error_uncatcher(self, code, i, error_label):
4449 code.globalstate.use_utility_code(restore_exception_utility_code)
4454 "__Pyx_ErrRestore(%s, %s, %s);" %
4458 Naming.lineno_cname, Naming.exc_lineno_name))
4459 for var in Naming.exc_vars:
4463 code.put_goto(error_label)
4467 def annotate(self, code):
4468 self.body.annotate(code)
4469 self.finally_clause.annotate(code)
4472 class GILStatNode(TryFinallyStatNode):
4473 # 'with gil' or 'with nogil' statement
4475 # state string 'gil' or 'nogil'
4479 preserve_exception = 0
4481 def __init__(self, pos, state, body):
4483 TryFinallyStatNode.__init__(self, pos,
4485 finally_clause = GILExitNode(pos, state = state))
4487 def analyse_expressions(self, env):
4488 env.use_utility_code(force_init_threads_utility_code)
4489 was_nogil = env.nogil
4491 TryFinallyStatNode.analyse_expressions(self, env)
4492 env.nogil = was_nogil
4494 def gil_check(self, env):
4497 def generate_execution_code(self, code):
4498 code.mark_pos(self.pos)
4499 if self.state == 'gil':
4500 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4502 code.putln("{ PyThreadState *_save;")
4503 code.putln("Py_UNBLOCK_THREADS")
4504 TryFinallyStatNode.generate_execution_code(self, code)
4508 class GILExitNode(StatNode):
4509 # Used as the 'finally' block in a GILStatNode
4511 # state string 'gil' or 'nogil'
4515 def analyse_expressions(self, env):
4518 def generate_execution_code(self, code):
4519 if self.state == 'gil':
4520 code.putln("PyGILState_Release();")
4522 code.putln("Py_BLOCK_THREADS")
4525 class CImportStatNode(StatNode):
4528 # module_name string Qualified name of module being imported
4529 # as_name string or None Name specified in "as" clause, if any
4533 def analyse_declarations(self, env):
4534 if not env.is_module_scope:
4535 error(self.pos, "cimport only allowed at module level")
4537 module_scope = env.find_module(self.module_name, self.pos)
4538 if "." in self.module_name:
4539 names = [EncodedString(name) for name in self.module_name.split(".")]
4541 top_module_scope = env.context.find_submodule(top_name)
4542 module_scope = top_module_scope
4543 for name in names[1:]:
4544 submodule_scope = module_scope.find_submodule(name)
4545 module_scope.declare_module(name, submodule_scope, self.pos)
4546 module_scope = submodule_scope
4548 env.declare_module(self.as_name, module_scope, self.pos)
4550 env.declare_module(top_name, top_module_scope, self.pos)
4552 name = self.as_name or self.module_name
4553 env.declare_module(name, module_scope, self.pos)
4555 def analyse_expressions(self, env):
4558 def generate_execution_code(self, code):
4562 class FromCImportStatNode(StatNode):
4563 # from ... cimport statement
4565 # module_name string Qualified name of module
4566 # imported_names [(pos, name, as_name, kind)] Names to be imported
4570 def analyse_declarations(self, env):
4571 if not env.is_module_scope:
4572 error(self.pos, "cimport only allowed at module level")
4574 module_scope = env.find_module(self.module_name, self.pos)
4575 env.add_imported_module(module_scope)
4576 for pos, name, as_name, kind in self.imported_names:
4578 for local_name, entry in module_scope.entries.items():
4579 env.add_imported_entry(local_name, entry, pos)
4581 entry = module_scope.lookup(name)
4583 if kind and not self.declaration_matches(entry, kind):
4584 entry.redeclared(pos)
4586 if kind == 'struct' or kind == 'union':
4587 entry = module_scope.declare_struct_or_union(name,
4588 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4589 elif kind == 'class':
4590 entry = module_scope.declare_c_class(name, pos = pos,
4591 module_name = self.module_name)
4593 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4594 if submodule_scope.parent_module is module_scope:
4595 env.declare_module(as_name or name, submodule_scope, self.pos)
4597 error(pos, "Name '%s' not declared in module '%s'"
4598 % (name, self.module_name))
4601 local_name = as_name or name
4602 env.add_imported_entry(local_name, entry, pos)
4604 def declaration_matches(self, entry, kind):
4605 if not entry.is_type:
4609 if not type.is_extension_type:
4612 if not type.is_struct_or_union:
4614 if kind != type.kind:
4618 def analyse_expressions(self, env):
4621 def generate_execution_code(self, code):
4625 class FromImportStatNode(StatNode):
4626 # from ... import statement
4629 # items [(string, NameNode)]
4630 # interned_items [(string, NameNode, ExprNode)]
4631 # item PyTempNode used internally
4632 # import_star boolean used internally
4634 child_attrs = ["module"]
4637 def analyse_declarations(self, env):
4638 for name, target in self.items:
4640 if not env.is_module_scope:
4641 error(self.pos, "import * only allowed at module level")
4643 env.has_import_star = 1
4644 self.import_star = 1
4646 target.analyse_target_declaration(env)
4648 def analyse_expressions(self, env):
4650 self.module.analyse_expressions(env)
4651 self.item = ExprNodes.PyTempNode(self.pos, env)
4652 self.interned_items = []
4653 for name, target in self.items:
4655 for _, entry in env.entries.items():
4656 if not entry.is_type and entry.type.is_extension_type:
4657 env.use_utility_code(ExprNodes.type_test_utility_code)
4660 entry = env.lookup(target.name)
4661 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4662 continue # already cimported
4663 target.analyse_target_expression(env, None)
4664 if target.type is py_object_type:
4667 coerced_item = self.item.coerce_to(target.type, env)
4668 self.interned_items.append(
4669 (name, target, coerced_item))
4671 def generate_execution_code(self, code):
4672 self.module.generate_evaluation_code(code)
4673 if self.import_star:
4675 'if (%s(%s) < 0) %s;' % (
4677 self.module.py_result(),
4678 code.error_goto(self.pos)))
4679 self.item.allocate(code)
4680 for name, target, coerced_item in self.interned_items:
4681 cname = code.intern_identifier(name)
4683 '%s = PyObject_GetAttr(%s, %s); %s' % (
4685 self.module.py_result(),
4687 code.error_goto_if_null(self.item.result(), self.pos)))
4688 code.put_gotref(self.item.py_result())
4689 if coerced_item is None:
4690 target.generate_assignment_code(self.item, code)
4692 coerced_item.allocate_temp_result(code)
4693 coerced_item.generate_result_code(code)
4694 target.generate_assignment_code(coerced_item, code)
4695 if self.item.result() != coerced_item.result():
4696 code.put_decref_clear(self.item.result(), self.item.type)
4697 self.item.release(code)
4698 self.module.generate_disposal_code(code)
4699 self.module.free_temps(code)
4703 #------------------------------------------------------------------------------------
4705 # Runtime support code
4707 #------------------------------------------------------------------------------------
4709 utility_function_predeclarations = \
4712 #define INLINE __inline__
4714 #define INLINE __inline
4719 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4723 static int %(skip_dispatch_cname)s = 0;
4725 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4727 if Options.gcc_branch_hints:
4728 branch_prediction_macros = \
4731 /* Test for GCC > 2.95 */
4732 #if __GNUC__ > 2 || \
4733 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4734 #define likely(x) __builtin_expect(!!(x), 1)
4735 #define unlikely(x) __builtin_expect(!!(x), 0)
4736 #else /* __GNUC__ > 2 ... */
4737 #define likely(x) (x)
4738 #define unlikely(x) (x)
4739 #endif /* __GNUC__ > 2 ... */
4740 #else /* __GNUC__ */
4741 #define likely(x) (x)
4742 #define unlikely(x) (x)
4743 #endif /* __GNUC__ */
4746 branch_prediction_macros = \
4748 #define likely(x) (x)
4749 #define unlikely(x) (x)
4752 #get_name_predeclaration = \
4753 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4755 #get_name_interned_predeclaration = \
4756 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4758 #------------------------------------------------------------------------------------
4760 printing_utility_code = UtilityCode(
4762 static int __Pyx_Print(PyObject *, int); /*proto*/
4763 #if PY_MAJOR_VERSION >= 3
4764 static PyObject* %s = 0;
4765 static PyObject* %s = 0;
4767 """ % (Naming.print_function, Naming.print_function_kwargs),
4769 #if PY_MAJOR_VERSION < 3
4770 static PyObject *__Pyx_GetStdout(void) {
4771 PyObject *f = PySys_GetObject((char *)"stdout");
4773 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4778 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4783 if (!(f = __Pyx_GetStdout()))
4785 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4786 if (PyFile_SoftSpace(f, 1)) {
4787 if (PyFile_WriteString(" ", f) < 0)
4790 v = PyTuple_GET_ITEM(arg_tuple, i);
4791 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4793 if (PyString_Check(v)) {
4794 char *s = PyString_AsString(v);
4795 Py_ssize_t len = PyString_Size(v);
4797 isspace(Py_CHARMASK(s[len-1])) &&
4799 PyFile_SoftSpace(f, 0);
4803 if (PyFile_WriteString("\n", f) < 0)
4805 PyFile_SoftSpace(f, 0);
4810 #else /* Python 3 has a print function */
4812 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4813 PyObject* kwargs = 0;
4814 PyObject* result = 0;
4815 PyObject* end_string;
4816 if (!%(PRINT_FUNCTION)s) {
4817 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4818 if (!%(PRINT_FUNCTION)s)
4822 if (!%(PRINT_KWARGS)s) {
4823 %(PRINT_KWARGS)s = PyDict_New();
4824 if (!%(PRINT_KWARGS)s)
4826 end_string = PyUnicode_FromStringAndSize(" ", 1);
4829 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4830 Py_DECREF(end_string);
4833 Py_DECREF(end_string);
4835 kwargs = %(PRINT_KWARGS)s;
4837 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4845 """ % {'BUILTINS' : Naming.builtins_cname,
4846 'PRINT_FUNCTION' : Naming.print_function,
4847 'PRINT_KWARGS' : Naming.print_function_kwargs}
4851 printing_one_utility_code = UtilityCode(
4853 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4856 #if PY_MAJOR_VERSION < 3
4858 static int __Pyx_PrintOne(PyObject *o) {
4860 if (!(f = __Pyx_GetStdout()))
4862 if (PyFile_SoftSpace(f, 0)) {
4863 if (PyFile_WriteString(" ", f) < 0)
4866 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4868 if (PyFile_WriteString("\n", f) < 0)
4871 /* the line below is just to avoid compiler
4872 * compiler warnings about unused functions */
4873 return __Pyx_Print(NULL, 0);
4876 #else /* Python 3 has a print function */
4878 static int __Pyx_PrintOne(PyObject *o) {
4880 PyObject* arg_tuple = PyTuple_New(1);
4881 if (unlikely(!arg_tuple))
4884 PyTuple_SET_ITEM(arg_tuple, 0, o);
4885 res = __Pyx_Print(arg_tuple, 1);
4886 Py_DECREF(arg_tuple);
4892 requires=[printing_utility_code])
4896 #------------------------------------------------------------------------------------
4898 # The following function is based on do_raise() from ceval.c.
4900 raise_utility_code = UtilityCode(
4902 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4905 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4909 /* First, check the traceback argument, replacing None with NULL. */
4910 if (tb == Py_None) {
4914 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4915 PyErr_SetString(PyExc_TypeError,
4916 "raise: arg 3 must be a traceback or None");
4919 /* Next, replace a missing value with None */
4920 if (value == NULL) {
4924 #if PY_VERSION_HEX < 0x02050000
4925 if (!PyClass_Check(type))
4927 if (!PyType_Check(type))
4930 /* Raising an instance. The value should be a dummy. */
4931 if (value != Py_None) {
4932 PyErr_SetString(PyExc_TypeError,
4933 "instance exception may not have a separate value");
4936 /* Normalize to raise <class>, <instance> */
4939 #if PY_VERSION_HEX < 0x02050000
4940 if (PyInstance_Check(type)) {
4941 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4946 PyErr_SetString(PyExc_TypeError,
4947 "raise: exception must be an old-style class or instance");
4951 type = (PyObject*) Py_TYPE(type);
4953 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4954 PyErr_SetString(PyExc_TypeError,
4955 "raise: exception class must be a subclass of BaseException");
4960 __Pyx_ErrRestore(type, value, tb);
4970 #------------------------------------------------------------------------------------
4972 reraise_utility_code = UtilityCode(
4974 static void __Pyx_ReRaise(void); /*proto*/
4977 static void __Pyx_ReRaise(void) {
4978 PyThreadState *tstate = PyThreadState_GET();
4979 PyObject* tmp_type = tstate->curexc_type;
4980 PyObject* tmp_value = tstate->curexc_value;
4981 PyObject* tmp_tb = tstate->curexc_traceback;
4982 tstate->curexc_type = tstate->exc_type;
4983 tstate->curexc_value = tstate->exc_value;
4984 tstate->curexc_traceback = tstate->exc_traceback;
4985 tstate->exc_type = 0;
4986 tstate->exc_value = 0;
4987 tstate->exc_traceback = 0;
4988 Py_XDECREF(tmp_type);
4989 Py_XDECREF(tmp_value);
4994 #------------------------------------------------------------------------------------
4996 arg_type_test_utility_code = UtilityCode(
4998 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4999 const char *name, int exact); /*proto*/
5002 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5003 const char *name, int exact)
5006 PyErr_Format(PyExc_SystemError, "Missing type object");
5009 if (none_allowed && obj == Py_None) return 1;
5011 if (Py_TYPE(obj) == type) return 1;
5014 if (PyObject_TypeCheck(obj, type)) return 1;
5016 PyErr_Format(PyExc_TypeError,
5017 "Argument '%s' has incorrect type (expected %s, got %s)",
5018 name, type->tp_name, Py_TYPE(obj)->tp_name);
5023 #------------------------------------------------------------------------------------
5025 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5026 # many or too few positional arguments were found. This handles
5027 # Py_ssize_t formatting correctly.
5029 raise_argtuple_invalid_utility_code = UtilityCode(
5031 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5032 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5035 static void __Pyx_RaiseArgtupleInvalid(
5036 const char* func_name,
5040 Py_ssize_t num_found)
5042 Py_ssize_t num_expected;
5043 const char *number, *more_or_less;
5045 if (num_found < num_min) {
5046 num_expected = num_min;
5047 more_or_less = "at least";
5049 num_expected = num_max;
5050 more_or_less = "at most";
5053 more_or_less = "exactly";
5055 number = (num_expected == 1) ? "" : "s";
5056 PyErr_Format(PyExc_TypeError,
5057 #if PY_VERSION_HEX < 0x02050000
5058 "%s() takes %s %d positional argument%s (%d given)",
5060 "%s() takes %s %zd positional argument%s (%zd given)",
5062 func_name, more_or_less, num_expected, number, num_found);
5066 raise_keyword_required_utility_code = UtilityCode(
5068 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5071 static INLINE void __Pyx_RaiseKeywordRequired(
5072 const char* func_name,
5075 PyErr_Format(PyExc_TypeError,
5076 #if PY_MAJOR_VERSION >= 3
5077 "%s() needs keyword-only argument %U", func_name, kw_name);
5079 "%s() needs keyword-only argument %s", func_name,
5080 PyString_AS_STRING(kw_name));
5085 raise_double_keywords_utility_code = UtilityCode(
5087 static void __Pyx_RaiseDoubleKeywordsError(
5088 const char* func_name, PyObject* kw_name); /*proto*/
5091 static void __Pyx_RaiseDoubleKeywordsError(
5092 const char* func_name,
5095 PyErr_Format(PyExc_TypeError,
5096 #if PY_MAJOR_VERSION >= 3
5097 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5099 "%s() got multiple values for keyword argument '%s'", func_name,
5100 PyString_AS_STRING(kw_name));
5105 #------------------------------------------------------------------------------------
5107 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5108 # were passed to a function, or if any keywords were passed to a
5109 # function that does not accept them.
5111 keyword_string_check_utility_code = UtilityCode(
5113 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5114 const char* function_name, int kw_allowed); /*proto*/
5117 static INLINE int __Pyx_CheckKeywordStrings(
5119 const char* function_name,
5124 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5125 #if PY_MAJOR_VERSION < 3
5126 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5128 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5130 goto invalid_keyword_type;
5132 if ((!kw_allowed) && unlikely(key))
5133 goto invalid_keyword;
5135 invalid_keyword_type:
5136 PyErr_Format(PyExc_TypeError,
5137 "%s() keywords must be strings", function_name);
5140 PyErr_Format(PyExc_TypeError,
5141 #if PY_MAJOR_VERSION < 3
5142 "%s() got an unexpected keyword argument '%s'",
5143 function_name, PyString_AsString(key));
5145 "%s() got an unexpected keyword argument '%U'",
5146 function_name, key);
5152 #------------------------------------------------------------------------------------
5154 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5155 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5156 # keywords will raise an invalid keyword error.
5158 # Three kinds of errors are checked: 1) non-string keywords, 2)
5159 # unexpected keywords and 3) overlap with positional arguments.
5161 # If num_posargs is greater 0, it denotes the number of positional
5162 # arguments that were passed and that must therefore not appear
5163 # amongst the keywords as well.
5165 # This method does not check for required keyword arguments.
5168 parse_keywords_utility_code = UtilityCode(
5170 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5171 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5172 const char* function_name); /*proto*/
5175 static int __Pyx_ParseOptionalKeywords(
5177 PyObject **argnames[],
5180 Py_ssize_t num_pos_args,
5181 const char* function_name)
5183 PyObject *key = 0, *value = 0;
5186 PyObject*** first_kw_arg = argnames + num_pos_args;
5188 while (PyDict_Next(kwds, &pos, &key, &value)) {
5189 name = first_kw_arg;
5190 while (*name && (**name != key)) name++;
5192 values[name-argnames] = value;
5194 #if PY_MAJOR_VERSION < 3
5195 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5197 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5199 goto invalid_keyword_type;
5201 for (name = first_kw_arg; *name; name++) {
5202 #if PY_MAJOR_VERSION >= 3
5203 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5204 PyUnicode_Compare(**name, key) == 0) break;
5206 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5207 _PyString_Eq(**name, key)) break;
5211 values[name-argnames] = value;
5213 /* unexpected keyword found */
5214 for (name=argnames; name != first_kw_arg; name++) {
5215 if (**name == key) goto arg_passed_twice;
5216 #if PY_MAJOR_VERSION >= 3
5217 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5218 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5220 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5221 _PyString_Eq(**name, key)) goto arg_passed_twice;
5225 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5227 goto invalid_keyword;
5235 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5237 invalid_keyword_type:
5238 PyErr_Format(PyExc_TypeError,
5239 "%s() keywords must be strings", function_name);
5242 PyErr_Format(PyExc_TypeError,
5243 #if PY_MAJOR_VERSION < 3
5244 "%s() got an unexpected keyword argument '%s'",
5245 function_name, PyString_AsString(key));
5247 "%s() got an unexpected keyword argument '%U'",
5248 function_name, key);
5255 #------------------------------------------------------------------------------------
5257 traceback_utility_code = UtilityCode(
5259 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5262 #include "compile.h"
5263 #include "frameobject.h"
5264 #include "traceback.h"
5266 static void __Pyx_AddTraceback(const char *funcname) {
5267 PyObject *py_srcfile = 0;
5268 PyObject *py_funcname = 0;
5269 PyObject *py_globals = 0;
5270 PyObject *empty_string = 0;
5271 PyCodeObject *py_code = 0;
5272 PyFrameObject *py_frame = 0;
5274 #if PY_MAJOR_VERSION < 3
5275 py_srcfile = PyString_FromString(%(FILENAME)s);
5277 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5279 if (!py_srcfile) goto bad;
5281 #if PY_MAJOR_VERSION < 3
5282 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5284 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5288 #if PY_MAJOR_VERSION < 3
5289 py_funcname = PyString_FromString(funcname);
5291 py_funcname = PyUnicode_FromString(funcname);
5294 if (!py_funcname) goto bad;
5295 py_globals = PyModule_GetDict(%(GLOBALS)s);
5296 if (!py_globals) goto bad;
5297 #if PY_MAJOR_VERSION < 3
5298 empty_string = PyString_FromStringAndSize("", 0);
5300 empty_string = PyBytes_FromStringAndSize("", 0);
5302 if (!empty_string) goto bad;
5303 py_code = PyCode_New(
5304 0, /*int argcount,*/
5305 #if PY_MAJOR_VERSION >= 3
5306 0, /*int kwonlyargcount,*/
5309 0, /*int stacksize,*/
5311 empty_string, /*PyObject *code,*/
5312 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5313 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5314 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5315 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5316 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5317 py_srcfile, /*PyObject *filename,*/
5318 py_funcname, /*PyObject *name,*/
5319 %(LINENO)s, /*int firstlineno,*/
5320 empty_string /*PyObject *lnotab*/
5322 if (!py_code) goto bad;
5323 py_frame = PyFrame_New(
5324 PyThreadState_GET(), /*PyThreadState *tstate,*/
5325 py_code, /*PyCodeObject *code,*/
5326 py_globals, /*PyObject *globals,*/
5327 0 /*PyObject *locals*/
5329 if (!py_frame) goto bad;
5330 py_frame->f_lineno = %(LINENO)s;
5331 PyTraceBack_Here(py_frame);
5333 Py_XDECREF(py_srcfile);
5334 Py_XDECREF(py_funcname);
5335 Py_XDECREF(empty_string);
5336 Py_XDECREF(py_code);
5337 Py_XDECREF(py_frame);
5340 'FILENAME': Naming.filename_cname,
5341 'LINENO': Naming.lineno_cname,
5342 'CFILENAME': Naming.cfilenm_cname,
5343 'CLINENO': Naming.clineno_cname,
5344 'GLOBALS': Naming.module_cname,
5345 'EMPTY_TUPLE' : Naming.empty_tuple,
5348 restore_exception_utility_code = UtilityCode(
5350 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5351 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5354 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5355 PyObject *tmp_type, *tmp_value, *tmp_tb;
5356 PyThreadState *tstate = PyThreadState_GET();
5358 #if PY_MAJOR_VERSION >= 3
5359 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5360 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5361 tmp_type = tstate->exc_type;
5362 tmp_value = tstate->exc_value;
5363 tmp_tb = tstate->exc_traceback;
5364 PyErr_NormalizeException(&type, &value, &tb);
5365 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5366 tstate->exc_type = 0;
5367 tstate->exc_value = 0;
5368 tstate->exc_traceback = 0;
5369 PyException_SetContext(value, tmp_value);
5370 Py_DECREF(tmp_type);
5375 tmp_type = tstate->curexc_type;
5376 tmp_value = tstate->curexc_value;
5377 tmp_tb = tstate->curexc_traceback;
5378 tstate->curexc_type = type;
5379 tstate->curexc_value = value;
5380 tstate->curexc_traceback = tb;
5381 Py_XDECREF(tmp_type);
5382 Py_XDECREF(tmp_value);
5386 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5387 PyThreadState *tstate = PyThreadState_GET();
5388 *type = tstate->curexc_type;
5389 *value = tstate->curexc_value;
5390 *tb = tstate->curexc_traceback;
5392 tstate->curexc_type = 0;
5393 tstate->curexc_value = 0;
5394 tstate->curexc_traceback = 0;
5399 #------------------------------------------------------------------------------------
5401 unraisable_exception_utility_code = UtilityCode(
5403 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5406 static void __Pyx_WriteUnraisable(const char *name) {
5407 PyObject *old_exc, *old_val, *old_tb;
5409 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5410 #if PY_MAJOR_VERSION < 3
5411 ctx = PyString_FromString(name);
5413 ctx = PyUnicode_FromString(name);
5415 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5417 PyErr_WriteUnraisable(Py_None);
5419 PyErr_WriteUnraisable(ctx);
5424 requires=[restore_exception_utility_code])
5426 #------------------------------------------------------------------------------------
5428 set_vtable_utility_code = UtilityCode(
5430 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5433 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5434 PyObject *pycobj = 0;
5437 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5440 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5453 #------------------------------------------------------------------------------------
5455 get_vtable_utility_code = UtilityCode(
5457 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5460 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5464 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5467 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5468 if (!*(void **)vtabptr)
5481 #------------------------------------------------------------------------------------
5483 init_string_tab_utility_code = UtilityCode(
5485 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5488 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5490 #if PY_MAJOR_VERSION < 3
5491 if (t->is_unicode && (!t->is_identifier)) {
5492 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5493 } else if (t->intern) {
5494 *t->p = PyString_InternFromString(t->s);
5496 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5498 #else /* Python 3+ has unicode identifiers */
5499 if (t->is_identifier || (t->is_unicode && t->intern)) {
5500 *t->p = PyUnicode_InternFromString(t->s);
5501 } else if (t->is_unicode) {
5502 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5504 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5515 #------------------------------------------------------------------------------------
5517 get_exception_utility_code = UtilityCode(
5519 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5522 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5523 PyObject *tmp_type, *tmp_value, *tmp_tb;
5524 PyThreadState *tstate = PyThreadState_GET();
5525 *type = tstate->curexc_type;
5526 *value = tstate->curexc_value;
5527 *tb = tstate->curexc_traceback;
5528 tstate->curexc_type = 0;
5529 tstate->curexc_value = 0;
5530 tstate->curexc_traceback = 0;
5531 PyErr_NormalizeException(type, value, tb);
5532 if (PyErr_Occurred())
5537 tmp_type = tstate->exc_type;
5538 tmp_value = tstate->exc_value;
5539 tmp_tb = tstate->exc_traceback;
5540 tstate->exc_type = *type;
5541 tstate->exc_value = *value;
5542 tstate->exc_traceback = *tb;
5543 /* Make sure tstate is in a consistent state when we XDECREF
5544 these objects (XDECREF may run arbitrary code). */
5545 Py_XDECREF(tmp_type);
5546 Py_XDECREF(tmp_value);
5558 #------------------------------------------------------------------------------------
5560 reset_exception_utility_code = UtilityCode(
5562 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5563 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5566 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5567 PyThreadState *tstate = PyThreadState_GET();
5568 *type = tstate->exc_type;
5569 *value = tstate->exc_value;
5570 *tb = tstate->exc_traceback;
5576 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5577 PyObject *tmp_type, *tmp_value, *tmp_tb;
5578 PyThreadState *tstate = PyThreadState_GET();
5579 tmp_type = tstate->exc_type;
5580 tmp_value = tstate->exc_value;
5581 tmp_tb = tstate->exc_traceback;
5582 tstate->exc_type = type;
5583 tstate->exc_value = value;
5584 tstate->exc_traceback = tb;
5585 Py_XDECREF(tmp_type);
5586 Py_XDECREF(tmp_value);
5591 #------------------------------------------------------------------------------------
5593 force_init_threads_utility_code = UtilityCode(
5595 #ifndef __PYX_FORCE_INIT_THREADS
5596 #if PY_VERSION_HEX < 0x02040200
5597 #define __PYX_FORCE_INIT_THREADS 1
5599 #define __PYX_FORCE_INIT_THREADS 0
5604 #------------------------------------------------------------------------------------