2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix
17 from Code import UtilityCode
18 from StringEncoding import EncodedString, escape_byte_string, split_docstring
23 absolute_path_length = 0
25 def relative_position(pos):
27 We embed the relative filename in the generated C file, since we
28 don't want to have to regnerate and compile all the source code
29 whenever the Python install directory moves (which could happen,
30 e.g,. when distributing binaries.)
33 a position tuple -- (absolute filename, line number column position)
41 global absolute_path_length
42 if absolute_path_length==0:
43 absolute_path_length = len(os.path.abspath(os.getcwd()))
44 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
46 def embed_position(pos, docstring):
47 if not Options.embed_pos_in_docstring:
49 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
52 return EncodedString(pos_line)
54 # make sure we can encode the filename in the docstring encoding
55 # otherwise make the docstring a unicode string
56 encoding = docstring.encoding
57 if encoding is not None:
59 encoded_bytes = pos_line.encode(encoding)
60 except UnicodeEncodeError:
64 # reuse the string encoding of the original docstring
65 doc = EncodedString(pos_line)
67 doc = EncodedString(pos_line + u'\n' + docstring)
68 doc.encoding = encoding
72 from Code import CCodeWriter
73 from types import FunctionType
75 def write_func_call(func):
77 if len(args) > 1 and isinstance(args[1], CCodeWriter):
78 # here we annotate the code with this function call
79 # but only if new code is generated
81 marker = ' /* %s -> %s.%s %s */' % (
82 ' ' * code.call_level,
83 node.__class__.__name__,
86 pristine = code.buffer.stream.tell()
88 start = code.buffer.stream.tell()
90 res = func(*args, **kwds)
92 if start == code.buffer.stream.tell():
93 code.buffer.stream.seek(pristine)
95 marker = marker.replace('->', '<-')
99 return func(*args, **kwds)
102 class VerboseCodeWriter(type):
103 # Set this as a metaclass to trace function calls in code.
104 # This slows down code generation and makes much larger files.
105 def __new__(cls, name, bases, attrs):
107 for mname, m in attrs.items():
108 if isinstance(m, FunctionType):
109 attrs[mname] = write_func_call(m)
110 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
114 # pos (string, int, int) Source file position
115 # is_name boolean Is a NameNode
116 # is_literal boolean Is a ConstNode
118 if DebugFlags.debug_trace_code_generation:
119 __metaclass__ = VerboseCodeWriter
125 # All descandants should set child_attrs to a list of the attributes
126 # containing nodes considered "children" in the tree. Each such attribute
127 # can either contain a single node or a list of nodes. See Visitor.py.
130 def __init__(self, pos, **kw):
132 self.__dict__.update(kw)
134 gil_message = "Operation"
137 def _gil_check(self, env):
142 error(self.pos, "%s not allowed without gil" % self.gil_message)
144 def clone_node(self):
145 """Clone the node. This is defined as a shallow copy, except for member lists
146 amongst the child attributes (from get_child_accessors) which are also
147 copied. Lists containing child nodes are thus seen as a way for the node
148 to hold multiple children directly; the list is not treated as a seperate
149 level in the tree."""
150 result = copy.copy(self)
151 for attrname in result.child_attrs:
152 value = getattr(result, attrname)
153 if isinstance(value, list):
154 setattr(result, attrname, [x for x in value])
159 # There are 4 phases of parse tree processing, applied in order to
160 # all the statements in a given scope-block:
162 # (0) analyse_control_flow
163 # Create the control flow tree into which state can be asserted and
166 # (1) analyse_declarations
167 # Make symbol table entries for all declarations at the current
168 # level, both explicit (def, cdef, etc.) and implicit (assignment
169 # to an otherwise undeclared name).
171 # (2) analyse_expressions
172 # Determine the result types of expressions and fill in the
173 # 'type' attribute of each ExprNode. Insert coercion nodes into the
174 # tree where needed to convert to and from Python objects.
175 # Allocate temporary locals for intermediate results. Fill
176 # in the 'result_code' attribute of each ExprNode with a C code
180 # Emit C code for all declarations, statements and expressions.
181 # Recursively applies the 3 processing phases to the bodies of
185 def analyse_control_flow(self, env):
188 def analyse_declarations(self, env):
191 def analyse_expressions(self, env):
192 raise InternalError("analyse_expressions not implemented for %s" % \
193 self.__class__.__name__)
195 def generate_code(self, code):
196 raise InternalError("generate_code not implemented for %s" % \
197 self.__class__.__name__)
199 def annotate(self, code):
200 # mro does the wrong thing
201 if isinstance(self, BlockNode):
202 self.body.annotate(code)
207 except AttributeError:
209 if not self.child_attrs:
212 for attr in self.child_attrs:
213 child = getattr(self, attr)
214 # Sometimes lists, sometimes nodes
217 elif isinstance(child, list):
219 pos = max(pos, c.end_pos())
221 pos = max(pos, child.end_pos())
225 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
227 return "<...nesting level cutoff...>"
228 if encountered is None:
230 if id(self) in encountered:
231 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
232 encountered.add(id(self))
234 def dump_child(x, level):
235 if isinstance(x, Node):
236 return x.dump(level, filter_out, cutoff-1, encountered)
237 elif isinstance(x, list):
238 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
243 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
245 return "<%s (%d)>" % (self.__class__.__name__, id(self))
248 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
249 for key, value in attrs:
250 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
251 res += "%s>" % indent
254 class CompilerDirectivesNode(Node):
256 Sets compiler directives for the children nodes
258 # directives {string:value} A dictionary holding the right value for
259 # *all* possible directives.
261 child_attrs = ["body"]
263 def analyse_control_flow(self, env):
265 env.directives = self.directives
266 self.body.analyse_control_flow(env)
269 def analyse_declarations(self, env):
271 env.directives = self.directives
272 self.body.analyse_declarations(env)
275 def analyse_expressions(self, env):
277 env.directives = self.directives
278 self.body.analyse_expressions(env)
281 def generate_function_definitions(self, env, code):
282 env_old = env.directives
283 code_old = code.globalstate.directives
284 code.globalstate.directives = self.directives
285 self.body.generate_function_definitions(env, code)
286 env.directives = env_old
287 code.globalstate.directives = code_old
289 def generate_execution_code(self, code):
290 old = code.globalstate.directives
291 code.globalstate.directives = self.directives
292 self.body.generate_execution_code(code)
293 code.globalstate.directives = old
295 def annotate(self, code):
296 old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.annotate(code)
299 code.globalstate.directives = old
301 class BlockNode(object):
302 # Mixin class for nodes representing a declaration block.
304 def generate_cached_builtins_decls(self, env, code):
305 entries = env.global_scope().undeclared_cached_builtins
306 for entry in entries:
307 code.globalstate.add_cached_builtin_decl(entry)
311 class StatListNode(Node):
312 # stats a list of StatNode
314 child_attrs = ["stats"]
316 def create_analysed(pos, env, *args, **kw):
317 node = StatListNode(pos, *args, **kw)
318 return node # No node-specific analysis necesarry
319 create_analysed = staticmethod(create_analysed)
321 def analyse_control_flow(self, env):
322 for stat in self.stats:
323 stat.analyse_control_flow(env)
325 def analyse_declarations(self, env):
326 #print "StatListNode.analyse_declarations" ###
327 for stat in self.stats:
328 stat.analyse_declarations(env)
330 def analyse_expressions(self, env):
331 #print "StatListNode.analyse_expressions" ###
332 for stat in self.stats:
333 stat.analyse_expressions(env)
335 def generate_function_definitions(self, env, code):
336 #print "StatListNode.generate_function_definitions" ###
337 for stat in self.stats:
338 stat.generate_function_definitions(env, code)
340 def generate_execution_code(self, code):
341 #print "StatListNode.generate_execution_code" ###
342 for stat in self.stats:
343 code.mark_pos(stat.pos)
344 stat.generate_execution_code(code)
346 def annotate(self, code):
347 for stat in self.stats:
351 class StatNode(Node):
353 # Code generation for statements is split into the following subphases:
355 # (1) generate_function_definitions
356 # Emit C code for the definitions of any structs,
357 # unions, enums and functions defined in the current
360 # (2) generate_execution_code
361 # Emit C code for executable statements.
364 def generate_function_definitions(self, env, code):
367 def generate_execution_code(self, code):
368 raise InternalError("generate_execution_code not implemented for %s" % \
369 self.__class__.__name__)
372 class CDefExternNode(StatNode):
373 # include_file string or None
376 child_attrs = ["body"]
378 def analyse_declarations(self, env):
379 if self.include_file:
380 env.add_include_file(self.include_file)
381 old_cinclude_flag = env.in_cinclude
383 self.body.analyse_declarations(env)
384 env.in_cinclude = old_cinclude_flag
386 def analyse_expressions(self, env):
389 def generate_execution_code(self, code):
392 def annotate(self, code):
393 self.body.annotate(code)
396 class CDeclaratorNode(Node):
397 # Part of a C declaration.
399 # Processing during analyse_declarations phase:
402 # Returns (name, type) pair where name is the
403 # CNameDeclaratorNode of the name being declared
404 # and type is the type it is being declared as.
406 # calling_convention string Calling convention of CFuncDeclaratorNode
407 # for which this is a base
411 calling_convention = ""
414 class CNameDeclaratorNode(CDeclaratorNode):
415 # name string The Pyrex name being declared
416 # cname string or None C name, if specified
417 # default ExprNode or None the value assigned on declaration
419 child_attrs = ['default']
423 def analyse(self, base_type, env, nonempty = 0):
424 if nonempty and self.name == '':
425 # May have mistaken the name for the type.
426 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
427 error(self.pos, "Missing argument name")
428 elif base_type.is_void:
429 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
431 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
432 base_type = py_object_type
433 self.type = base_type
434 return self, base_type
436 class CPtrDeclaratorNode(CDeclaratorNode):
437 # base CDeclaratorNode
439 child_attrs = ["base"]
441 def analyse(self, base_type, env, nonempty = 0):
442 if base_type.is_pyobject:
444 "Pointer base type cannot be a Python object")
445 ptr_type = PyrexTypes.c_ptr_type(base_type)
446 return self.base.analyse(ptr_type, env, nonempty = nonempty)
448 class CArrayDeclaratorNode(CDeclaratorNode):
449 # base CDeclaratorNode
452 child_attrs = ["base", "dimension"]
454 def analyse(self, base_type, env, nonempty = 0):
456 self.dimension.analyse_const_expression(env)
457 if not self.dimension.type.is_int:
458 error(self.dimension.pos, "Array dimension not integer")
459 size = self.dimension.get_constant_c_result_code()
468 if not base_type.is_complete():
470 "Array element type '%s' is incomplete" % base_type)
471 if base_type.is_pyobject:
473 "Array element cannot be a Python object")
474 if base_type.is_cfunction:
476 "Array element cannot be a function")
477 array_type = PyrexTypes.c_array_type(base_type, size)
478 return self.base.analyse(array_type, env, nonempty = nonempty)
481 class CFuncDeclaratorNode(CDeclaratorNode):
482 # base CDeclaratorNode
483 # args [CArgDeclNode]
484 # has_varargs boolean
485 # exception_value ConstNode
486 # exception_check boolean True if PyErr_Occurred check needed
487 # nogil boolean Can be called without gil
488 # with_gil boolean Acquire gil around function body
490 child_attrs = ["base", "args", "exception_value"]
493 optional_arg_count = 0
495 def analyse(self, return_type, env, nonempty = 0):
499 for arg_node in self.args:
500 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
501 name = name_declarator.name
502 if name_declarator.cname:
504 "Function argument cannot have C name specification")
505 # Turn *[] argument into **
507 type = PyrexTypes.c_ptr_type(type.base_type)
508 # Catch attempted C-style func(void) decl
510 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
511 func_type_args.append(
512 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
514 self.optional_arg_count += 1
515 elif self.optional_arg_count:
516 error(self.pos, "Non-default argument follows default argument")
518 if self.optional_arg_count:
519 scope = StructOrUnionScope()
520 arg_count_member = '%sn' % Naming.pyrex_prefix
521 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
522 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
523 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
524 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
525 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
530 cname = struct_cname)
531 self.op_args_struct.defined_in_pxd = 1
532 self.op_args_struct.used = 1
536 if self.exception_check == '+':
537 env.add_include_file('stdexcept')
538 if return_type.is_pyobject \
539 and (self.exception_value or self.exception_check) \
540 and self.exception_check != '+':
542 "Exception clause not allowed for function returning Python object")
544 if self.exception_value:
545 self.exception_value.analyse_const_expression(env)
546 exc_val = self.exception_value.get_constant_c_result_code()
547 if self.exception_check == '+':
548 exc_val_type = self.exception_value.type
549 if not exc_val_type.is_error and \
550 not exc_val_type.is_pyobject and \
551 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
552 error(self.exception_value.pos,
553 "Exception value must be a Python exception or cdef function with no arguments.")
555 if not return_type.assignable_from(self.exception_value.type):
556 error(self.exception_value.pos,
557 "Exception value incompatible with function return type")
558 exc_check = self.exception_check
559 if return_type.is_array:
561 "Function cannot return an array")
562 if return_type.is_cfunction:
564 "Function cannot return a function")
565 func_type = PyrexTypes.CFuncType(
566 return_type, func_type_args, self.has_varargs,
567 optional_arg_count = self.optional_arg_count,
568 exception_value = exc_val, exception_check = exc_check,
569 calling_convention = self.base.calling_convention,
570 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
571 if self.optional_arg_count:
572 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
573 callspec = env.directives['callspec']
575 current = func_type.calling_convention
576 if current and current != callspec:
577 error(self.pos, "cannot have both '%s' and '%s' "
578 "calling conventions" % (current, callspec))
579 func_type.calling_convention = callspec
580 return self.base.analyse(func_type, env)
583 class CArgDeclNode(Node):
584 # Item in a function declaration argument list.
586 # base_type CBaseTypeNode
587 # declarator CDeclaratorNode
588 # not_none boolean Tagged with 'not None'
589 # default ExprNode or None
590 # default_value PyObjectConst constant for default value
591 # is_self_arg boolean Is the "self" arg of an extension type method
592 # is_kw_only boolean Is a keyword-only argument
594 child_attrs = ["base_type", "declarator", "default"]
599 name_declarator = None
602 def analyse(self, env, nonempty = 0):
603 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
604 if self.type is None:
605 # The parser may missinterpret names as types...
607 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
609 self.declarator.name = self.base_type.name
610 self.base_type.name = None
611 self.base_type.is_basic_c_type = False
614 could_be_name = False
615 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
616 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
617 self.declarator.name = self.base_type.arg_name
618 return self.declarator.analyse(base_type, env, nonempty = nonempty)
620 return self.name_declarator, self.type
622 def calculate_default_value_code(self, code):
623 if self.default_value is None:
625 if self.default.is_literal:
626 # will not output any code, just assign the result_code
627 self.default.generate_evaluation_code(code)
628 return self.type.cast_code(self.default.result())
629 self.default_value = code.get_argument_default_const(self.type)
630 return self.default_value
632 def annotate(self, code):
634 self.default.annotate(code)
637 class CBaseTypeNode(Node):
638 # Abstract base class for C base type nodes.
640 # Processing during analyse_declarations phase:
647 class CAnalysedBaseTypeNode(Node):
652 def analyse(self, env, could_be_name = False):
655 class CSimpleBaseTypeNode(CBaseTypeNode):
657 # module_path [string] Qualifying name components
658 # is_basic_c_type boolean
662 # is_self_arg boolean Is self argument of C method
665 arg_name = None # in case the argument name was interpreted as a type
667 def analyse(self, env, could_be_name = False):
668 # Return type descriptor.
669 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
671 if self.is_basic_c_type:
672 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
674 error(self.pos, "Unrecognised type modifier combination")
675 elif self.name == "object" and not self.module_path:
676 type = py_object_type
677 elif self.name is None:
678 if self.is_self_arg and env.is_c_class_scope:
679 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
680 type = env.parent_type
682 type = py_object_type
685 scope = env.find_imported_module(self.module_path, self.pos)
689 if scope.is_c_class_scope:
690 scope = scope.global_scope()
691 entry = scope.lookup(self.name)
692 if entry and entry.is_type:
695 if self.is_self_arg and env.is_c_class_scope:
696 type = env.parent_type
698 type = py_object_type
699 self.arg_name = self.name
701 error(self.pos, "'%s' is not a type identifier" % self.name)
703 if not type.is_numeric or type.is_complex:
704 error(self.pos, "can only complexify c numeric types")
705 type = PyrexTypes.CComplexType(type)
706 type.create_declaration_utility_code(env)
710 return PyrexTypes.error_type
712 class CBufferAccessTypeNode(CBaseTypeNode):
714 # positional_args [ExprNode] List of positional arguments
715 # keyword_args DictNode Keyword arguments
716 # base_type_node CBaseTypeNode
719 # type PyrexType.BufferType ...containing the right options
722 child_attrs = ["base_type_node", "positional_args",
723 "keyword_args", "dtype_node"]
729 def analyse(self, env, could_be_name = False):
730 base_type = self.base_type_node.analyse(env)
731 if base_type.is_error: return base_type
734 options = Buffer.analyse_buffer_options(
737 self.positional_args,
739 base_type.buffer_defaults)
741 self.type = PyrexTypes.BufferType(base_type, **options)
744 class CComplexBaseTypeNode(CBaseTypeNode):
745 # base_type CBaseTypeNode
746 # declarator CDeclaratorNode
748 child_attrs = ["base_type", "declarator"]
750 def analyse(self, env, could_be_name = False):
751 base = self.base_type.analyse(env, could_be_name)
752 _, type = self.declarator.analyse(base, env)
756 class CVarDefNode(StatNode):
757 # C variable definition or forward/extern function declaration.
759 # visibility 'private' or 'public' or 'extern'
760 # base_type CBaseTypeNode
761 # declarators [CDeclaratorNode]
764 # need_properties [entry]
766 # decorators [cython.locals(...)] or None
767 # directive_locals { string : NameNode } locals defined by cython.locals(...)
769 child_attrs = ["base_type", "declarators"]
773 directive_locals = {}
775 def analyse_declarations(self, env, dest_scope = None):
778 self.dest_scope = dest_scope
779 base_type = self.base_type.analyse(env)
781 # If the field is an external typedef, we cannot be sure about the type,
782 # so do conversion ourself rather than rely on the CPython mechanism (through
783 # a property; made in AnalyseDeclarationsTransform).
784 if (dest_scope.is_c_class_scope
785 and self.visibility == 'public'
786 and base_type.is_pyobject
787 and (base_type.is_builtin_type or base_type.is_extension_type)):
788 self.need_properties = []
790 visibility = 'private'
792 need_property = False
793 visibility = self.visibility
795 for declarator in self.declarators:
796 name_declarator, type = declarator.analyse(base_type, env)
797 if not type.is_complete():
798 if not (self.visibility == 'extern' and type.is_array):
799 error(declarator.pos,
800 "Variable type '%s' is incomplete" % type)
801 if self.visibility == 'extern' and type.is_pyobject:
802 error(declarator.pos,
803 "Python object cannot be declared extern")
804 name = name_declarator.name
805 cname = name_declarator.cname
807 error(declarator.pos, "Missing name in declaration.")
809 if type.is_cfunction:
810 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
811 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
813 if entry is not None:
814 entry.directive_locals = self.directive_locals
816 if self.directive_locals:
817 s.error("Decorators can only be followed by functions")
818 if self.in_pxd and self.visibility != 'extern':
820 "Only 'extern' C variable declaration allowed in .pxd file")
821 entry = dest_scope.declare_var(name, type, declarator.pos,
822 cname = cname, visibility = visibility, is_cdef = 1)
824 self.need_properties.append(entry)
825 entry.needs_property = 1
828 class CStructOrUnionDefNode(StatNode):
830 # cname string or None
831 # kind "struct" or "union"
832 # typedef_flag boolean
833 # visibility "public" or "private"
835 # attributes [CVarDefNode] or None
839 child_attrs = ["attributes"]
841 def analyse_declarations(self, env):
843 if self.visibility == 'extern' and self.packed:
844 error(self.pos, "Cannot declare extern struct as 'packed'")
845 if self.attributes is not None:
846 scope = StructOrUnionScope(self.name)
847 self.entry = env.declare_struct_or_union(
848 self.name, self.kind, scope, self.typedef_flag, self.pos,
849 self.cname, visibility = self.visibility, packed = self.packed)
850 if self.attributes is not None:
851 if self.in_pxd and not env.in_cinclude:
852 self.entry.defined_in_pxd = 1
853 for attr in self.attributes:
854 attr.analyse_declarations(env, scope)
855 if self.visibility != 'extern':
856 need_typedef_indirection = False
857 for attr in scope.var_entries:
860 type = type.base_type
861 if type == self.entry.type:
862 error(attr.pos, "Struct cannot contain itself as a member.")
863 if self.typedef_flag:
865 type = type.base_type
866 if type == self.entry.type:
867 need_typedef_indirection = True
868 if need_typedef_indirection:
869 # C can't handle typedef structs that refer to themselves.
870 struct_entry = self.entry
871 self.entry = env.declare_typedef(
872 self.name, struct_entry.type, self.pos,
873 cname = self.cname, visibility='ignore')
874 struct_entry.type.typedef_flag = False
875 # FIXME: this might be considered a hack ;-)
876 struct_entry.cname = struct_entry.type.cname = \
877 '_' + self.entry.type.typedef_cname
879 def analyse_expressions(self, env):
882 def generate_execution_code(self, code):
886 class CEnumDefNode(StatNode):
887 # name string or None
888 # cname string or None
889 # items [CEnumDefItemNode]
890 # typedef_flag boolean
891 # visibility "public" or "private"
895 child_attrs = ["items"]
897 def analyse_declarations(self, env):
898 self.entry = env.declare_enum(self.name, self.pos,
899 cname = self.cname, typedef_flag = self.typedef_flag,
900 visibility = self.visibility)
901 if self.items is not None:
902 if self.in_pxd and not env.in_cinclude:
903 self.entry.defined_in_pxd = 1
904 for item in self.items:
905 item.analyse_declarations(env, self.entry)
907 def generate_execution_code(self, code):
908 if self.visibility == 'public':
909 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
910 for item in self.entry.enum_values:
911 code.putln("%s = PyInt_FromLong(%s); %s" % (
914 code.error_goto_if_null(temp, item.pos)))
915 code.put_gotref(temp)
916 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
920 code.error_goto(item.pos)))
921 code.put_decref_clear(temp, PyrexTypes.py_object_type)
922 code.funcstate.release_temp(temp)
925 class CEnumDefItemNode(StatNode):
927 # cname string or None
928 # value ExprNode or None
930 child_attrs = ["value"]
932 def analyse_declarations(self, env, enum_entry):
934 self.value.analyse_const_expression(env)
935 if not self.value.type.is_int:
936 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
937 self.value.analyse_const_expression(env)
938 entry = env.declare_const(self.name, enum_entry.type,
939 self.value, self.pos, cname = self.cname,
940 visibility = enum_entry.visibility)
941 enum_entry.enum_values.append(entry)
944 class CTypeDefNode(StatNode):
945 # base_type CBaseTypeNode
946 # declarator CDeclaratorNode
947 # visibility "public" or "private"
950 child_attrs = ["base_type", "declarator"]
952 def analyse_declarations(self, env):
953 base = self.base_type.analyse(env)
954 name_declarator, type = self.declarator.analyse(base, env)
955 name = name_declarator.name
956 cname = name_declarator.cname
957 entry = env.declare_typedef(name, type, self.pos,
958 cname = cname, visibility = self.visibility)
959 if self.in_pxd and not env.in_cinclude:
960 entry.defined_in_pxd = 1
962 def analyse_expressions(self, env):
964 def generate_execution_code(self, code):
968 class FuncDefNode(StatNode, BlockNode):
969 # Base class for function definition nodes.
971 # return_type PyrexType
972 # #filename string C name of filename string const
974 # needs_closure boolean Whether or not this function has inner functions/classes/yield
975 # directive_locals { string : NameNode } locals defined by cython.locals(...)
979 needs_closure = False
981 def analyse_default_values(self, env):
982 genv = env.global_scope()
983 for arg in self.args:
986 arg.default.analyse_types(env)
987 arg.default = arg.default.coerce_to(arg.type, genv)
990 "This argument cannot have a default value")
993 def need_gil_acquisition(self, lenv):
996 def create_local_scope(self, env):
998 while env.is_py_class_scope or env.is_c_class_scope:
999 env = env.outer_scope
1000 if self.needs_closure:
1001 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
1003 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
1004 lenv.return_type = self.return_type
1005 type = self.entry.type
1006 if type.is_cfunction:
1007 lenv.nogil = type.nogil and not type.with_gil
1008 self.local_scope = lenv
1009 lenv.directives = env.directives
1012 def generate_function_definitions(self, env, code):
1015 lenv = self.local_scope
1017 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1018 self.entry.scope.is_c_class_scope)
1020 # Generate C code for header and body of function
1021 code.enter_cfunc_scope()
1022 code.return_from_error_cleanup_label = code.new_label()
1024 # ----- Top-level constants used by this function
1025 code.mark_pos(self.pos)
1026 self.generate_cached_builtins_decls(lenv, code)
1027 # ----- Function header
1030 self.py_func.generate_function_header(code,
1031 with_pymethdef = env.is_py_class_scope,
1033 self.generate_function_header(code,
1034 with_pymethdef = env.is_py_class_scope)
1035 # ----- Local variable declarations
1036 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1037 self.generate_argument_declarations(lenv, code)
1038 if self.needs_closure:
1039 code.putln("/* TODO: declare and create scope object */")
1040 code.put_var_declarations(lenv.var_entries)
1042 if not self.return_type.is_void:
1043 if self.return_type.is_pyobject:
1047 (self.return_type.declaration_code(
1048 Naming.retval_cname),
1050 tempvardecl_code = code.insertion_point()
1051 self.generate_keyword_list(code)
1052 # ----- Extern library function declarations
1053 lenv.generate_library_function_declarations(code)
1054 # ----- GIL acquisition
1055 acquire_gil = self.need_gil_acquisition(lenv)
1057 env.use_utility_code(force_init_threads_utility_code)
1058 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1059 # ----- Automatic lead-ins for certain special functions
1061 code.put_setup_refcount_context(self.entry.name)
1062 if is_getbuffer_slot:
1063 self.getbuffer_init(code)
1064 # ----- Fetch arguments
1065 self.generate_argument_parsing_code(env, code)
1066 # If an argument is assigned to in the body, we must
1067 # incref it to properly keep track of refcounts.
1068 for entry in lenv.arg_entries:
1069 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1070 code.put_var_incref(entry)
1071 # ----- Initialise local variables
1072 for entry in lenv.var_entries:
1073 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1074 code.put_init_var_to_py_none(entry)
1075 # ----- Initialise local buffer auxiliary variables
1076 for entry in lenv.var_entries + lenv.arg_entries:
1077 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1078 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1079 # ----- Check and convert arguments
1080 self.generate_argument_type_tests(code)
1081 # ----- Acquire buffer arguments
1082 for entry in lenv.arg_entries:
1083 if entry.type.is_buffer:
1084 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1085 # ----- Function body
1086 self.body.generate_execution_code(code)
1087 # ----- Default return value
1089 if self.return_type.is_pyobject:
1090 #if self.return_type.is_extension_type:
1091 # lhs = "(PyObject *)%s" % Naming.retval_cname
1093 lhs = Naming.retval_cname
1094 code.put_init_to_py_none(lhs, self.return_type)
1096 val = self.return_type.default_value
1098 code.putln("%s = %s;" % (Naming.retval_cname, val))
1099 # ----- Error cleanup
1100 if code.error_label in code.labels_used:
1101 code.put_goto(code.return_label)
1102 code.put_label(code.error_label)
1103 for cname, type in code.funcstate.all_managed_temps():
1104 code.put_xdecref(cname, type)
1106 # Clean up buffers -- this calls a Python function
1107 # so need to save and restore error state
1108 buffers_present = len(lenv.buffer_entries) > 0
1110 code.globalstate.use_utility_code(restore_exception_utility_code)
1111 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1112 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1113 for entry in lenv.buffer_entries:
1114 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1115 #code.putln("%s = 0;" % entry.cname)
1116 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1118 err_val = self.error_value()
1119 exc_check = self.caller_will_check_exceptions()
1120 if err_val is not None or exc_check:
1121 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1123 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1124 % self.entry.qualified_name, 0)
1126 '__Pyx_WriteUnraisable("%s");' %
1127 self.entry.qualified_name)
1128 env.use_utility_code(unraisable_exception_utility_code)
1129 env.use_utility_code(restore_exception_utility_code)
1130 default_retval = self.return_type.default_value
1131 if err_val is None and default_retval:
1132 err_val = default_retval
1133 if err_val is not None:
1136 Naming.retval_cname,
1139 if is_getbuffer_slot:
1140 self.getbuffer_error_cleanup(code)
1142 # If we are using the non-error cleanup section we should
1143 # jump past it if we have an error. The if-test below determine
1144 # whether this section is used.
1145 if buffers_present or is_getbuffer_slot:
1146 code.put_goto(code.return_from_error_cleanup_label)
1149 # ----- Non-error return cleanup
1150 # If you add anything here, remember to add a condition to the
1151 # if-test above in the error block (so that it can jump past this
1153 code.put_label(code.return_label)
1154 for entry in lenv.buffer_entries:
1156 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1157 if is_getbuffer_slot:
1158 self.getbuffer_normal_cleanup(code)
1159 # ----- Return cleanup for both error and no-error return
1160 code.put_label(code.return_from_error_cleanup_label)
1161 if not Options.init_local_none:
1162 for entry in lenv.var_entries:
1163 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1164 entry.xdecref_cleanup = 1
1165 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1166 # Decref any increfed args
1167 for entry in lenv.arg_entries:
1168 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1169 code.put_var_decref(entry)
1171 # code.putln("/* TODO: decref scope object */")
1173 # This code is duplicated in ModuleNode.generate_module_init_func
1175 default_retval = self.return_type.default_value
1176 err_val = self.error_value()
1177 if err_val is None and default_retval:
1178 err_val = default_retval
1179 if self.return_type.is_pyobject:
1180 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1182 code.put_finish_refcount_context()
1184 if self.entry.is_special and self.entry.name == "__hash__":
1185 # Returning -1 for __hash__ is supposed to signal an error
1186 # We do as Python instances and coerce -1 into -2.
1187 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (Naming.retval_cname, Naming.retval_cname))
1190 code.putln("PyGILState_Release(_save);")
1192 if not self.return_type.is_void:
1193 code.putln("return %s;" % Naming.retval_cname)
1196 # ----- Go back and insert temp variable declarations
1197 tempvardecl_code.put_temp_declarations(code.funcstate)
1198 # ----- Python version
1199 code.exit_cfunc_scope()
1201 self.py_func.generate_function_definitions(env, code)
1202 self.generate_wrapper_functions(code)
1204 def declare_argument(self, env, arg):
1205 if arg.type.is_void:
1206 error(arg.pos, "Invalid use of 'void'")
1207 elif not arg.type.is_complete() and not arg.type.is_array:
1209 "Argument type '%s' is incomplete" % arg.type)
1210 return env.declare_arg(arg.name, arg.type, arg.pos)
1212 def generate_wrapper_functions(self, code):
1215 def generate_execution_code(self, code):
1216 # Evaluate and store argument default values
1217 for arg in self.args:
1218 default = arg.default
1220 if not default.is_literal:
1221 default.generate_evaluation_code(code)
1222 default.make_owned_reference(code)
1223 result = default.result_as(arg.type)
1226 arg.calculate_default_value_code(code),
1228 if arg.type.is_pyobject:
1229 code.put_giveref(default.result())
1230 default.generate_post_assignment_code(code)
1231 default.free_temps(code)
1232 # For Python class methods, create and store function object
1234 self.assmt.generate_execution_code(code)
1237 # Special code for the __getbuffer__ function
1239 def getbuffer_init(self, code):
1240 info = self.local_scope.arg_entries[1].cname
1241 # Python 3.0 betas have a bug in memoryview which makes it call
1242 # getbuffer with a NULL parameter. For now we work around this;
1243 # the following line should be removed when this bug is fixed.
1244 code.putln("if (%s == NULL) return 0;" % info)
1245 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1246 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1248 def getbuffer_error_cleanup(self, code):
1249 info = self.local_scope.arg_entries[1].cname
1250 code.put_gotref("%s->obj" % info)
1251 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1254 def getbuffer_normal_cleanup(self, code):
1255 info = self.local_scope.arg_entries[1].cname
1256 code.putln("if (%s->obj == Py_None) {" % info)
1257 code.put_gotref("Py_None")
1258 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1261 class CFuncDefNode(FuncDefNode):
1262 # C function definition.
1264 # modifiers ['inline']
1265 # visibility 'private' or 'public' or 'extern'
1266 # base_type CBaseTypeNode
1267 # declarator CDeclaratorNode
1270 # decorators [DecoratorNode] list of decorators
1272 # with_gil boolean Acquire GIL around body
1274 # py_func wrapper for calling from Python
1275 # overridable whether or not this is a cpdef function
1276 # inline_in_pxd whether this is an inline function in a pxd file
1278 child_attrs = ["base_type", "declarator", "body", "py_func"]
1280 inline_in_pxd = False
1282 directive_locals = {}
1284 def unqualified_name(self):
1285 return self.entry.name
1287 def analyse_declarations(self, env):
1288 directive_locals = self.directive_locals = env.directives['locals']
1289 base_type = self.base_type.analyse(env)
1290 # The 2 here is because we need both function and argument names.
1291 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1292 if not type.is_cfunction:
1294 "Suite attached to non-function declaration")
1295 # Remember the actual type according to the function header
1296 # written here, because the type in the symbol table entry
1297 # may be different if we're overriding a C method inherited
1298 # from the base type of an extension type.
1300 type.is_overridable = self.overridable
1301 declarator = self.declarator
1302 while not hasattr(declarator, 'args'):
1303 declarator = declarator.base
1304 self.args = declarator.args
1305 for formal_arg, type_arg in zip(self.args, type.args):
1306 formal_arg.type = type_arg.type
1307 formal_arg.name = type_arg.name
1308 formal_arg.cname = type_arg.cname
1309 name = name_declarator.name
1310 cname = name_declarator.cname
1311 self.entry = env.declare_cfunction(
1312 name, type, self.pos,
1313 cname = cname, visibility = self.visibility,
1314 defining = self.body is not None,
1315 api = self.api, modifiers = self.modifiers)
1316 self.entry.inline_func_in_pxd = self.inline_in_pxd
1317 self.return_type = type.return_type
1319 if self.overridable and not env.is_module_scope:
1320 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1321 # An error will be produced in the cdef function
1322 self.overridable = False
1324 if self.overridable:
1326 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1327 self.py_func = DefNode(pos = self.pos,
1328 name = self.entry.name,
1331 starstar_arg = None,
1333 body = py_func_body,
1335 self.py_func.is_module_scope = env.is_module_scope
1336 self.py_func.analyse_declarations(env)
1337 self.entry.as_variable = self.py_func.entry
1338 # Reset scope entry the above cfunction
1339 env.entries[name] = self.entry
1340 if not env.is_module_scope or Options.lookup_module_cpdef:
1341 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1342 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1344 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1346 args = self.type.args
1347 if omit_optional_args:
1348 args = args[:len(args) - self.type.optional_arg_count]
1349 arg_names = [arg.name for arg in args]
1351 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1353 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1354 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1355 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1356 c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1357 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1359 def declare_arguments(self, env):
1360 for arg in self.type.args:
1362 error(arg.pos, "Missing argument name")
1363 self.declare_argument(env, arg)
1365 def need_gil_acquisition(self, lenv):
1366 return self.type.with_gil
1368 def gil_check(self, env):
1370 with_gil = type.with_gil
1371 if type.nogil and not with_gil:
1372 if type.return_type.is_pyobject:
1374 "Function with Python return type cannot be declared nogil")
1375 for entry in env.var_entries:
1376 if entry.type.is_pyobject:
1377 error(self.pos, "Function declared nogil has Python locals or temporaries")
1379 def analyse_expressions(self, env):
1380 self.local_scope.directives = env.directives
1381 if self.py_func is not None:
1382 # this will also analyse the default values
1383 self.py_func.analyse_expressions(env)
1385 self.analyse_default_values(env)
1387 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1390 visibility = self.entry.visibility
1391 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1392 arg_decls.append(arg.declaration_code())
1393 if with_dispatch and self.overridable:
1394 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1395 if type.optional_arg_count and with_opt_args:
1396 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1397 if type.has_varargs:
1398 arg_decls.append("...")
1400 arg_decls = ["void"]
1402 cname = self.entry.func_cname
1403 entity = type.function_header_code(cname, ', '.join(arg_decls))
1404 if visibility == 'public':
1405 dll_linkage = "DL_EXPORT"
1408 header = self.return_type.declaration_code(entity,
1409 dll_linkage = dll_linkage)
1410 if visibility == 'extern':
1411 storage_class = "%s " % Naming.extern_c_macro
1412 elif visibility == 'public':
1415 storage_class = "static "
1416 code.putln("%s%s %s {" % (
1418 ' '.join(self.modifiers).upper(), # macro forms
1421 def generate_argument_declarations(self, env, code):
1422 for arg in self.args:
1424 result = arg.calculate_default_value_code(code)
1425 code.putln('%s = %s;' % (
1426 arg.type.declaration_code(arg.cname), result))
1428 def generate_keyword_list(self, code):
1431 def generate_argument_parsing_code(self, env, code):
1433 if self.type.optional_arg_count:
1434 code.putln('if (%s) {' % Naming.optional_args_cname)
1435 for arg in self.args:
1437 # FIXME: simple name prefixing doesn't work when
1438 # argument name mangling is in place
1439 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1440 declarator = arg.declarator
1441 while not hasattr(declarator, 'name'):
1442 declarator = declarator.base
1443 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1445 for _ in range(self.type.optional_arg_count):
1449 def generate_argument_conversion_code(self, code):
1452 def generate_argument_type_tests(self, code):
1453 # Generate type tests for args whose type in a parent
1454 # class is a supertype of the declared type.
1455 for arg in self.type.args:
1456 if arg.needs_type_test:
1457 self.generate_arg_type_test(arg, code)
1459 def generate_arg_type_test(self, arg, code):
1460 # Generate type test for one argument.
1461 if arg.type.typeobj_is_available():
1462 typeptr_cname = arg.type.typeptr_cname
1463 arg_code = "((PyObject *)%s)" % arg.cname
1465 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1470 type.is_builtin_type,
1471 code.error_goto(arg.pos)))
1473 error(arg.pos, "Cannot test type of extern C class "
1474 "without type object name specification")
1476 def error_value(self):
1477 if self.return_type.is_pyobject:
1481 return self.entry.type.exception_value
1483 def caller_will_check_exceptions(self):
1484 return self.entry.type.exception_check
1486 def generate_wrapper_functions(self, code):
1487 # If the C signature of a function has changed, we need to generate
1488 # wrappers to put in the slots here.
1491 func_type = entry.type
1492 while entry.prev_entry is not None:
1494 entry = entry.prev_entry
1495 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1497 self.generate_function_header(code,
1499 with_dispatch = entry.type.is_overridable,
1500 with_opt_args = entry.type.optional_arg_count,
1501 cname = entry.func_cname)
1502 if not self.return_type.is_void:
1504 args = self.type.args
1505 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1506 if entry.type.is_overridable:
1507 arglist.append(Naming.skip_dispatch_cname)
1508 elif func_type.is_overridable:
1510 if entry.type.optional_arg_count:
1511 arglist.append(Naming.optional_args_cname)
1512 elif func_type.optional_arg_count:
1513 arglist.append('NULL')
1514 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1518 class PyArgDeclNode(Node):
1519 # Argument which must be a Python object (used
1520 # for * and ** arguments).
1523 # entry Symtab.Entry
1527 class DecoratorNode(Node):
1530 # decorator NameNode or CallNode
1531 child_attrs = ['decorator']
1534 class DefNode(FuncDefNode):
1535 # A Python function definition.
1537 # name string the Python name of the function
1538 # decorators [DecoratorNode] list of decorators
1539 # args [CArgDeclNode] formal arguments
1540 # star_arg PyArgDeclNode or None * argument
1541 # starstar_arg PyArgDeclNode or None ** argument
1542 # doc EncodedString or None
1545 # The following subnode is constructed internally
1546 # when the def statement is inside a Python class definition.
1548 # assmt AssignmentNode Function construction/assignment
1550 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1554 num_required_kw_args = 0
1555 reqd_kw_flags_cname = "0"
1561 def __init__(self, pos, **kwds):
1562 FuncDefNode.__init__(self, pos, **kwds)
1564 for arg in self.args:
1571 self.num_kwonly_args = k
1572 self.num_required_kw_args = rk
1573 self.num_required_args = r
1575 def as_cfunction(self, cfunc=None, scope=None):
1577 error(self.star_arg.pos, "cdef function cannot have star argument")
1578 if self.starstar_arg:
1579 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1582 for formal_arg in self.args:
1583 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1584 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1586 type = py_object_type,
1587 pos = formal_arg.pos))
1588 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1590 has_varargs = False,
1591 exception_value = None,
1592 exception_check = False,
1595 is_overridable = True)
1596 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1598 cfunc_type = cfunc.type
1599 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1600 error(self.pos, "wrong number of arguments")
1601 error(declarator.pos, "previous declaration here")
1602 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1603 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1604 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1605 formal_arg.type = type_arg.type
1606 formal_arg.name_declarator = name_declarator
1608 if cfunc_type.exception_value is None:
1609 exception_value = None
1611 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1612 declarator = CFuncDeclaratorNode(self.pos,
1613 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1615 has_varargs = False,
1616 exception_check = cfunc_type.exception_check,
1617 exception_value = exception_value,
1618 with_gil = cfunc_type.with_gil,
1619 nogil = cfunc_type.nogil)
1620 return CFuncDefNode(self.pos,
1622 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1623 declarator = declarator,
1626 overridable = cfunc_type.is_overridable,
1628 with_gil = cfunc_type.with_gil,
1629 nogil = cfunc_type.nogil,
1630 visibility = 'private',
1632 directive_locals = getattr(cfunc, 'directive_locals', {}))
1634 def analyse_declarations(self, env):
1635 directive_locals = self.directive_locals = env.directives['locals']
1636 for arg in self.args:
1637 if hasattr(arg, 'name'):
1639 name_declarator = None
1641 base_type = arg.base_type.analyse(env)
1642 name_declarator, type = \
1643 arg.declarator.analyse(base_type, env)
1644 arg.name = name_declarator.name
1645 if arg.name in directive_locals:
1646 type_node = directive_locals[arg.name]
1647 other_type = type_node.analyse_as_type(env)
1648 if other_type is None:
1649 error(type_node.pos, "Not a type")
1650 elif (type is not PyrexTypes.py_object_type
1651 and not type.same_as(other_type)):
1652 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1653 error(type_node.pos, "Previous declaration here")
1656 if name_declarator and name_declarator.cname:
1658 "Python function argument cannot have C name specification")
1659 arg.type = type.as_argument_type()
1661 arg.needs_conversion = 0
1662 arg.needs_type_test = 0
1664 if arg.not_none and not arg.type.is_extension_type:
1666 "Only extension type arguments can have 'not None'")
1667 self.declare_pyfunction(env)
1668 self.analyse_signature(env)
1669 self.return_type = self.entry.signature.return_type()
1671 def analyse_signature(self, env):
1672 any_type_tests_needed = 0
1673 if self.entry.is_special:
1674 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1675 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
1676 # Use the simpler calling signature for zero- and one-argument functions.
1677 if self.entry.signature is TypeSlots.pyfunction_signature:
1678 if len(self.args) == 0:
1679 self.entry.signature = TypeSlots.pyfunction_noargs
1680 elif len(self.args) == 1:
1681 if self.args[0].default is None and not self.args[0].kw_only:
1682 self.entry.signature = TypeSlots.pyfunction_onearg
1683 elif self.entry.signature is TypeSlots.pymethod_signature:
1684 if len(self.args) == 1:
1685 self.entry.signature = TypeSlots.unaryfunc
1686 elif len(self.args) == 2:
1687 if self.args[1].default is None and not self.args[1].kw_only:
1688 self.entry.signature = TypeSlots.ibinaryfunc
1689 sig = self.entry.signature
1690 nfixed = sig.num_fixed_args()
1691 for i in range(nfixed):
1692 if i < len(self.args):
1695 if sig.is_self_arg(i):
1697 arg.hdr_type = arg.type = env.parent_type
1698 arg.needs_conversion = 0
1700 arg.hdr_type = sig.fixed_arg_type(i)
1701 if not arg.type.same_as(arg.hdr_type):
1702 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1703 arg.needs_type_test = 1
1704 any_type_tests_needed = 1
1706 arg.needs_conversion = 1
1707 if arg.needs_conversion:
1708 arg.hdr_cname = Naming.arg_prefix + arg.name
1710 arg.hdr_cname = Naming.var_prefix + arg.name
1712 self.bad_signature()
1714 if nfixed < len(self.args):
1715 if not sig.has_generic_args:
1716 self.bad_signature()
1717 for arg in self.args:
1718 if arg.is_generic and \
1719 (arg.type.is_extension_type or arg.type.is_builtin_type):
1720 arg.needs_type_test = 1
1721 any_type_tests_needed = 1
1722 if any_type_tests_needed:
1723 env.use_utility_code(arg_type_test_utility_code)
1725 def bad_signature(self):
1726 sig = self.entry.signature
1727 expected_str = "%d" % sig.num_fixed_args()
1728 if sig.has_generic_args:
1729 expected_str = expected_str + " or more"
1731 if name.startswith("__") and name.endswith("__"):
1732 desc = "Special method"
1736 "%s %s has wrong number of arguments "
1737 "(%d declared, %s expected)" % (
1738 desc, self.name, len(self.args), expected_str))
1740 def signature_has_nongeneric_args(self):
1741 argcount = len(self.args)
1742 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1746 def signature_has_generic_args(self):
1747 return self.entry.signature.has_generic_args
1749 def declare_pyfunction(self, env):
1750 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1752 entry = env.lookup_here(self.name)
1753 if entry and entry.type.is_cfunction and not self.is_wrapper:
1754 warning(self.pos, "Overriding cdef method with def method.", 5)
1755 entry = env.declare_pyfunction(self.name, self.pos)
1757 prefix = env.scope_prefix
1758 entry.func_cname = \
1759 Naming.pyfunc_prefix + prefix + name
1760 entry.pymethdef_cname = \
1761 Naming.pymethdef_prefix + prefix + name
1762 if Options.docstrings:
1763 entry.doc = embed_position(self.pos, self.doc)
1765 Naming.funcdoc_prefix + prefix + name
1769 def declare_arguments(self, env):
1770 for arg in self.args:
1772 error(arg.pos, "Missing argument name")
1773 if arg.needs_conversion:
1774 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1775 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1776 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1777 if arg.type.is_pyobject:
1778 arg.entry.init = "0"
1779 arg.entry.init_to_none = 0
1781 arg.entry = self.declare_argument(env, arg)
1783 arg.entry.is_self_arg = arg.is_self_arg
1785 if arg.is_self_arg or \
1786 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1787 arg.entry.is_declared_generic = 1
1788 self.declare_python_arg(env, self.star_arg)
1789 self.declare_python_arg(env, self.starstar_arg)
1791 def declare_python_arg(self, env, arg):
1793 entry = env.declare_var(arg.name,
1794 PyrexTypes.py_object_type, arg.pos)
1797 entry.init_to_none = 0
1798 entry.xdecref_cleanup = 1
1800 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1802 def analyse_expressions(self, env):
1803 self.local_scope.directives = env.directives
1804 self.analyse_default_values(env)
1805 if env.is_py_class_scope:
1806 self.synthesize_assignment_node(env)
1808 def synthesize_assignment_node(self, env):
1810 self.assmt = SingleAssignmentNode(self.pos,
1811 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1812 rhs = ExprNodes.UnboundMethodNode(self.pos,
1813 function = ExprNodes.PyCFunctionNode(self.pos,
1814 pymethdef_cname = self.entry.pymethdef_cname)))
1815 self.assmt.analyse_declarations(env)
1816 self.assmt.analyse_expressions(env)
1818 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1820 sig = self.entry.signature
1821 if sig.has_dummy_arg:
1822 arg_code_list.append(
1823 "PyObject *%s" % Naming.self_cname)
1824 for arg in self.args:
1825 if not arg.is_generic:
1827 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1829 arg_code_list.append(
1830 arg.hdr_type.declaration_code(arg.hdr_cname))
1831 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1832 arg_code_list.append("PyObject *unused")
1833 if sig.has_generic_args:
1834 arg_code_list.append(
1835 "PyObject *%s, PyObject *%s"
1836 % (Naming.args_cname, Naming.kwds_cname))
1837 arg_code = ", ".join(arg_code_list)
1838 dc = self.return_type.declaration_code(self.entry.func_cname)
1839 header = "static %s(%s)" % (dc, arg_code)
1840 code.putln("%s; /*proto*/" % header)
1843 if self.entry.doc and Options.docstrings:
1844 docstr = self.entry.doc
1845 if not isinstance(docstr, str):
1846 docstr = docstr.utf8encode()
1848 'static char %s[] = "%s";' % (
1849 self.entry.doc_cname,
1850 split_docstring(escape_byte_string(docstr))))
1853 "static PyMethodDef %s = " %
1854 self.entry.pymethdef_cname)
1855 code.put_pymethoddef(self.entry, ";")
1856 code.putln("%s {" % header)
1858 def generate_argument_declarations(self, env, code):
1859 for arg in self.args:
1860 if arg.is_generic: # or arg.needs_conversion:
1861 if arg.needs_conversion:
1862 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1864 code.put_var_declaration(arg.entry)
1866 def generate_keyword_list(self, code):
1867 if self.signature_has_generic_args() and \
1868 self.signature_has_nongeneric_args():
1870 "static PyObject **%s[] = {" %
1871 Naming.pykwdlist_cname)
1872 for arg in self.args:
1874 pystring_cname = code.intern_identifier(arg.name)
1875 code.put('&%s,' % pystring_cname)
1878 def generate_argument_parsing_code(self, env, code):
1879 # Generate PyArg_ParseTuple call for generic
1880 # arguments, if any.
1881 if self.entry.signature.has_dummy_arg:
1882 # get rid of unused argument warning
1883 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1885 old_error_label = code.new_error_label()
1886 our_error_label = code.error_label
1887 end_label = code.new_label("argument_unpacking_done")
1889 has_kwonly_args = self.num_kwonly_args > 0
1890 has_star_or_kw_args = self.star_arg is not None \
1891 or self.starstar_arg is not None or has_kwonly_args
1893 for arg in self.args:
1894 if not arg.type.is_pyobject and arg.type.from_py_function is None:
1895 arg.type.create_from_py_utility_code(env)
1897 if not self.signature_has_generic_args():
1898 if has_star_or_kw_args:
1899 error(self.pos, "This method cannot have * or keyword arguments")
1900 self.generate_argument_conversion_code(code)
1902 elif not self.signature_has_nongeneric_args():
1903 # func(*args) or func(**kw) or func(*args, **kw)
1904 self.generate_stararg_copy_code(code)
1907 positional_args = []
1910 for arg in self.args:
1911 arg_entry = arg.entry
1915 if not arg.is_self_arg:
1917 kw_only_args.append(arg)
1919 positional_args.append(arg)
1921 kw_only_args.append(arg)
1924 error(arg.pos, "Non-default argument following default argument")
1925 elif not arg.is_self_arg:
1926 positional_args.append(arg)
1928 self.generate_tuple_and_keyword_parsing_code(
1929 positional_args, kw_only_args, end_label, code)
1931 code.error_label = old_error_label
1932 if code.label_used(our_error_label):
1933 if not code.label_used(end_label):
1934 code.put_goto(end_label)
1935 code.put_label(our_error_label)
1936 if has_star_or_kw_args:
1937 self.generate_arg_decref(self.star_arg, code)
1938 if self.starstar_arg:
1939 if self.starstar_arg.entry.xdecref_cleanup:
1940 code.put_var_xdecref(self.starstar_arg.entry)
1942 code.put_var_decref(self.starstar_arg.entry)
1943 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1944 code.putln("return %s;" % self.error_value())
1945 if code.label_used(end_label):
1946 code.put_label(end_label)
1948 def generate_arg_assignment(self, arg, item, code):
1949 if arg.type.is_pyobject:
1951 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1952 code.putln("%s = %s;" % (arg.entry.cname, item))
1954 func = arg.type.from_py_function
1956 code.putln("%s = %s(%s); %s" % (
1960 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1962 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1964 def generate_arg_xdecref(self, arg, code):
1966 code.put_var_xdecref(arg.entry)
1968 def generate_arg_decref(self, arg, code):
1970 code.put_var_decref(arg.entry)
1972 def generate_stararg_copy_code(self, code):
1973 if not self.star_arg:
1974 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1975 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1977 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1978 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1981 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1983 if self.starstar_arg:
1985 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1987 kwarg_check = "%s" % Naming.kwds_cname
1989 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1990 Naming.kwds_cname, Naming.kwds_cname)
1992 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1993 kwarg_check, Naming.kwds_cname, self.name,
1994 bool(self.starstar_arg), self.error_value()))
1996 if self.starstar_arg:
1997 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1998 self.starstar_arg.entry.cname,
2001 code.putln("if (unlikely(!%s)) return %s;" % (
2002 self.starstar_arg.entry.cname, self.error_value()))
2003 self.starstar_arg.entry.xdecref_cleanup = 0
2004 code.put_gotref(self.starstar_arg.entry.cname)
2008 code.put_incref(Naming.args_cname, py_object_type)
2009 code.putln("%s = %s;" % (
2010 self.star_arg.entry.cname,
2012 self.star_arg.entry.xdecref_cleanup = 0
2014 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2015 kw_only_args, success_label, code):
2016 argtuple_error_label = code.new_label("argtuple_error")
2018 min_positional_args = self.num_required_args - self.num_required_kw_args
2019 if len(self.args) > 0 and self.args[0].is_self_arg:
2020 min_positional_args -= 1
2021 max_positional_args = len(positional_args)
2022 has_fixed_positional_count = not self.star_arg and \
2023 min_positional_args == max_positional_args
2025 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2026 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2027 if self.num_required_kw_args:
2028 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2030 if self.starstar_arg or self.star_arg:
2031 self.generate_stararg_init_code(max_positional_args, code)
2033 # --- optimised code when we receive keyword arguments
2034 if self.num_required_kw_args:
2035 likely_hint = "likely"
2037 likely_hint = "unlikely"
2038 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2039 self.generate_keyword_unpacking_code(
2040 min_positional_args, max_positional_args,
2041 has_fixed_positional_count,
2042 positional_args, kw_only_args, argtuple_error_label, code)
2044 # --- optimised code when we do not receive any keyword arguments
2045 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2046 # Python raises arg tuple related errors first, so we must
2047 # check the length here
2048 if min_positional_args == max_positional_args and not self.star_arg:
2052 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2053 Naming.args_cname, compare, min_positional_args))
2054 code.put_goto(argtuple_error_label)
2056 if self.num_required_kw_args:
2057 # pure error case: keywords required but not passed
2058 if max_positional_args > min_positional_args and not self.star_arg:
2059 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2060 Naming.args_cname, max_positional_args))
2061 code.put_goto(argtuple_error_label)
2062 code.putln('} else {')
2063 for i, arg in enumerate(kw_only_args):
2065 pystring_cname = code.intern_identifier(arg.name)
2066 # required keyword-only argument missing
2067 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2068 self.name.utf8encode(),
2070 code.putln(code.error_goto(self.pos))
2073 elif min_positional_args == max_positional_args:
2074 # parse the exact number of positional arguments from the
2076 code.putln('} else {')
2077 for i, arg in enumerate(positional_args):
2078 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2079 self.generate_arg_assignment(arg, item, code)
2080 self.generate_arg_default_assignments(code)
2083 # parse the positional arguments from the variable length
2085 code.putln('} else {')
2086 self.generate_arg_default_assignments(code)
2087 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2089 code.putln('default:')
2090 reversed_args = list(enumerate(positional_args))[::-1]
2091 for i, arg in reversed_args:
2092 if i >= min_positional_args-1:
2093 if min_positional_args > 1:
2094 code.putln('case %2d:' % (i+1)) # pure code beautification
2096 code.put('case %2d: ' % (i+1))
2097 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2098 self.generate_arg_assignment(arg, item, code)
2099 if min_positional_args == 0:
2100 code.put('case 0: ')
2101 code.putln('break;')
2103 if min_positional_args:
2104 for i in range(min_positional_args-1, -1, -1):
2105 code.putln('case %2d:' % i)
2106 code.put_goto(argtuple_error_label)
2108 code.put('default: ')
2109 code.put_goto(argtuple_error_label)
2114 if code.label_used(argtuple_error_label):
2115 code.put_goto(success_label)
2116 code.put_label(argtuple_error_label)
2117 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2118 self.name.utf8encode(), has_fixed_positional_count,
2119 min_positional_args, max_positional_args,
2121 code.putln(code.error_goto(self.pos))
2123 def generate_arg_default_assignments(self, code):
2124 for arg in self.args:
2125 if arg.is_generic and arg.default:
2129 arg.calculate_default_value_code(code)))
2131 def generate_stararg_init_code(self, max_positional_args, code):
2132 if self.starstar_arg:
2133 self.starstar_arg.entry.xdecref_cleanup = 0
2134 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2135 self.starstar_arg.entry.cname,
2136 self.starstar_arg.entry.cname,
2137 self.error_value()))
2138 code.put_gotref(self.starstar_arg.entry.cname)
2140 self.star_arg.entry.xdecref_cleanup = 0
2141 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2143 max_positional_args))
2144 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2145 self.star_arg.entry.cname, Naming.args_cname,
2146 max_positional_args, Naming.args_cname))
2147 code.put_gotref(self.star_arg.entry.cname)
2148 if self.starstar_arg:
2150 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2151 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2152 code.putln('return %s;' % self.error_value())
2155 code.putln("if (unlikely(!%s)) return %s;" % (
2156 self.star_arg.entry.cname, self.error_value()))
2157 code.putln('} else {')
2158 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2159 code.put_incref(Naming.empty_tuple, py_object_type)
2162 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2163 has_fixed_positional_count, positional_args,
2164 kw_only_args, argtuple_error_label, code):
2165 all_args = tuple(positional_args) + tuple(kw_only_args)
2166 max_args = len(all_args)
2169 for i, arg in enumerate(all_args):
2170 if arg.default and arg.type.is_pyobject:
2171 default_value = arg.calculate_default_value_code(code)
2172 if arg.type is not PyrexTypes.py_object_type:
2173 default_value = "(PyObject*)"+default_value
2174 default_args.append((i, default_value))
2176 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2178 # it looks funny to separate the init-to-0 from setting the
2179 # default value, but C89 needs this
2180 code.putln("PyObject* values[%d] = {%s};" % (
2181 max_args, ','.join(['0']*max_args)))
2182 for i, default_value in default_args:
2183 code.putln('values[%d] = %s;' % (i, default_value))
2185 # parse the tuple and check that it's not too long
2186 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2188 code.putln('default:')
2189 for i in range(max_positional_args-1, -1, -1):
2190 code.put('case %2d: ' % (i+1))
2191 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2192 i, Naming.args_cname, i))
2193 code.putln('case 0: break;')
2194 if not self.star_arg:
2195 code.put('default: ') # more arguments than allowed
2196 code.put_goto(argtuple_error_label)
2199 # now fill up the positional/required arguments with values
2201 if self.num_required_args or max_positional_args > 0:
2202 last_required_arg = -1
2203 for i, arg in enumerate(all_args):
2205 last_required_arg = i
2206 if last_required_arg < max_positional_args:
2207 last_required_arg = max_positional_args-1
2208 num_required_args = self.num_required_args
2209 if max_positional_args > 0:
2210 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2211 for i, arg in enumerate(all_args[:last_required_arg+1]):
2212 if max_positional_args > 0 and i <= max_positional_args:
2213 if self.star_arg and i == max_positional_args:
2214 code.putln('default:')
2216 code.putln('case %2d:' % i)
2217 pystring_cname = code.intern_identifier(arg.name)
2220 # handled separately below
2222 code.putln('if (kw_args > %d) {' % num_required_args)
2223 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2224 Naming.kwds_cname, pystring_cname))
2225 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2228 num_required_args -= 1
2229 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2230 i, Naming.kwds_cname, pystring_cname))
2231 code.putln('if (likely(values[%d])) kw_args--;' % i);
2232 if i < min_positional_args:
2234 # special case: we know arg 0 is missing
2236 code.put_goto(argtuple_error_label)
2238 # print the correct number of values (args or
2239 # kwargs) that were passed into positional
2240 # arguments up to this point
2241 code.putln('else {')
2242 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2243 self.name.utf8encode(), has_fixed_positional_count,
2244 min_positional_args, max_positional_args, i))
2245 code.putln(code.error_goto(self.pos))
2248 code.putln('else {')
2249 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2250 self.name.utf8encode(), pystring_cname))
2251 code.putln(code.error_goto(self.pos))
2253 if max_positional_args > 0:
2256 if kw_only_args and not self.starstar_arg:
2257 # unpack optional keyword-only arguments
2258 # checking for interned strings in a dict is faster than iterating
2259 # but it's too likely that we must iterate if we expect **kwargs
2261 for i, arg in enumerate(all_args[max_positional_args:]):
2262 if not arg.kw_only or not arg.default:
2264 optional_args.append((i+max_positional_args, arg))
2266 # this mimics an unrolled loop so that we can "break" out of it
2267 code.putln('while (kw_args > 0) {')
2268 code.putln('PyObject* value;')
2269 for i, arg in optional_args:
2270 pystring_cname = code.intern_identifier(arg.name)
2272 'value = PyDict_GetItem(%s, %s);' % (
2273 Naming.kwds_cname, pystring_cname))
2275 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2276 code.putln('break;')
2279 code.putln('if (unlikely(kw_args > 0)) {')
2280 # non-positional/-required kw args left in dict: default args,
2281 # kw-only args, **kwargs or error
2283 # This is sort of a catch-all: except for checking required
2284 # arguments, this will always do the right thing for unpacking
2285 # keyword arguments, so that we can concentrate on optimising
2286 # common cases above.
2287 if max_positional_args == 0:
2290 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2291 Naming.args_cname, max_positional_args,
2292 Naming.args_cname, max_positional_args))
2293 pos_arg_count = "used_pos_args"
2295 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2296 code.globalstate.use_utility_code(parse_keywords_utility_code)
2298 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2300 Naming.pykwdlist_cname,
2301 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2303 self.name.utf8encode()))
2304 code.putln(code.error_goto(self.pos))
2307 # convert arg values to their final type and assign them
2308 for i, arg in enumerate(all_args):
2309 if arg.default and not arg.type.is_pyobject:
2310 code.putln("if (values[%d]) {" % i)
2311 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2312 if arg.default and not arg.type.is_pyobject:
2313 code.putln('} else {')
2317 arg.calculate_default_value_code(code)))
2320 def generate_argument_conversion_code(self, code):
2321 # Generate code to convert arguments from
2322 # signature type to declared type, if needed.
2323 for arg in self.args:
2324 if arg.needs_conversion:
2325 self.generate_arg_conversion(arg, code)
2327 def generate_arg_conversion(self, arg, code):
2328 # Generate conversion code for one argument.
2329 old_type = arg.hdr_type
2331 if old_type.is_pyobject:
2333 code.putln("if (%s) {" % arg.hdr_cname)
2335 code.putln("assert(%s); {" % arg.hdr_cname)
2336 self.generate_arg_conversion_from_pyobject(arg, code)
2338 elif new_type.is_pyobject:
2339 self.generate_arg_conversion_to_pyobject(arg, code)
2341 if new_type.assignable_from(old_type):
2343 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2346 "Cannot convert 1 argument from '%s' to '%s'" %
2347 (old_type, new_type))
2349 def generate_arg_conversion_from_pyobject(self, arg, code):
2351 func = new_type.from_py_function
2352 # copied from CoerceFromPyTypeNode
2354 code.putln("%s = %s(%s); %s" % (
2358 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2361 "Cannot convert Python object argument to type '%s'"
2364 def generate_arg_conversion_to_pyobject(self, arg, code):
2365 old_type = arg.hdr_type
2366 func = old_type.to_py_function
2368 code.putln("%s = %s(%s); %s" % (
2372 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2373 code.put_var_gotref(arg.entry)
2376 "Cannot convert argument of type '%s' to Python object"
2379 def generate_argument_type_tests(self, code):
2380 # Generate type tests for args whose signature
2381 # type is PyObject * and whose declared type is
2382 # a subtype thereof.
2383 for arg in self.args:
2384 if arg.needs_type_test:
2385 self.generate_arg_type_test(arg, code)
2387 def generate_arg_type_test(self, arg, code):
2388 # Generate type test for one argument.
2389 if arg.type.typeobj_is_available():
2390 typeptr_cname = arg.type.typeptr_cname
2391 arg_code = "((PyObject *)%s)" % arg.entry.cname
2393 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2398 arg.type.is_builtin_type,
2399 code.error_goto(arg.pos)))
2401 error(arg.pos, "Cannot test type of extern C class "
2402 "without type object name specification")
2404 def error_value(self):
2405 return self.entry.signature.error_value
2407 def caller_will_check_exceptions(self):
2410 class OverrideCheckNode(StatNode):
2411 # A Node for dispatching to the def method if it
2420 child_attrs = ['body']
2424 def analyse_expressions(self, env):
2425 self.args = env.arg_entries
2426 if self.py_func.is_module_scope:
2431 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2432 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2433 call_node = ExprNodes.SimpleCallNode(self.pos,
2434 function=self.func_node,
2435 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2436 self.body = ReturnStatNode(self.pos, value=call_node)
2437 self.body.analyse_expressions(env)
2439 def generate_execution_code(self, code):
2440 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2441 # Check to see if we are an extension type
2442 if self.py_func.is_module_scope:
2443 self_arg = "((PyObject *)%s)" % Naming.module_cname
2445 self_arg = "((PyObject *)%s)" % self.args[0].cname
2446 code.putln("/* Check if called by wrapper */")
2447 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2448 code.putln("/* Check if overriden in Python */")
2449 if self.py_func.is_module_scope:
2450 code.putln("else {")
2452 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2453 self.func_node.allocate(code)
2454 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2455 # need to get attribute manually--scope would return cdef method
2456 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2457 self.func_node.result(), self_arg, interned_attr_cname, err))
2458 code.put_gotref(self.func_node.py_result())
2459 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2460 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2461 self.func_node.result(), self.py_func.entry.func_cname)
2462 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2463 self.body.generate_execution_code(code)
2465 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2467 self.func_node.release(code)
2469 class ClassDefNode(StatNode, BlockNode):
2472 class PyClassDefNode(ClassDefNode):
2473 # A Python class definition.
2475 # name EncodedString Name of the class
2476 # doc string or None
2477 # body StatNode Attribute definition code
2478 # entry Symtab.Entry
2479 # scope PyClassScope
2480 # decorators [DecoratorNode] list of decorators or None
2482 # The following subnodes are constructed internally:
2484 # dict DictNode Class dictionary
2485 # classobj ClassNode Class object
2486 # target NameNode Variable to assign class object to
2488 child_attrs = ["body", "dict", "classobj", "target"]
2491 def __init__(self, pos, name, bases, doc, body, decorators = None):
2492 StatNode.__init__(self, pos)
2496 self.decorators = decorators
2498 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2499 if self.doc and Options.docstrings:
2500 doc = embed_position(self.pos, self.doc)
2501 doc_node = ExprNodes.StringNode(pos, value = doc)
2504 self.classobj = ExprNodes.ClassNode(pos, name = name,
2505 bases = bases, dict = self.dict, doc = doc_node)
2506 self.target = ExprNodes.NameNode(pos, name = name)
2508 def as_cclass(self):
2510 Return this node as if it were declared as an extension class
2512 bases = self.classobj.bases.args
2514 base_class_name = None
2515 base_class_module = None
2516 elif len(bases) == 1:
2519 from ExprNodes import AttributeNode, NameNode
2520 while isinstance(base, AttributeNode):
2521 path.insert(0, base.attribute)
2523 if isinstance(base, NameNode):
2524 path.insert(0, base.name)
2525 base_class_name = path[-1]
2527 base_class_module = u'.'.join(path[:-1])
2529 base_class_module = None
2531 error(self.classobj.bases.args.pos, "Invalid base class")
2533 error(self.classobj.bases.args.pos, "C class may only have one base class")
2536 return CClassDefNode(self.pos,
2537 visibility = 'private',
2539 class_name = self.name,
2540 base_class_module = base_class_module,
2541 base_class_name = base_class_name,
2542 decorators = self.decorators,
2547 def create_scope(self, env):
2549 while env.is_py_class_scope or env.is_c_class_scope:
2550 env = env.outer_scope
2551 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2554 def analyse_declarations(self, env):
2555 self.target.analyse_target_declaration(env)
2556 cenv = self.create_scope(env)
2557 cenv.directives = env.directives
2558 cenv.class_obj_cname = self.target.entry.cname
2559 self.body.analyse_declarations(cenv)
2561 def analyse_expressions(self, env):
2562 self.dict.analyse_expressions(env)
2563 self.classobj.analyse_expressions(env)
2564 genv = env.global_scope()
2566 self.body.analyse_expressions(cenv)
2567 self.target.analyse_target_expression(env, self.classobj)
2569 def generate_function_definitions(self, env, code):
2570 self.body.generate_function_definitions(self.scope, code)
2572 def generate_execution_code(self, code):
2573 code.pyclass_stack.append(self)
2575 self.dict.generate_evaluation_code(code)
2576 self.classobj.generate_evaluation_code(code)
2577 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2578 self.body.generate_execution_code(code)
2579 self.target.generate_assignment_code(self.classobj, code)
2580 self.dict.generate_disposal_code(code)
2581 self.dict.free_temps(code)
2582 code.pyclass_stack.pop()
2585 class CClassDefNode(ClassDefNode):
2586 # An extension type definition.
2588 # visibility 'private' or 'public' or 'extern'
2589 # typedef_flag boolean
2591 # module_name string or None For import of extern type objects
2592 # class_name string Unqualified name of class
2593 # as_name string or None Name to declare as in this scope
2594 # base_class_module string or None Module containing the base class
2595 # base_class_name string or None Name of the base class
2596 # objstruct_name string or None Specified C name of object struct
2597 # typeobj_name string or None Specified C name of type object
2598 # in_pxd boolean Is in a .pxd file
2599 # decorators [DecoratorNode] list of decorators or None
2600 # doc string or None
2601 # body StatNode or None
2602 # entry Symtab.Entry
2603 # base_type PyExtensionType or None
2604 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2605 # buffer_defaults_pos
2607 child_attrs = ["body"]
2608 buffer_defaults_node = None
2609 buffer_defaults_pos = None
2610 typedef_flag = False
2612 objstruct_name = None
2616 def analyse_declarations(self, env):
2617 #print "CClassDefNode.analyse_declarations:", self.class_name
2618 #print "...visibility =", self.visibility
2619 #print "...module_name =", self.module_name
2622 if self.buffer_defaults_node:
2623 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2624 env, [], self.buffer_defaults_node,
2625 need_complete=False)
2627 buffer_defaults = None
2629 if env.in_cinclude and not self.objstruct_name:
2630 error(self.pos, "Object struct name specification required for "
2631 "C class defined in 'extern from' block")
2632 self.base_type = None
2633 # Now that module imports are cached, we need to
2634 # import the modules for extern classes.
2635 if self.module_name:
2637 for module in env.cimported_modules:
2638 if module.name == self.module_name:
2639 self.module = module
2640 if self.module is None:
2641 self.module = ModuleScope(self.module_name, None, env.context)
2642 self.module.has_extern_class = 1
2643 env.add_imported_module(self.module)
2645 if self.base_class_name:
2646 if self.base_class_module:
2647 base_class_scope = env.find_module(self.base_class_module, self.pos)
2649 base_class_scope = env
2650 if self.base_class_name == 'object':
2651 # extension classes are special and don't need to inherit from object
2652 if base_class_scope is None or base_class_scope.lookup('object') is None:
2653 self.base_class_name = None
2654 self.base_class_module = None
2655 base_class_scope = None
2656 if base_class_scope:
2657 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2658 if base_class_entry:
2659 if not base_class_entry.is_type:
2660 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2661 elif not base_class_entry.type.is_extension_type:
2662 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2663 elif not base_class_entry.type.is_complete():
2664 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2666 self.base_type = base_class_entry.type
2667 has_body = self.body is not None
2668 if self.module_name and self.visibility != 'extern':
2669 module_path = self.module_name.split(".")
2670 home_scope = env.find_imported_module(module_path, self.pos)
2676 if self.visibility == 'extern':
2677 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2678 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2680 self.entry = home_scope.declare_c_class(
2681 name = self.class_name,
2683 defining = has_body and self.in_pxd,
2684 implementing = has_body and not self.in_pxd,
2685 module_name = self.module_name,
2686 base_type = self.base_type,
2687 objstruct_cname = self.objstruct_name,
2688 typeobj_cname = self.typeobj_name,
2689 visibility = self.visibility,
2690 typedef_flag = self.typedef_flag,
2692 buffer_defaults = buffer_defaults)
2693 if home_scope is not env and self.visibility == 'extern':
2694 env.add_imported_entry(self.class_name, self.entry, pos)
2695 scope = self.entry.type.scope
2696 if scope is not None:
2697 scope.directives = env.directives
2699 if self.doc and Options.docstrings:
2700 scope.doc = embed_position(self.pos, self.doc)
2703 self.body.analyse_declarations(scope)
2707 scope.implemented = 1
2708 env.allocate_vtable_names(self.entry)
2710 def analyse_expressions(self, env):
2712 scope = self.entry.type.scope
2713 self.body.analyse_expressions(scope)
2715 def generate_function_definitions(self, env, code):
2717 self.body.generate_function_definitions(
2718 self.entry.type.scope, code)
2720 def generate_execution_code(self, code):
2721 # This is needed to generate evaluation code for
2722 # default values of method arguments.
2724 self.body.generate_execution_code(code)
2726 def annotate(self, code):
2728 self.body.annotate(code)
2731 class PropertyNode(StatNode):
2732 # Definition of a property in an extension type.
2735 # doc EncodedString or None Doc string
2738 child_attrs = ["body"]
2740 def analyse_declarations(self, env):
2741 entry = env.declare_property(self.name, self.doc, self.pos)
2743 entry.scope.directives = env.directives
2744 self.body.analyse_declarations(entry.scope)
2746 def analyse_expressions(self, env):
2747 self.body.analyse_expressions(env)
2749 def generate_function_definitions(self, env, code):
2750 self.body.generate_function_definitions(env, code)
2752 def generate_execution_code(self, code):
2755 def annotate(self, code):
2756 self.body.annotate(code)
2759 class GlobalNode(StatNode):
2760 # Global variable declaration.
2766 def analyse_declarations(self, env):
2767 for name in self.names:
2768 env.declare_global(name, self.pos)
2770 def analyse_expressions(self, env):
2773 def generate_execution_code(self, code):
2777 class ExprStatNode(StatNode):
2778 # Expression used as a statement.
2782 child_attrs = ["expr"]
2784 def analyse_declarations(self, env):
2786 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2787 func = self.expr.function.as_cython_attribute()
2788 if func == u'declare':
2789 args, kwds = self.expr.explicit_args_kwds()
2791 error(self.expr.pos, "Variable names must be specified.")
2792 for var, type_node in kwds.key_value_pairs:
2793 type = type_node.analyse_as_type(env)
2795 error(type_node.pos, "Unknown type")
2797 env.declare_var(var.value, type, var.pos, is_cdef = True)
2798 self.__class__ = PassStatNode
2800 def analyse_expressions(self, env):
2801 self.expr.analyse_expressions(env)
2803 def generate_execution_code(self, code):
2804 self.expr.generate_evaluation_code(code)
2805 if not self.expr.is_temp and self.expr.result():
2806 code.putln("%s;" % self.expr.result())
2807 self.expr.generate_disposal_code(code)
2808 self.expr.free_temps(code)
2810 def annotate(self, code):
2811 self.expr.annotate(code)
2814 class AssignmentNode(StatNode):
2815 # Abstract base class for assignment nodes.
2817 # The analyse_expressions and generate_execution_code
2818 # phases of assignments are split into two sub-phases
2819 # each, to enable all the right hand sides of a
2820 # parallel assignment to be evaluated before assigning
2821 # to any of the left hand sides.
2823 def analyse_expressions(self, env):
2824 self.analyse_types(env)
2826 # def analyse_expressions(self, env):
2827 # self.analyse_expressions_1(env)
2828 # self.analyse_expressions_2(env)
2830 def generate_execution_code(self, code):
2831 self.generate_rhs_evaluation_code(code)
2832 self.generate_assignment_code(code)
2835 class SingleAssignmentNode(AssignmentNode):
2836 # The simplest case:
2840 # lhs ExprNode Left hand side
2841 # rhs ExprNode Right hand side
2842 # first bool Is this guaranteed the first assignment to lhs?
2844 child_attrs = ["lhs", "rhs"]
2846 declaration_only = False
2848 def analyse_declarations(self, env):
2851 # handle declarations of the form x = cython.foo()
2852 if isinstance(self.rhs, ExprNodes.CallNode):
2853 func_name = self.rhs.function.as_cython_attribute()
2855 args, kwds = self.rhs.explicit_args_kwds()
2857 if func_name in ['declare', 'typedef']:
2858 if len(args) > 2 or kwds is not None:
2859 error(rhs.pos, "Can only declare one type at a time.")
2861 type = args[0].analyse_as_type(env)
2863 error(args[0].pos, "Unknown type")
2866 if func_name == 'declare':
2867 if isinstance(lhs, ExprNodes.NameNode):
2868 vars = [(lhs.name, lhs.pos)]
2869 elif isinstance(lhs, ExprNodes.TupleNode):
2870 vars = [(var.name, var.pos) for var in lhs.args]
2872 error(lhs.pos, "Invalid declaration")
2874 for var, pos in vars:
2875 env.declare_var(var, type, pos, is_cdef = True)
2880 self.declaration_only = True
2882 self.declaration_only = True
2883 if not isinstance(lhs, ExprNodes.NameNode):
2884 error(lhs.pos, "Invalid declaration.")
2885 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2887 elif func_name in ['struct', 'union']:
2888 self.declaration_only = True
2889 if len(args) > 0 or kwds is None:
2890 error(rhs.pos, "Struct or union members must be given by name.")
2893 for member, type_node in kwds.key_value_pairs:
2894 type = type_node.analyse_as_type(env)
2896 error(type_node.pos, "Unknown type")
2898 members.append((member.value, type, member.pos))
2899 if len(members) < len(kwds.key_value_pairs):
2901 if not isinstance(self.lhs, ExprNodes.NameNode):
2902 error(self.lhs.pos, "Invalid declaration.")
2903 name = self.lhs.name
2904 scope = StructOrUnionScope(name)
2905 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2906 for member, type, pos in members:
2907 scope.declare_var(member, type, pos)
2909 if self.declaration_only:
2912 self.lhs.analyse_target_declaration(env)
2914 def analyse_types(self, env, use_temp = 0):
2915 self.rhs.analyse_types(env)
2916 self.lhs.analyse_target_types(env)
2917 self.lhs.gil_assignment_check(env)
2918 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2920 self.rhs = self.rhs.coerce_to_temp(env)
2922 def generate_rhs_evaluation_code(self, code):
2923 self.rhs.generate_evaluation_code(code)
2925 def generate_assignment_code(self, code):
2926 self.lhs.generate_assignment_code(self.rhs, code)
2928 def annotate(self, code):
2929 self.lhs.annotate(code)
2930 self.rhs.annotate(code)
2933 class CascadedAssignmentNode(AssignmentNode):
2934 # An assignment with multiple left hand sides:
2938 # lhs_list [ExprNode] Left hand sides
2939 # rhs ExprNode Right hand sides
2943 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2945 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2946 coerced_rhs_list = None
2948 def analyse_declarations(self, env):
2949 for lhs in self.lhs_list:
2950 lhs.analyse_target_declaration(env)
2952 def analyse_types(self, env, use_temp = 0):
2953 self.rhs.analyse_types(env)
2955 self.rhs = self.rhs.coerce_to_temp(env)
2957 self.rhs = self.rhs.coerce_to_simple(env)
2958 from ExprNodes import CloneNode
2959 self.coerced_rhs_list = []
2960 for lhs in self.lhs_list:
2961 lhs.analyse_target_types(env)
2962 lhs.gil_assignment_check(env)
2963 rhs = CloneNode(self.rhs)
2964 rhs = rhs.coerce_to(lhs.type, env)
2965 self.coerced_rhs_list.append(rhs)
2967 def generate_rhs_evaluation_code(self, code):
2968 self.rhs.generate_evaluation_code(code)
2970 def generate_assignment_code(self, code):
2971 for i in range(len(self.lhs_list)):
2972 lhs = self.lhs_list[i]
2973 rhs = self.coerced_rhs_list[i]
2974 rhs.generate_evaluation_code(code)
2975 lhs.generate_assignment_code(rhs, code)
2976 # Assignment has disposed of the cloned RHS
2977 self.rhs.generate_disposal_code(code)
2978 self.rhs.free_temps(code)
2980 def annotate(self, code):
2981 for i in range(len(self.lhs_list)):
2982 lhs = self.lhs_list[i].annotate(code)
2983 rhs = self.coerced_rhs_list[i].annotate(code)
2984 self.rhs.annotate(code)
2987 class ParallelAssignmentNode(AssignmentNode):
2988 # A combined packing/unpacking assignment:
2992 # This has been rearranged by the parser into
2994 # a = d ; b = e ; c = f
2996 # but we must evaluate all the right hand sides
2997 # before assigning to any of the left hand sides.
2999 # stats [AssignmentNode] The constituent assignments
3001 child_attrs = ["stats"]
3003 def analyse_declarations(self, env):
3004 for stat in self.stats:
3005 stat.analyse_declarations(env)
3007 def analyse_expressions(self, env):
3008 for stat in self.stats:
3009 stat.analyse_types(env, use_temp = 1)
3011 # def analyse_expressions(self, env):
3012 # for stat in self.stats:
3013 # stat.analyse_expressions_1(env, use_temp = 1)
3014 # for stat in self.stats:
3015 # stat.analyse_expressions_2(env)
3017 def generate_execution_code(self, code):
3018 for stat in self.stats:
3019 stat.generate_rhs_evaluation_code(code)
3020 for stat in self.stats:
3021 stat.generate_assignment_code(code)
3023 def annotate(self, code):
3024 for stat in self.stats:
3028 class InPlaceAssignmentNode(AssignmentNode):
3029 # An in place arithmatic operand:
3035 # lhs ExprNode Left hand side
3036 # rhs ExprNode Right hand side
3037 # op char one of "+-*/%^&|"
3038 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3040 # This code is a bit tricky because in order to obey Python
3041 # semantics the sub-expressions (e.g. indices) of the lhs must
3042 # not be evaluated twice. So we must re-use the values calculated
3043 # in evaluation phase for the assignment phase as well.
3044 # Fortunately, the type of the lhs node is fairly constrained
3045 # (it must be a NameNode, AttributeNode, or IndexNode).
3047 child_attrs = ["lhs", "rhs"]
3050 def analyse_declarations(self, env):
3051 self.lhs.analyse_target_declaration(env)
3053 def analyse_types(self, env):
3054 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3055 self.rhs.analyse_types(env)
3056 self.lhs.analyse_target_types(env)
3057 if Options.incref_local_binop and self.dup.type.is_pyobject:
3058 self.dup = self.dup.coerce_to_temp(env)
3060 if self.lhs.type.is_pyobject:
3061 self.rhs = self.rhs.coerce_to_pyobject(env)
3062 elif self.rhs.type.is_pyobject:
3063 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3064 if self.lhs.type.is_pyobject:
3065 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3066 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3068 def generate_execution_code(self, code):
3070 self.rhs.generate_evaluation_code(code)
3071 self.dup.generate_subexpr_evaluation_code(code)
3072 if self.dup.is_temp:
3073 self.dup.allocate_temp_result(code)
3074 # self.dup.generate_result_code is run only if it is not buffer access
3075 if self.operator == "**":
3079 if self.lhs.type.is_pyobject:
3080 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3081 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3082 self.dup.generate_result_code(code)
3083 self.result_value_temp.allocate(code)
3085 "%s = %s(%s, %s%s); %s" % (
3086 self.result_value.result(),
3087 self.py_operation_function(),
3088 self.dup.py_result(),
3089 self.rhs.py_result(),
3091 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3092 code.put_gotref(self.result_value.py_result())
3093 self.result_value.generate_evaluation_code(code) # May be a type check...
3094 self.rhs.generate_disposal_code(code)
3095 self.rhs.free_temps(code)
3096 self.dup.generate_disposal_code(code)
3097 self.dup.free_temps(code)
3098 self.lhs.generate_assignment_code(self.result_value, code)
3099 self.result_value_temp.release(code)
3101 c_op = self.operator
3105 error(self.pos, "No C inplace power operator")
3106 elif self.lhs.type.is_complex and not code.globalstate.directives['c99_complex']:
3107 error(self.pos, "Inplace operators not implemented for complex types.")
3109 # have to do assignment directly to avoid side-effects
3110 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3111 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3113 self.dup.generate_result_code(code)
3114 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3115 self.rhs.generate_disposal_code(code)
3116 self.rhs.free_temps(code)
3117 if self.dup.is_temp:
3118 self.dup.generate_subexpr_disposal_code(code)
3119 self.dup.free_subexpr_temps(code)
3121 def create_dup_node(self, env):
3124 self.dup.analyse_types(env)
3125 if isinstance(self.lhs, ExprNodes.NameNode):
3126 target_lhs = ExprNodes.NameNode(self.dup.pos,
3127 name = self.dup.name,
3128 is_temp = self.dup.is_temp,
3129 entry = self.dup.entry)
3130 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3131 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3132 obj = ExprNodes.CloneNode(self.lhs.obj),
3133 attribute = self.dup.attribute,
3134 is_temp = self.dup.is_temp)
3135 elif isinstance(self.lhs, ExprNodes.IndexNode):
3137 index = ExprNodes.CloneNode(self.lhs.index)
3140 if self.lhs.indices:
3141 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3144 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3145 base = ExprNodes.CloneNode(self.dup.base),
3148 is_temp = self.dup.is_temp)
3151 self.lhs = target_lhs
3154 def py_operation_function(self):
3155 return self.py_functions[self.operator]
3158 "|": "PyNumber_InPlaceOr",
3159 "^": "PyNumber_InPlaceXor",
3160 "&": "PyNumber_InPlaceAnd",
3161 "+": "PyNumber_InPlaceAdd",
3162 "-": "PyNumber_InPlaceSubtract",
3163 "*": "PyNumber_InPlaceMultiply",
3164 "/": "PyNumber_InPlaceDivide",
3165 "%": "PyNumber_InPlaceRemainder",
3166 "<<": "PyNumber_InPlaceLshift",
3167 ">>": "PyNumber_InPlaceRshift",
3168 "**": "PyNumber_InPlacePower",
3169 "//": "PyNumber_InPlaceFloorDivide",
3172 def annotate(self, code):
3173 self.lhs.annotate(code)
3174 self.rhs.annotate(code)
3175 self.dup.annotate(code)
3178 class PrintStatNode(StatNode):
3181 # arg_tuple TupleNode
3182 # append_newline boolean
3184 child_attrs = ["arg_tuple"]
3186 def analyse_expressions(self, env):
3187 self.arg_tuple.analyse_expressions(env)
3188 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3189 env.use_utility_code(printing_utility_code)
3190 if len(self.arg_tuple.args) == 1 and self.append_newline:
3191 env.use_utility_code(printing_one_utility_code)
3193 gil_check = StatNode._gil_check
3194 gil_message = "Python print statement"
3196 def generate_execution_code(self, code):
3197 if len(self.arg_tuple.args) == 1 and self.append_newline:
3198 arg = self.arg_tuple.args[0]
3199 arg.generate_evaluation_code(code)
3202 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3204 code.error_goto(self.pos)))
3205 arg.generate_disposal_code(code)
3206 arg.free_temps(code)
3208 self.arg_tuple.generate_evaluation_code(code)
3210 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3211 self.arg_tuple.py_result(),
3212 self.append_newline,
3213 code.error_goto(self.pos)))
3214 self.arg_tuple.generate_disposal_code(code)
3215 self.arg_tuple.free_temps(code)
3217 def annotate(self, code):
3218 self.arg_tuple.annotate(code)
3221 class ExecStatNode(StatNode):
3226 child_attrs = ["args"]
3228 def analyse_expressions(self, env):
3229 for i, arg in enumerate(self.args):
3230 arg.analyse_expressions(env)
3231 arg = arg.coerce_to_pyobject(env)
3233 env.use_utility_code(Builtin.pyexec_utility_code)
3235 gil_check = StatNode._gil_check
3236 gil_message = "Python exec statement"
3238 def generate_execution_code(self, code):
3240 for arg in self.args:
3241 arg.generate_evaluation_code(code)
3242 args.append( arg.py_result() )
3243 args = tuple(args + ['0', '0'][:3-len(args)])
3244 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3245 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3246 (temp_result,) + args))
3247 for arg in self.args:
3248 arg.generate_disposal_code(code)
3249 arg.free_temps(code)
3251 code.error_goto_if_null(temp_result, self.pos))
3252 code.put_gotref(temp_result)
3253 code.put_decref_clear(temp_result, py_object_type)
3254 code.funcstate.release_temp(temp_result)
3256 def annotate(self, code):
3257 for arg in self.args:
3261 class DelStatNode(StatNode):
3266 child_attrs = ["args"]
3268 def analyse_declarations(self, env):
3269 for arg in self.args:
3270 arg.analyse_target_declaration(env)
3272 def analyse_expressions(self, env):
3273 for arg in self.args:
3274 arg.analyse_target_expression(env, None)
3275 if not arg.type.is_pyobject:
3276 error(arg.pos, "Deletion of non-Python object")
3277 #arg.release_target_temp(env)
3279 def gil_check(self, env):
3280 for arg in self.args:
3281 if arg.type.is_pyobject:
3282 self._gil_check(env)
3284 gil_message = "Deleting Python object"
3286 def generate_execution_code(self, code):
3287 for arg in self.args:
3288 if arg.type.is_pyobject:
3289 arg.generate_deletion_code(code)
3290 # else error reported earlier
3292 def annotate(self, code):
3293 for arg in self.args:
3297 class PassStatNode(StatNode):
3302 def analyse_expressions(self, env):
3305 def generate_execution_code(self, code):
3309 class BreakStatNode(StatNode):
3313 def analyse_expressions(self, env):
3316 def generate_execution_code(self, code):
3317 if not code.break_label:
3318 error(self.pos, "break statement not inside loop")
3320 code.put_goto(code.break_label)
3323 class ContinueStatNode(StatNode):
3327 def analyse_expressions(self, env):
3330 def generate_execution_code(self, code):
3331 if code.funcstate.in_try_finally:
3332 error(self.pos, "continue statement inside try of try...finally")
3333 elif not code.continue_label:
3334 error(self.pos, "continue statement not inside loop")
3336 code.put_goto(code.continue_label)
3339 class ReturnStatNode(StatNode):
3342 # value ExprNode or None
3343 # return_type PyrexType
3345 child_attrs = ["value"]
3347 def analyse_expressions(self, env):
3348 return_type = env.return_type
3349 self.return_type = return_type
3351 error(self.pos, "Return not inside a function body")
3354 self.value.analyse_types(env)
3355 if return_type.is_void or return_type.is_returncode:
3356 error(self.value.pos,
3357 "Return with value in void function")
3359 self.value = self.value.coerce_to(env.return_type, env)
3361 if (not return_type.is_void
3362 and not return_type.is_pyobject
3363 and not return_type.is_returncode):
3364 error(self.pos, "Return value required")
3366 def gil_check(self, env):
3367 if self.return_type.is_pyobject:
3368 self._gil_check(env)
3370 gil_message = "Returning Python object"
3372 def generate_execution_code(self, code):
3373 code.mark_pos(self.pos)
3374 if not self.return_type:
3375 # error reported earlier
3377 if self.return_type.is_pyobject:
3378 code.put_xdecref(Naming.retval_cname,
3381 self.value.generate_evaluation_code(code)
3382 self.value.make_owned_reference(code)
3385 Naming.retval_cname,
3386 self.value.result_as(self.return_type)))
3387 self.value.generate_post_assignment_code(code)
3388 self.value.free_temps(code)
3390 if self.return_type.is_pyobject:
3391 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3392 elif self.return_type.is_returncode:
3395 Naming.retval_cname,
3396 self.return_type.default_value))
3397 for cname, type in code.funcstate.temps_holding_reference():
3398 code.put_decref_clear(cname, type)
3399 code.put_goto(code.return_label)
3401 def annotate(self, code):
3403 self.value.annotate(code)
3406 class RaiseStatNode(StatNode):
3409 # exc_type ExprNode or None
3410 # exc_value ExprNode or None
3411 # exc_tb ExprNode or None
3413 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3415 def analyse_expressions(self, env):
3417 self.exc_type.analyse_types(env)
3418 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3420 self.exc_value.analyse_types(env)
3421 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3423 self.exc_tb.analyse_types(env)
3424 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3425 env.use_utility_code(raise_utility_code)
3426 env.use_utility_code(restore_exception_utility_code)
3428 gil_check = StatNode._gil_check
3429 gil_message = "Raising exception"
3431 def generate_execution_code(self, code):
3433 self.exc_type.generate_evaluation_code(code)
3434 type_code = self.exc_type.py_result()
3438 self.exc_value.generate_evaluation_code(code)
3439 value_code = self.exc_value.py_result()
3443 self.exc_tb.generate_evaluation_code(code)
3444 tb_code = self.exc_tb.py_result()
3447 if self.exc_type or self.exc_value or self.exc_tb:
3449 "__Pyx_Raise(%s, %s, %s);" % (
3456 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3458 obj.generate_disposal_code(code)
3459 obj.free_temps(code)
3461 code.error_goto(self.pos))
3463 def annotate(self, code):
3465 self.exc_type.annotate(code)
3467 self.exc_value.annotate(code)
3469 self.exc_tb.annotate(code)
3472 class ReraiseStatNode(StatNode):
3476 def analyse_expressions(self, env):
3477 env.use_utility_code(raise_utility_code)
3478 env.use_utility_code(restore_exception_utility_code)
3480 gil_check = StatNode._gil_check
3481 gil_message = "Raising exception"
3483 def generate_execution_code(self, code):
3484 vars = code.funcstate.exc_vars
3486 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3487 code.putln(code.error_goto(self.pos))
3489 error(self.pos, "Reraise not inside except clause")
3492 class AssertStatNode(StatNode):
3496 # value ExprNode or None
3498 child_attrs = ["cond", "value"]
3500 def analyse_expressions(self, env):
3501 self.cond = self.cond.analyse_boolean_expression(env)
3503 self.value.analyse_types(env)
3504 self.value = self.value.coerce_to_pyobject(env)
3506 gil_check = StatNode._gil_check
3507 gil_message = "Raising exception"
3509 def generate_execution_code(self, code):
3510 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3511 self.cond.generate_evaluation_code(code)
3513 "if (unlikely(!%s)) {" %
3516 self.value.generate_evaluation_code(code)
3518 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3519 self.value.py_result())
3520 self.value.generate_disposal_code(code)
3521 self.value.free_temps(code)
3524 "PyErr_SetNone(PyExc_AssertionError);")
3526 code.error_goto(self.pos))
3529 self.cond.generate_disposal_code(code)
3530 self.cond.free_temps(code)
3531 code.putln("#endif")
3533 def annotate(self, code):
3534 self.cond.annotate(code)
3536 self.value.annotate(code)
3539 class IfStatNode(StatNode):
3542 # if_clauses [IfClauseNode]
3543 # else_clause StatNode or None
3545 child_attrs = ["if_clauses", "else_clause"]
3547 def analyse_control_flow(self, env):
3548 env.start_branching(self.pos)
3549 for if_clause in self.if_clauses:
3550 if_clause.analyse_control_flow(env)
3551 env.next_branch(if_clause.end_pos())
3552 if self.else_clause:
3553 self.else_clause.analyse_control_flow(env)
3554 env.finish_branching(self.end_pos())
3556 def analyse_declarations(self, env):
3557 for if_clause in self.if_clauses:
3558 if_clause.analyse_declarations(env)
3559 if self.else_clause:
3560 self.else_clause.analyse_declarations(env)
3562 def analyse_expressions(self, env):
3563 for if_clause in self.if_clauses:
3564 if_clause.analyse_expressions(env)
3565 if self.else_clause:
3566 self.else_clause.analyse_expressions(env)
3568 def generate_execution_code(self, code):
3569 code.mark_pos(self.pos)
3570 end_label = code.new_label()
3571 for if_clause in self.if_clauses:
3572 if_clause.generate_execution_code(code, end_label)
3573 if self.else_clause:
3574 code.putln("/*else*/ {")
3575 self.else_clause.generate_execution_code(code)
3577 code.put_label(end_label)
3579 def annotate(self, code):
3580 for if_clause in self.if_clauses:
3581 if_clause.annotate(code)
3582 if self.else_clause:
3583 self.else_clause.annotate(code)
3586 class IfClauseNode(Node):
3587 # if or elif clause in an if statement
3589 # condition ExprNode
3592 child_attrs = ["condition", "body"]
3594 def analyse_control_flow(self, env):
3595 self.body.analyse_control_flow(env)
3597 def analyse_declarations(self, env):
3598 self.condition.analyse_declarations(env)
3599 self.body.analyse_declarations(env)
3601 def analyse_expressions(self, env):
3603 self.condition.analyse_temp_boolean_expression(env)
3604 self.body.analyse_expressions(env)
3606 def generate_execution_code(self, code, end_label):
3607 self.condition.generate_evaluation_code(code)
3610 self.condition.result())
3611 self.condition.generate_disposal_code(code)
3612 self.condition.free_temps(code)
3613 self.body.generate_execution_code(code)
3617 code.put_goto(end_label)
3620 def annotate(self, code):
3621 self.condition.annotate(code)
3622 self.body.annotate(code)
3625 class SwitchCaseNode(StatNode):
3626 # Generated in the optimization of an if-elif-else node
3628 # conditions [ExprNode]
3631 child_attrs = ['conditions', 'body']
3633 def generate_execution_code(self, code):
3634 for cond in self.conditions:
3635 code.mark_pos(cond.pos)
3636 cond.generate_evaluation_code(code)
3637 code.putln("case %s:" % cond.result())
3638 self.body.generate_execution_code(code)
3639 code.putln("break;")
3641 def annotate(self, code):
3642 for cond in self.conditions:
3644 self.body.annotate(code)
3646 class SwitchStatNode(StatNode):
3647 # Generated in the optimization of an if-elif-else node
3650 # cases [SwitchCaseNode]
3651 # else_clause StatNode or None
3653 child_attrs = ['test', 'cases', 'else_clause']
3655 def generate_execution_code(self, code):
3656 code.putln("switch (%s) {" % self.test.result())
3657 for case in self.cases:
3658 case.generate_execution_code(code)
3659 if self.else_clause is not None:
3660 code.putln("default:")
3661 self.else_clause.generate_execution_code(code)
3662 code.putln("break;")
3665 def annotate(self, code):
3666 self.test.annotate(code)
3667 for case in self.cases:
3669 if self.else_clause is not None:
3670 self.else_clause.annotate(code)
3672 class LoopNode(object):
3674 def analyse_control_flow(self, env):
3675 env.start_branching(self.pos)
3676 self.body.analyse_control_flow(env)
3677 env.next_branch(self.body.end_pos())
3678 if self.else_clause:
3679 self.else_clause.analyse_control_flow(env)
3680 env.finish_branching(self.end_pos())
3683 class WhileStatNode(LoopNode, StatNode):
3686 # condition ExprNode
3688 # else_clause StatNode
3690 child_attrs = ["condition", "body", "else_clause"]
3692 def analyse_declarations(self, env):
3693 self.body.analyse_declarations(env)
3694 if self.else_clause:
3695 self.else_clause.analyse_declarations(env)
3697 def analyse_expressions(self, env):
3699 self.condition.analyse_temp_boolean_expression(env)
3700 self.body.analyse_expressions(env)
3701 if self.else_clause:
3702 self.else_clause.analyse_expressions(env)
3704 def generate_execution_code(self, code):
3705 old_loop_labels = code.new_loop_labels()
3708 self.condition.generate_evaluation_code(code)
3709 self.condition.generate_disposal_code(code)
3712 self.condition.result())
3713 self.condition.free_temps(code)
3714 self.body.generate_execution_code(code)
3715 code.put_label(code.continue_label)
3717 break_label = code.break_label
3718 code.set_loop_labels(old_loop_labels)
3719 if self.else_clause:
3720 code.putln("/*else*/ {")
3721 self.else_clause.generate_execution_code(code)
3723 code.put_label(break_label)
3725 def annotate(self, code):
3726 self.condition.annotate(code)
3727 self.body.annotate(code)
3728 if self.else_clause:
3729 self.else_clause.annotate(code)
3732 def ForStatNode(pos, **kw):
3733 if 'iterator' in kw:
3734 return ForInStatNode(pos, **kw)
3736 return ForFromStatNode(pos, **kw)
3738 class ForInStatNode(LoopNode, StatNode):
3742 # iterator IteratorNode
3744 # else_clause StatNode
3745 # item NextNode used internally
3747 child_attrs = ["target", "iterator", "body", "else_clause"]
3750 def analyse_declarations(self, env):
3751 self.target.analyse_target_declaration(env)
3752 self.body.analyse_declarations(env)
3753 if self.else_clause:
3754 self.else_clause.analyse_declarations(env)
3756 def analyse_expressions(self, env):
3758 self.target.analyse_target_types(env)
3759 self.iterator.analyse_expressions(env)
3760 self.item = ExprNodes.NextNode(self.iterator, env)
3761 self.item = self.item.coerce_to(self.target.type, env)
3762 self.body.analyse_expressions(env)
3763 if self.else_clause:
3764 self.else_clause.analyse_expressions(env)
3766 def generate_execution_code(self, code):
3767 old_loop_labels = code.new_loop_labels()
3768 self.iterator.allocate_counter_temp(code)
3769 self.iterator.generate_evaluation_code(code)
3772 self.item.generate_evaluation_code(code)
3773 self.target.generate_assignment_code(self.item, code)
3774 self.body.generate_execution_code(code)
3775 code.put_label(code.continue_label)
3778 break_label = code.break_label
3779 code.set_loop_labels(old_loop_labels)
3780 if self.else_clause:
3781 code.putln("/*else*/ {")
3782 self.else_clause.generate_execution_code(code)
3784 code.put_label(break_label)
3785 self.iterator.release_counter_temp(code)
3786 self.iterator.generate_disposal_code(code)
3787 self.iterator.free_temps(code)
3789 def annotate(self, code):
3790 self.target.annotate(code)
3791 self.iterator.annotate(code)
3792 self.body.annotate(code)
3793 if self.else_clause:
3794 self.else_clause.annotate(code)
3795 self.item.annotate(code)
3798 class ForFromStatNode(LoopNode, StatNode):
3799 # for name from expr rel name rel expr
3806 # step ExprNode or None
3808 # else_clause StatNode or None
3814 # loopvar_node ExprNode (usually a NameNode or temp node)
3815 # py_loopvar_node PyTempNode or None
3816 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3818 is_py_target = False
3820 py_loopvar_node = None
3823 def analyse_declarations(self, env):
3824 self.target.analyse_target_declaration(env)
3825 self.body.analyse_declarations(env)
3826 if self.else_clause:
3827 self.else_clause.analyse_declarations(env)
3829 def analyse_expressions(self, env):
3831 self.target.analyse_target_types(env)
3832 self.bound1.analyse_types(env)
3833 self.bound2.analyse_types(env)
3834 if self.step is not None:
3835 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3836 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3837 self.step.analyse_types(env)
3839 target_type = self.target.type
3840 if self.target.type.is_numeric:
3841 loop_type = self.target.type
3843 loop_type = PyrexTypes.c_int_type
3844 if not self.bound1.type.is_pyobject:
3845 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3846 if not self.bound2.type.is_pyobject:
3847 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3848 if self.step is not None and not self.step.type.is_pyobject:
3849 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3850 self.bound1 = self.bound1.coerce_to(loop_type, env)
3851 self.bound2 = self.bound2.coerce_to(loop_type, env)
3852 if not self.bound2.is_literal:
3853 self.bound2 = self.bound2.coerce_to_temp(env)
3854 if self.step is not None:
3855 self.step = self.step.coerce_to(loop_type, env)
3856 if not self.step.is_literal:
3857 self.step = self.step.coerce_to_temp(env)
3859 target_type = self.target.type
3860 if not (target_type.is_pyobject or target_type.is_numeric):
3861 error(self.target.pos,
3862 "for-from loop variable must be c numeric type or Python object")
3863 if target_type.is_numeric:
3864 self.is_py_target = False
3865 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3866 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3867 self.loopvar_node = self.target
3868 self.py_loopvar_node = None
3870 self.is_py_target = True
3871 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3872 self.loopvar_node = c_loopvar_node
3873 self.py_loopvar_node = \
3874 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3875 self.body.analyse_expressions(env)
3876 if self.else_clause:
3877 self.else_clause.analyse_expressions(env)
3879 def generate_execution_code(self, code):
3880 old_loop_labels = code.new_loop_labels()
3881 from_range = self.from_range
3882 self.bound1.generate_evaluation_code(code)
3883 self.bound2.generate_evaluation_code(code)
3884 offset, incop = self.relation_table[self.relation1]
3885 if self.step is not None:
3886 self.step.generate_evaluation_code(code)
3887 step = self.step.result()
3888 incop = "%s=%s" % (incop[0], step)
3890 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3891 self.loopvar_node.allocate(code)
3892 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3893 self.py_loopvar_node.allocate(code)
3895 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3897 loopvar_name = self.loopvar_node.result()
3899 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3901 self.bound1.result(), offset,
3902 loopvar_name, self.relation2, self.bound2.result(),
3903 loopvar_name, incop))
3904 if self.py_loopvar_node:
3905 self.py_loopvar_node.generate_evaluation_code(code)
3906 self.target.generate_assignment_code(self.py_loopvar_node, code)
3908 code.putln("%s = %s;" % (
3909 self.target.result(), loopvar_name))
3910 self.body.generate_execution_code(code)
3911 code.put_label(code.continue_label)
3912 if self.py_loopvar_node:
3913 # This mess is to make for..from loops with python targets behave
3914 # exactly like those with C targets with regards to re-assignment
3915 # of the loop variable.
3917 if self.target.entry.is_pyglobal:
3918 # We know target is a NameNode, this is the only ugly case.
3919 target_node = ExprNodes.PyTempNode(self.target.pos, None)
3920 target_node.allocate(code)
3921 interned_cname = code.intern_identifier(self.target.entry.name)
3922 code.putln("/*here*/")
3923 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
3924 target_node.result(),
3925 Naming.module_cname,
3927 code.error_goto_if_null(target_node.result(), self.target.pos)))
3928 code.put_gotref(target_node.result())
3930 target_node = self.target
3931 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
3932 from_py_node.temp_code = loopvar_name
3933 from_py_node.generate_result_code(code)
3934 if self.target.entry.is_pyglobal:
3935 code.put_decref(target_node.result(), target_node.type)
3936 target_node.release(code)
3938 if self.py_loopvar_node:
3939 # This is potentially wasteful, but we don't want the semantics to
3940 # depend on whether or not the loop is a python type.
3941 self.py_loopvar_node.generate_evaluation_code(code)
3942 self.target.generate_assignment_code(self.py_loopvar_node, code)
3943 break_label = code.break_label
3944 code.set_loop_labels(old_loop_labels)
3945 if self.else_clause:
3946 code.putln("/*else*/ {")
3947 self.else_clause.generate_execution_code(code)
3949 code.put_label(break_label)
3950 self.bound1.generate_disposal_code(code)
3951 self.bound1.free_temps(code)
3952 self.bound2.generate_disposal_code(code)
3953 self.bound2.free_temps(code)
3954 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3955 self.loopvar_node.release(code)
3956 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3957 self.py_loopvar_node.release(code)
3958 if self.step is not None:
3959 self.step.generate_disposal_code(code)
3960 self.step.free_temps(code)
3963 # {relop : (initial offset, increment op)}
3970 def annotate(self, code):
3971 self.target.annotate(code)
3972 self.bound1.annotate(code)
3973 self.bound2.annotate(code)
3975 self.bound2.annotate(code)
3976 self.body.annotate(code)
3977 if self.else_clause:
3978 self.else_clause.annotate(code)
3981 class WithStatNode(StatNode):
3983 Represents a Python with statement.
3985 This is only used at parse tree level; and is not present in
3986 analysis or generation phases.
3988 # manager The with statement manager object
3989 # target Node (lhs expression)
3991 child_attrs = ["manager", "target", "body"]
3993 class TryExceptStatNode(StatNode):
3994 # try .. except statement
3997 # except_clauses [ExceptClauseNode]
3998 # else_clause StatNode or None
4000 child_attrs = ["body", "except_clauses", "else_clause"]
4002 def analyse_control_flow(self, env):
4003 env.start_branching(self.pos)
4004 self.body.analyse_control_flow(env)
4005 successful_try = env.control_flow # grab this for later
4006 env.next_branch(self.body.end_pos())
4007 env.finish_branching(self.body.end_pos())
4009 env.start_branching(self.except_clauses[0].pos)
4010 for except_clause in self.except_clauses:
4011 except_clause.analyse_control_flow(env)
4012 env.next_branch(except_clause.end_pos())
4014 # the else cause it executed only when the try clause finishes
4015 env.control_flow.incoming = successful_try
4016 if self.else_clause:
4017 self.else_clause.analyse_control_flow(env)
4018 env.finish_branching(self.end_pos())
4020 def analyse_declarations(self, env):
4021 self.body.analyse_declarations(env)
4022 for except_clause in self.except_clauses:
4023 except_clause.analyse_declarations(env)
4024 if self.else_clause:
4025 self.else_clause.analyse_declarations(env)
4026 env.use_utility_code(reset_exception_utility_code)
4028 def analyse_expressions(self, env):
4029 self.body.analyse_expressions(env)
4030 default_clause_seen = 0
4031 for except_clause in self.except_clauses:
4032 except_clause.analyse_expressions(env)
4033 if default_clause_seen:
4034 error(except_clause.pos, "default 'except:' must be last")
4035 if not except_clause.pattern:
4036 default_clause_seen = 1
4037 self.has_default_clause = default_clause_seen
4038 if self.else_clause:
4039 self.else_clause.analyse_expressions(env)
4041 gil_check = StatNode._gil_check
4042 gil_message = "Try-except statement"
4044 def generate_execution_code(self, code):
4045 old_return_label = code.return_label
4046 old_break_label = code.break_label
4047 old_continue_label = code.continue_label
4048 old_error_label = code.new_error_label()
4049 our_error_label = code.error_label
4050 except_end_label = code.new_label('exception_handled')
4051 except_error_label = code.new_label('except_error')
4052 except_return_label = code.new_label('except_return')
4053 try_return_label = code.new_label('try_return')
4054 try_break_label = code.new_label('try_break')
4055 try_continue_label = code.new_label('try_continue')
4056 try_end_label = code.new_label('try_end')
4059 code.putln("PyObject %s;" %
4060 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4061 code.putln("__Pyx_ExceptionSave(%s);" %
4062 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4063 for var in Naming.exc_save_vars:
4064 code.put_xgotref(var)
4067 code.return_label = try_return_label
4068 code.break_label = try_break_label
4069 code.continue_label = try_continue_label
4070 self.body.generate_execution_code(code)
4073 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4074 code.error_label = except_error_label
4075 code.return_label = except_return_label
4076 if self.else_clause:
4079 self.else_clause.generate_execution_code(code)
4082 for var in Naming.exc_save_vars:
4083 code.put_xdecref_clear(var, py_object_type)
4084 code.put_goto(try_end_label)
4085 if code.label_used(try_return_label):
4086 code.put_label(try_return_label)
4087 for var in Naming.exc_save_vars:
4088 code.put_xdecref_clear(var, py_object_type)
4089 code.put_goto(old_return_label)
4090 code.put_label(our_error_label)
4091 for temp_name, type in temps_to_clean_up:
4092 code.put_xdecref_clear(temp_name, type)
4093 for except_clause in self.except_clauses:
4094 except_clause.generate_handling_code(code, except_end_label)
4096 error_label_used = code.label_used(except_error_label)
4097 if error_label_used or not self.has_default_clause:
4098 if error_label_used:
4099 code.put_label(except_error_label)
4100 for var in Naming.exc_save_vars:
4101 code.put_xdecref(var, py_object_type)
4102 code.put_goto(old_error_label)
4104 if code.label_used(try_break_label):
4105 code.put_label(try_break_label)
4106 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4107 code.putln("__Pyx_ExceptionReset(%s);" %
4108 ', '.join(Naming.exc_save_vars))
4109 code.put_goto(old_break_label)
4111 if code.label_used(try_continue_label):
4112 code.put_label(try_continue_label)
4113 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4114 code.putln("__Pyx_ExceptionReset(%s);" %
4115 ', '.join(Naming.exc_save_vars))
4116 code.put_goto(old_continue_label)
4118 if code.label_used(except_return_label):
4119 code.put_label(except_return_label)
4120 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4121 code.putln("__Pyx_ExceptionReset(%s);" %
4122 ', '.join(Naming.exc_save_vars))
4123 code.put_goto(old_return_label)
4125 if code.label_used(except_end_label):
4126 code.put_label(except_end_label)
4127 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4128 code.putln("__Pyx_ExceptionReset(%s);" %
4129 ', '.join(Naming.exc_save_vars))
4130 code.put_label(try_end_label)
4133 code.return_label = old_return_label
4134 code.break_label = old_break_label
4135 code.continue_label = old_continue_label
4136 code.error_label = old_error_label
4138 def annotate(self, code):
4139 self.body.annotate(code)
4140 for except_node in self.except_clauses:
4141 except_node.annotate(code)
4142 if self.else_clause:
4143 self.else_clause.annotate(code)
4146 class ExceptClauseNode(Node):
4147 # Part of try ... except statement.
4150 # target ExprNode or None
4152 # excinfo_target NameNode or None optional target for exception info
4153 # match_flag string result of exception match
4154 # exc_value ExcValueNode used internally
4155 # function_name string qualified name of enclosing function
4156 # exc_vars (string * 3) local exception variables
4158 # excinfo_target is never set by the parser, but can be set by a transform
4159 # in order to extract more extensive information about the exception as a
4160 # sys.exc_info()-style tuple into a target variable
4162 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4165 excinfo_target = None
4167 def analyse_declarations(self, env):
4169 self.target.analyse_target_declaration(env)
4170 if self.excinfo_target is not None:
4171 self.excinfo_target.analyse_target_declaration(env)
4172 self.body.analyse_declarations(env)
4174 def analyse_expressions(self, env):
4176 genv = env.global_scope()
4177 self.function_name = env.qualified_name
4179 self.pattern.analyse_expressions(env)
4180 self.pattern = self.pattern.coerce_to_pyobject(env)
4183 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4184 self.target.analyse_target_expression(env, self.exc_value)
4185 if self.excinfo_target is not None:
4187 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4188 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4189 self.excinfo_tuple.analyse_expressions(env)
4190 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4192 self.body.analyse_expressions(env)
4194 def generate_handling_code(self, code, end_label):
4195 code.mark_pos(self.pos)
4197 self.pattern.generate_evaluation_code(code)
4199 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4201 "%s = PyErr_ExceptionMatches(%s);" % (
4203 self.pattern.py_result()))
4204 self.pattern.generate_disposal_code(code)
4205 self.pattern.free_temps(code)
4209 code.funcstate.release_temp(match_flag)
4211 code.putln("/*except:*/ {")
4213 if not getattr(self.body, 'stats', True):
4214 # most simple case: no exception variable, empty body (pass)
4215 # => reset the exception state, done
4216 code.putln("PyErr_Restore(0,0,0);")
4217 code.put_goto(end_label)
4221 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4224 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4225 # We always have to fetch the exception value even if
4226 # there is no target, because this also normalises the
4227 # exception and stores it in the thread state.
4228 code.globalstate.use_utility_code(get_exception_utility_code)
4229 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4230 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4231 code.error_goto(self.pos)))
4235 self.exc_value.set_var(exc_vars[1])
4236 self.exc_value.generate_evaluation_code(code)
4237 self.target.generate_assignment_code(self.exc_value, code)
4238 if self.excinfo_target is not None:
4239 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4240 node.set_var(tempvar)
4241 self.excinfo_tuple.generate_evaluation_code(code)
4242 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4244 old_break_label, old_continue_label = code.break_label, code.continue_label
4245 code.break_label = code.new_label('except_break')
4246 code.continue_label = code.new_label('except_continue')
4248 old_exc_vars = code.funcstate.exc_vars
4249 code.funcstate.exc_vars = exc_vars
4250 self.body.generate_execution_code(code)
4251 code.funcstate.exc_vars = old_exc_vars
4252 for var in exc_vars:
4253 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4254 code.put_goto(end_label)
4256 if code.label_used(code.break_label):
4257 code.put_label(code.break_label)
4258 for var in exc_vars:
4259 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4260 code.put_goto(old_break_label)
4261 code.break_label = old_break_label
4263 if code.label_used(code.continue_label):
4264 code.put_label(code.continue_label)
4265 for var in exc_vars:
4266 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4267 code.put_goto(old_continue_label)
4268 code.continue_label = old_continue_label
4270 for temp in exc_vars:
4271 code.funcstate.release_temp(temp)
4276 def annotate(self, code):
4278 self.pattern.annotate(code)
4280 self.target.annotate(code)
4281 self.body.annotate(code)
4284 class TryFinallyStatNode(StatNode):
4285 # try ... finally statement
4288 # finally_clause StatNode
4290 # The plan is that we funnel all continue, break
4291 # return and error gotos into the beginning of the
4292 # finally block, setting a variable to remember which
4293 # one we're doing. At the end of the finally block, we
4294 # switch on the variable to figure out where to go.
4295 # In addition, if we're doing an error, we save the
4296 # exception on entry to the finally block and restore
4299 child_attrs = ["body", "finally_clause"]
4301 preserve_exception = 1
4303 disallow_continue_in_try_finally = 0
4304 # There doesn't seem to be any point in disallowing
4305 # continue in the try block, since we have no problem
4308 def create_analysed(pos, env, body, finally_clause):
4309 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4311 create_analysed = staticmethod(create_analysed)
4313 def analyse_control_flow(self, env):
4314 env.start_branching(self.pos)
4315 self.body.analyse_control_flow(env)
4316 env.next_branch(self.body.end_pos())
4317 env.finish_branching(self.body.end_pos())
4318 self.finally_clause.analyse_control_flow(env)
4320 def analyse_declarations(self, env):
4321 self.body.analyse_declarations(env)
4322 self.finally_clause.analyse_declarations(env)
4324 def analyse_expressions(self, env):
4325 self.body.analyse_expressions(env)
4326 self.finally_clause.analyse_expressions(env)
4328 gil_check = StatNode._gil_check
4329 gil_message = "Try-finally statement"
4331 def generate_execution_code(self, code):
4332 old_error_label = code.error_label
4333 old_labels = code.all_new_labels()
4334 new_labels = code.get_all_labels()
4335 new_error_label = code.error_label
4336 catch_label = code.new_label()
4339 if self.disallow_continue_in_try_finally:
4340 was_in_try_finally = code.funcstate.in_try_finally
4341 code.funcstate.in_try_finally = 1
4342 self.body.generate_execution_code(code)
4343 if self.disallow_continue_in_try_finally:
4344 code.funcstate.in_try_finally = was_in_try_finally
4347 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4351 error_label_used = 0
4352 for i, new_label in enumerate(new_labels):
4353 if new_label in code.labels_used:
4354 cases_used.append(i)
4355 if new_label == new_error_label:
4356 error_label_used = 1
4357 error_label_case = i
4361 if error_label_used and self.preserve_exception:
4363 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4365 "int %s;" % Naming.exc_lineno_name)
4366 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4367 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4368 code.putln(exc_var_init_zero)
4370 exc_var_init_zero = None
4371 code.use_label(catch_label)
4373 "__pyx_why = 0; goto %s;" % catch_label)
4374 for i in cases_used:
4375 new_label = new_labels[i]
4376 #if new_label and new_label != "<try>":
4377 if new_label == new_error_label and self.preserve_exception:
4378 self.put_error_catcher(code,
4379 new_error_label, i+1, catch_label, temps_to_clean_up)
4381 code.put('%s: ' % new_label)
4382 if exc_var_init_zero:
4383 code.putln(exc_var_init_zero)
4384 code.putln("__pyx_why = %s; goto %s;" % (
4387 code.put_label(catch_label)
4388 code.set_all_labels(old_labels)
4389 if error_label_used:
4390 code.new_error_label()
4391 finally_error_label = code.error_label
4392 self.finally_clause.generate_execution_code(code)
4393 if error_label_used:
4394 if finally_error_label in code.labels_used and self.preserve_exception:
4395 over_label = code.new_label()
4396 code.put_goto(over_label);
4397 code.put_label(finally_error_label)
4398 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4399 for var in Naming.exc_vars:
4400 code.putln("Py_XDECREF(%s);" % var)
4402 code.put_goto(old_error_label)
4403 code.put_label(over_label)
4404 code.error_label = old_error_label
4407 "switch (__pyx_why) {")
4408 for i in cases_used:
4409 old_label = old_labels[i]
4410 if old_label == old_error_label and self.preserve_exception:
4411 self.put_error_uncatcher(code, i+1, old_error_label)
4413 code.use_label(old_label)
4415 "case %s: goto %s;" % (
4423 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4424 code.globalstate.use_utility_code(restore_exception_utility_code)
4431 for temp_name, type in temps_to_clean_up:
4432 code.put_xdecref_clear(temp_name, type)
4434 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4438 Naming.exc_lineno_name, Naming.lineno_cname))
4442 code.put_goto(catch_label)
4446 def put_error_uncatcher(self, code, i, error_label):
4447 code.globalstate.use_utility_code(restore_exception_utility_code)
4452 "__Pyx_ErrRestore(%s, %s, %s);" %
4456 Naming.lineno_cname, Naming.exc_lineno_name))
4457 for var in Naming.exc_vars:
4461 code.put_goto(error_label)
4465 def annotate(self, code):
4466 self.body.annotate(code)
4467 self.finally_clause.annotate(code)
4470 class GILStatNode(TryFinallyStatNode):
4471 # 'with gil' or 'with nogil' statement
4473 # state string 'gil' or 'nogil'
4477 preserve_exception = 0
4479 def __init__(self, pos, state, body):
4481 TryFinallyStatNode.__init__(self, pos,
4483 finally_clause = GILExitNode(pos, state = state))
4485 def analyse_expressions(self, env):
4486 env.use_utility_code(force_init_threads_utility_code)
4487 was_nogil = env.nogil
4489 TryFinallyStatNode.analyse_expressions(self, env)
4490 env.nogil = was_nogil
4492 def gil_check(self, env):
4495 def generate_execution_code(self, code):
4496 code.mark_pos(self.pos)
4497 if self.state == 'gil':
4498 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4500 code.putln("{ PyThreadState *_save;")
4501 code.putln("Py_UNBLOCK_THREADS")
4502 TryFinallyStatNode.generate_execution_code(self, code)
4506 class GILExitNode(StatNode):
4507 # Used as the 'finally' block in a GILStatNode
4509 # state string 'gil' or 'nogil'
4513 def analyse_expressions(self, env):
4516 def generate_execution_code(self, code):
4517 if self.state == 'gil':
4518 code.putln("PyGILState_Release();")
4520 code.putln("Py_BLOCK_THREADS")
4523 class CImportStatNode(StatNode):
4526 # module_name string Qualified name of module being imported
4527 # as_name string or None Name specified in "as" clause, if any
4531 def analyse_declarations(self, env):
4532 if not env.is_module_scope:
4533 error(self.pos, "cimport only allowed at module level")
4535 module_scope = env.find_module(self.module_name, self.pos)
4536 if "." in self.module_name:
4537 names = [EncodedString(name) for name in self.module_name.split(".")]
4539 top_module_scope = env.context.find_submodule(top_name)
4540 module_scope = top_module_scope
4541 for name in names[1:]:
4542 submodule_scope = module_scope.find_submodule(name)
4543 module_scope.declare_module(name, submodule_scope, self.pos)
4544 module_scope = submodule_scope
4546 env.declare_module(self.as_name, module_scope, self.pos)
4548 env.declare_module(top_name, top_module_scope, self.pos)
4550 name = self.as_name or self.module_name
4551 env.declare_module(name, module_scope, self.pos)
4553 def analyse_expressions(self, env):
4556 def generate_execution_code(self, code):
4560 class FromCImportStatNode(StatNode):
4561 # from ... cimport statement
4563 # module_name string Qualified name of module
4564 # imported_names [(pos, name, as_name, kind)] Names to be imported
4568 def analyse_declarations(self, env):
4569 if not env.is_module_scope:
4570 error(self.pos, "cimport only allowed at module level")
4572 module_scope = env.find_module(self.module_name, self.pos)
4573 env.add_imported_module(module_scope)
4574 for pos, name, as_name, kind in self.imported_names:
4576 for local_name, entry in module_scope.entries.items():
4577 env.add_imported_entry(local_name, entry, pos)
4579 entry = module_scope.lookup(name)
4581 if kind and not self.declaration_matches(entry, kind):
4582 entry.redeclared(pos)
4584 if kind == 'struct' or kind == 'union':
4585 entry = module_scope.declare_struct_or_union(name,
4586 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4587 elif kind == 'class':
4588 entry = module_scope.declare_c_class(name, pos = pos,
4589 module_name = self.module_name)
4591 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4592 if submodule_scope.parent_module is module_scope:
4593 env.declare_module(as_name or name, submodule_scope, self.pos)
4595 error(pos, "Name '%s' not declared in module '%s'"
4596 % (name, self.module_name))
4599 local_name = as_name or name
4600 env.add_imported_entry(local_name, entry, pos)
4602 def declaration_matches(self, entry, kind):
4603 if not entry.is_type:
4607 if not type.is_extension_type:
4610 if not type.is_struct_or_union:
4612 if kind != type.kind:
4616 def analyse_expressions(self, env):
4619 def generate_execution_code(self, code):
4623 class FromImportStatNode(StatNode):
4624 # from ... import statement
4627 # items [(string, NameNode)]
4628 # interned_items [(string, NameNode, ExprNode)]
4629 # item PyTempNode used internally
4630 # import_star boolean used internally
4632 child_attrs = ["module"]
4635 def analyse_declarations(self, env):
4636 for name, target in self.items:
4638 if not env.is_module_scope:
4639 error(self.pos, "import * only allowed at module level")
4641 env.has_import_star = 1
4642 self.import_star = 1
4644 target.analyse_target_declaration(env)
4646 def analyse_expressions(self, env):
4648 self.module.analyse_expressions(env)
4649 self.item = ExprNodes.PyTempNode(self.pos, env)
4650 self.interned_items = []
4651 for name, target in self.items:
4653 for _, entry in env.entries.items():
4654 if not entry.is_type and entry.type.is_extension_type:
4655 env.use_utility_code(ExprNodes.type_test_utility_code)
4658 entry = env.lookup(target.name)
4659 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4660 continue # already cimported
4661 target.analyse_target_expression(env, None)
4662 if target.type is py_object_type:
4665 coerced_item = self.item.coerce_to(target.type, env)
4666 self.interned_items.append(
4667 (name, target, coerced_item))
4669 def generate_execution_code(self, code):
4670 self.module.generate_evaluation_code(code)
4671 if self.import_star:
4673 'if (%s(%s) < 0) %s;' % (
4675 self.module.py_result(),
4676 code.error_goto(self.pos)))
4677 self.item.allocate(code)
4678 for name, target, coerced_item in self.interned_items:
4679 cname = code.intern_identifier(name)
4681 '%s = PyObject_GetAttr(%s, %s); %s' % (
4683 self.module.py_result(),
4685 code.error_goto_if_null(self.item.result(), self.pos)))
4686 code.put_gotref(self.item.py_result())
4687 if coerced_item is None:
4688 target.generate_assignment_code(self.item, code)
4690 coerced_item.allocate_temp_result(code)
4691 coerced_item.generate_result_code(code)
4692 target.generate_assignment_code(coerced_item, code)
4693 if self.item.result() != coerced_item.result():
4694 code.put_decref_clear(self.item.result(), self.item.type)
4695 self.item.release(code)
4696 self.module.generate_disposal_code(code)
4697 self.module.free_temps(code)
4701 #------------------------------------------------------------------------------------
4703 # Runtime support code
4705 #------------------------------------------------------------------------------------
4707 utility_function_predeclarations = \
4710 #define INLINE __inline__
4712 #define INLINE __inline
4717 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4721 static int %(skip_dispatch_cname)s = 0;
4723 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4725 if Options.gcc_branch_hints:
4726 branch_prediction_macros = \
4729 /* Test for GCC > 2.95 */
4730 #if __GNUC__ > 2 || \
4731 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4732 #define likely(x) __builtin_expect(!!(x), 1)
4733 #define unlikely(x) __builtin_expect(!!(x), 0)
4734 #else /* __GNUC__ > 2 ... */
4735 #define likely(x) (x)
4736 #define unlikely(x) (x)
4737 #endif /* __GNUC__ > 2 ... */
4738 #else /* __GNUC__ */
4739 #define likely(x) (x)
4740 #define unlikely(x) (x)
4741 #endif /* __GNUC__ */
4744 branch_prediction_macros = \
4746 #define likely(x) (x)
4747 #define unlikely(x) (x)
4750 #get_name_predeclaration = \
4751 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4753 #get_name_interned_predeclaration = \
4754 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4756 #------------------------------------------------------------------------------------
4758 printing_utility_code = UtilityCode(
4760 static int __Pyx_Print(PyObject *, int); /*proto*/
4761 #if PY_MAJOR_VERSION >= 3
4762 static PyObject* %s = 0;
4763 static PyObject* %s = 0;
4765 """ % (Naming.print_function, Naming.print_function_kwargs),
4767 #if PY_MAJOR_VERSION < 3
4768 static PyObject *__Pyx_GetStdout(void) {
4769 PyObject *f = PySys_GetObject((char *)"stdout");
4771 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4776 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4781 if (!(f = __Pyx_GetStdout()))
4783 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4784 if (PyFile_SoftSpace(f, 1)) {
4785 if (PyFile_WriteString(" ", f) < 0)
4788 v = PyTuple_GET_ITEM(arg_tuple, i);
4789 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4791 if (PyString_Check(v)) {
4792 char *s = PyString_AsString(v);
4793 Py_ssize_t len = PyString_Size(v);
4795 isspace(Py_CHARMASK(s[len-1])) &&
4797 PyFile_SoftSpace(f, 0);
4801 if (PyFile_WriteString("\n", f) < 0)
4803 PyFile_SoftSpace(f, 0);
4808 #else /* Python 3 has a print function */
4810 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4811 PyObject* kwargs = 0;
4812 PyObject* result = 0;
4813 PyObject* end_string;
4814 if (!%(PRINT_FUNCTION)s) {
4815 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4816 if (!%(PRINT_FUNCTION)s)
4820 if (!%(PRINT_KWARGS)s) {
4821 %(PRINT_KWARGS)s = PyDict_New();
4822 if (!%(PRINT_KWARGS)s)
4824 end_string = PyUnicode_FromStringAndSize(" ", 1);
4827 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4828 Py_DECREF(end_string);
4831 Py_DECREF(end_string);
4833 kwargs = %(PRINT_KWARGS)s;
4835 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4843 """ % {'BUILTINS' : Naming.builtins_cname,
4844 'PRINT_FUNCTION' : Naming.print_function,
4845 'PRINT_KWARGS' : Naming.print_function_kwargs}
4849 printing_one_utility_code = UtilityCode(
4851 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4854 #if PY_MAJOR_VERSION < 3
4856 static int __Pyx_PrintOne(PyObject *o) {
4858 if (!(f = __Pyx_GetStdout()))
4860 if (PyFile_SoftSpace(f, 0)) {
4861 if (PyFile_WriteString(" ", f) < 0)
4864 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4866 if (PyFile_WriteString("\n", f) < 0)
4869 /* the line below is just to avoid compiler
4870 * compiler warnings about unused functions */
4871 return __Pyx_Print(NULL, 0);
4874 #else /* Python 3 has a print function */
4876 static int __Pyx_PrintOne(PyObject *o) {
4878 PyObject* arg_tuple = PyTuple_New(1);
4879 if (unlikely(!arg_tuple))
4882 PyTuple_SET_ITEM(arg_tuple, 0, o);
4883 res = __Pyx_Print(arg_tuple, 1);
4884 Py_DECREF(arg_tuple);
4890 requires=[printing_utility_code])
4894 #------------------------------------------------------------------------------------
4896 # The following function is based on do_raise() from ceval.c.
4898 raise_utility_code = UtilityCode(
4900 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4903 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4907 /* First, check the traceback argument, replacing None with NULL. */
4908 if (tb == Py_None) {
4912 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4913 PyErr_SetString(PyExc_TypeError,
4914 "raise: arg 3 must be a traceback or None");
4917 /* Next, replace a missing value with None */
4918 if (value == NULL) {
4922 #if PY_VERSION_HEX < 0x02050000
4923 if (!PyClass_Check(type))
4925 if (!PyType_Check(type))
4928 /* Raising an instance. The value should be a dummy. */
4929 if (value != Py_None) {
4930 PyErr_SetString(PyExc_TypeError,
4931 "instance exception may not have a separate value");
4934 /* Normalize to raise <class>, <instance> */
4937 #if PY_VERSION_HEX < 0x02050000
4938 if (PyInstance_Check(type)) {
4939 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4944 PyErr_SetString(PyExc_TypeError,
4945 "raise: exception must be an old-style class or instance");
4949 type = (PyObject*) Py_TYPE(type);
4951 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4952 PyErr_SetString(PyExc_TypeError,
4953 "raise: exception class must be a subclass of BaseException");
4958 __Pyx_ErrRestore(type, value, tb);
4968 #------------------------------------------------------------------------------------
4970 reraise_utility_code = UtilityCode(
4972 static void __Pyx_ReRaise(void); /*proto*/
4975 static void __Pyx_ReRaise(void) {
4976 PyThreadState *tstate = PyThreadState_GET();
4977 PyObject* tmp_type = tstate->curexc_type;
4978 PyObject* tmp_value = tstate->curexc_value;
4979 PyObject* tmp_tb = tstate->curexc_traceback;
4980 tstate->curexc_type = tstate->exc_type;
4981 tstate->curexc_value = tstate->exc_value;
4982 tstate->curexc_traceback = tstate->exc_traceback;
4983 tstate->exc_type = 0;
4984 tstate->exc_value = 0;
4985 tstate->exc_traceback = 0;
4986 Py_XDECREF(tmp_type);
4987 Py_XDECREF(tmp_value);
4992 #------------------------------------------------------------------------------------
4994 arg_type_test_utility_code = UtilityCode(
4996 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4997 const char *name, int exact); /*proto*/
5000 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5001 const char *name, int exact)
5004 PyErr_Format(PyExc_SystemError, "Missing type object");
5007 if (none_allowed && obj == Py_None) return 1;
5009 if (Py_TYPE(obj) == type) return 1;
5012 if (PyObject_TypeCheck(obj, type)) return 1;
5014 PyErr_Format(PyExc_TypeError,
5015 "Argument '%s' has incorrect type (expected %s, got %s)",
5016 name, type->tp_name, Py_TYPE(obj)->tp_name);
5021 #------------------------------------------------------------------------------------
5023 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5024 # many or too few positional arguments were found. This handles
5025 # Py_ssize_t formatting correctly.
5027 raise_argtuple_invalid_utility_code = UtilityCode(
5029 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5030 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5033 static void __Pyx_RaiseArgtupleInvalid(
5034 const char* func_name,
5038 Py_ssize_t num_found)
5040 Py_ssize_t num_expected;
5041 const char *number, *more_or_less;
5043 if (num_found < num_min) {
5044 num_expected = num_min;
5045 more_or_less = "at least";
5047 num_expected = num_max;
5048 more_or_less = "at most";
5051 more_or_less = "exactly";
5053 number = (num_expected == 1) ? "" : "s";
5054 PyErr_Format(PyExc_TypeError,
5055 #if PY_VERSION_HEX < 0x02050000
5056 "%s() takes %s %d positional argument%s (%d given)",
5058 "%s() takes %s %zd positional argument%s (%zd given)",
5060 func_name, more_or_less, num_expected, number, num_found);
5064 raise_keyword_required_utility_code = UtilityCode(
5066 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5069 static INLINE void __Pyx_RaiseKeywordRequired(
5070 const char* func_name,
5073 PyErr_Format(PyExc_TypeError,
5074 #if PY_MAJOR_VERSION >= 3
5075 "%s() needs keyword-only argument %U", func_name, kw_name);
5077 "%s() needs keyword-only argument %s", func_name,
5078 PyString_AS_STRING(kw_name));
5083 raise_double_keywords_utility_code = UtilityCode(
5085 static void __Pyx_RaiseDoubleKeywordsError(
5086 const char* func_name, PyObject* kw_name); /*proto*/
5089 static void __Pyx_RaiseDoubleKeywordsError(
5090 const char* func_name,
5093 PyErr_Format(PyExc_TypeError,
5094 #if PY_MAJOR_VERSION >= 3
5095 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5097 "%s() got multiple values for keyword argument '%s'", func_name,
5098 PyString_AS_STRING(kw_name));
5103 #------------------------------------------------------------------------------------
5105 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5106 # were passed to a function, or if any keywords were passed to a
5107 # function that does not accept them.
5109 keyword_string_check_utility_code = UtilityCode(
5111 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5112 const char* function_name, int kw_allowed); /*proto*/
5115 static INLINE int __Pyx_CheckKeywordStrings(
5117 const char* function_name,
5122 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5123 #if PY_MAJOR_VERSION < 3
5124 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5126 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5128 goto invalid_keyword_type;
5130 if ((!kw_allowed) && unlikely(key))
5131 goto invalid_keyword;
5133 invalid_keyword_type:
5134 PyErr_Format(PyExc_TypeError,
5135 "%s() keywords must be strings", function_name);
5138 PyErr_Format(PyExc_TypeError,
5139 #if PY_MAJOR_VERSION < 3
5140 "%s() got an unexpected keyword argument '%s'",
5141 function_name, PyString_AsString(key));
5143 "%s() got an unexpected keyword argument '%U'",
5144 function_name, key);
5150 #------------------------------------------------------------------------------------
5152 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5153 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5154 # keywords will raise an invalid keyword error.
5156 # Three kinds of errors are checked: 1) non-string keywords, 2)
5157 # unexpected keywords and 3) overlap with positional arguments.
5159 # If num_posargs is greater 0, it denotes the number of positional
5160 # arguments that were passed and that must therefore not appear
5161 # amongst the keywords as well.
5163 # This method does not check for required keyword arguments.
5166 parse_keywords_utility_code = UtilityCode(
5168 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5169 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5170 const char* function_name); /*proto*/
5173 static int __Pyx_ParseOptionalKeywords(
5175 PyObject **argnames[],
5178 Py_ssize_t num_pos_args,
5179 const char* function_name)
5181 PyObject *key = 0, *value = 0;
5184 PyObject*** first_kw_arg = argnames + num_pos_args;
5186 while (PyDict_Next(kwds, &pos, &key, &value)) {
5187 name = first_kw_arg;
5188 while (*name && (**name != key)) name++;
5190 values[name-argnames] = value;
5192 #if PY_MAJOR_VERSION < 3
5193 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5195 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5197 goto invalid_keyword_type;
5199 for (name = first_kw_arg; *name; name++) {
5200 #if PY_MAJOR_VERSION >= 3
5201 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5202 PyUnicode_Compare(**name, key) == 0) break;
5204 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5205 _PyString_Eq(**name, key)) break;
5209 values[name-argnames] = value;
5211 /* unexpected keyword found */
5212 for (name=argnames; name != first_kw_arg; name++) {
5213 if (**name == key) goto arg_passed_twice;
5214 #if PY_MAJOR_VERSION >= 3
5215 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5216 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5218 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5219 _PyString_Eq(**name, key)) goto arg_passed_twice;
5223 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5225 goto invalid_keyword;
5233 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5235 invalid_keyword_type:
5236 PyErr_Format(PyExc_TypeError,
5237 "%s() keywords must be strings", function_name);
5240 PyErr_Format(PyExc_TypeError,
5241 #if PY_MAJOR_VERSION < 3
5242 "%s() got an unexpected keyword argument '%s'",
5243 function_name, PyString_AsString(key));
5245 "%s() got an unexpected keyword argument '%U'",
5246 function_name, key);
5253 #------------------------------------------------------------------------------------
5255 traceback_utility_code = UtilityCode(
5257 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5260 #include "compile.h"
5261 #include "frameobject.h"
5262 #include "traceback.h"
5264 static void __Pyx_AddTraceback(const char *funcname) {
5265 PyObject *py_srcfile = 0;
5266 PyObject *py_funcname = 0;
5267 PyObject *py_globals = 0;
5268 PyObject *empty_string = 0;
5269 PyCodeObject *py_code = 0;
5270 PyFrameObject *py_frame = 0;
5272 #if PY_MAJOR_VERSION < 3
5273 py_srcfile = PyString_FromString(%(FILENAME)s);
5275 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5277 if (!py_srcfile) goto bad;
5279 #if PY_MAJOR_VERSION < 3
5280 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5282 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5286 #if PY_MAJOR_VERSION < 3
5287 py_funcname = PyString_FromString(funcname);
5289 py_funcname = PyUnicode_FromString(funcname);
5292 if (!py_funcname) goto bad;
5293 py_globals = PyModule_GetDict(%(GLOBALS)s);
5294 if (!py_globals) goto bad;
5295 #if PY_MAJOR_VERSION < 3
5296 empty_string = PyString_FromStringAndSize("", 0);
5298 empty_string = PyBytes_FromStringAndSize("", 0);
5300 if (!empty_string) goto bad;
5301 py_code = PyCode_New(
5302 0, /*int argcount,*/
5303 #if PY_MAJOR_VERSION >= 3
5304 0, /*int kwonlyargcount,*/
5307 0, /*int stacksize,*/
5309 empty_string, /*PyObject *code,*/
5310 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5311 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5312 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5313 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5314 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5315 py_srcfile, /*PyObject *filename,*/
5316 py_funcname, /*PyObject *name,*/
5317 %(LINENO)s, /*int firstlineno,*/
5318 empty_string /*PyObject *lnotab*/
5320 if (!py_code) goto bad;
5321 py_frame = PyFrame_New(
5322 PyThreadState_GET(), /*PyThreadState *tstate,*/
5323 py_code, /*PyCodeObject *code,*/
5324 py_globals, /*PyObject *globals,*/
5325 0 /*PyObject *locals*/
5327 if (!py_frame) goto bad;
5328 py_frame->f_lineno = %(LINENO)s;
5329 PyTraceBack_Here(py_frame);
5331 Py_XDECREF(py_srcfile);
5332 Py_XDECREF(py_funcname);
5333 Py_XDECREF(empty_string);
5334 Py_XDECREF(py_code);
5335 Py_XDECREF(py_frame);
5338 'FILENAME': Naming.filename_cname,
5339 'LINENO': Naming.lineno_cname,
5340 'CFILENAME': Naming.cfilenm_cname,
5341 'CLINENO': Naming.clineno_cname,
5342 'GLOBALS': Naming.module_cname,
5343 'EMPTY_TUPLE' : Naming.empty_tuple,
5346 restore_exception_utility_code = UtilityCode(
5348 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5349 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5352 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5353 PyObject *tmp_type, *tmp_value, *tmp_tb;
5354 PyThreadState *tstate = PyThreadState_GET();
5356 #if PY_MAJOR_VERSION >= 3
5357 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5358 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5359 tmp_type = tstate->exc_type;
5360 tmp_value = tstate->exc_value;
5361 tmp_tb = tstate->exc_traceback;
5362 PyErr_NormalizeException(&type, &value, &tb);
5363 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5364 tstate->exc_type = 0;
5365 tstate->exc_value = 0;
5366 tstate->exc_traceback = 0;
5367 PyException_SetContext(value, tmp_value);
5368 Py_DECREF(tmp_type);
5373 tmp_type = tstate->curexc_type;
5374 tmp_value = tstate->curexc_value;
5375 tmp_tb = tstate->curexc_traceback;
5376 tstate->curexc_type = type;
5377 tstate->curexc_value = value;
5378 tstate->curexc_traceback = tb;
5379 Py_XDECREF(tmp_type);
5380 Py_XDECREF(tmp_value);
5384 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5385 PyThreadState *tstate = PyThreadState_GET();
5386 *type = tstate->curexc_type;
5387 *value = tstate->curexc_value;
5388 *tb = tstate->curexc_traceback;
5390 tstate->curexc_type = 0;
5391 tstate->curexc_value = 0;
5392 tstate->curexc_traceback = 0;
5397 #------------------------------------------------------------------------------------
5399 unraisable_exception_utility_code = UtilityCode(
5401 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5404 static void __Pyx_WriteUnraisable(const char *name) {
5405 PyObject *old_exc, *old_val, *old_tb;
5407 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5408 #if PY_MAJOR_VERSION < 3
5409 ctx = PyString_FromString(name);
5411 ctx = PyUnicode_FromString(name);
5413 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5415 PyErr_WriteUnraisable(Py_None);
5417 PyErr_WriteUnraisable(ctx);
5422 requires=[restore_exception_utility_code])
5424 #------------------------------------------------------------------------------------
5426 set_vtable_utility_code = UtilityCode(
5428 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5431 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5432 PyObject *pycobj = 0;
5435 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5438 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5451 #------------------------------------------------------------------------------------
5453 get_vtable_utility_code = UtilityCode(
5455 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5458 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5462 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5465 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5466 if (!*(void **)vtabptr)
5479 #------------------------------------------------------------------------------------
5481 init_string_tab_utility_code = UtilityCode(
5483 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5486 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5488 #if PY_MAJOR_VERSION < 3
5489 if (t->is_unicode && (!t->is_identifier)) {
5490 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5491 } else if (t->intern) {
5492 *t->p = PyString_InternFromString(t->s);
5494 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5496 #else /* Python 3+ has unicode identifiers */
5497 if (t->is_identifier || (t->is_unicode && t->intern)) {
5498 *t->p = PyUnicode_InternFromString(t->s);
5499 } else if (t->is_unicode) {
5500 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5502 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5513 #------------------------------------------------------------------------------------
5515 get_exception_utility_code = UtilityCode(
5517 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5520 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5521 PyObject *tmp_type, *tmp_value, *tmp_tb;
5522 PyThreadState *tstate = PyThreadState_GET();
5523 *type = tstate->curexc_type;
5524 *value = tstate->curexc_value;
5525 *tb = tstate->curexc_traceback;
5526 tstate->curexc_type = 0;
5527 tstate->curexc_value = 0;
5528 tstate->curexc_traceback = 0;
5529 PyErr_NormalizeException(type, value, tb);
5530 if (PyErr_Occurred())
5535 tmp_type = tstate->exc_type;
5536 tmp_value = tstate->exc_value;
5537 tmp_tb = tstate->exc_traceback;
5538 tstate->exc_type = *type;
5539 tstate->exc_value = *value;
5540 tstate->exc_traceback = *tb;
5541 /* Make sure tstate is in a consistent state when we XDECREF
5542 these objects (XDECREF may run arbitrary code). */
5543 Py_XDECREF(tmp_type);
5544 Py_XDECREF(tmp_value);
5556 #------------------------------------------------------------------------------------
5558 reset_exception_utility_code = UtilityCode(
5560 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5561 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5564 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5565 PyThreadState *tstate = PyThreadState_GET();
5566 *type = tstate->exc_type;
5567 *value = tstate->exc_value;
5568 *tb = tstate->exc_traceback;
5574 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5575 PyObject *tmp_type, *tmp_value, *tmp_tb;
5576 PyThreadState *tstate = PyThreadState_GET();
5577 tmp_type = tstate->exc_type;
5578 tmp_value = tstate->exc_value;
5579 tmp_tb = tstate->exc_traceback;
5580 tstate->exc_type = type;
5581 tstate->exc_value = value;
5582 tstate->exc_traceback = tb;
5583 Py_XDECREF(tmp_type);
5584 Py_XDECREF(tmp_value);
5589 #------------------------------------------------------------------------------------
5591 force_init_threads_utility_code = UtilityCode(
5593 #ifndef __PYX_FORCE_INIT_THREADS
5594 #if PY_VERSION_HEX < 0x02040200
5595 #define __PYX_FORCE_INIT_THREADS 1
5597 #define __PYX_FORCE_INIT_THREADS 0
5602 #------------------------------------------------------------------------------------