2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
136 def _gil_check(self, env):
141 error(self.pos, "%s not allowed without gil" % self.gil_message)
143 def clone_node(self):
144 """Clone the node. This is defined as a shallow copy, except for member lists
145 amongst the child attributes (from get_child_accessors) which are also
146 copied. Lists containing child nodes are thus seen as a way for the node
147 to hold multiple children directly; the list is not treated as a seperate
148 level in the tree."""
149 result = copy.copy(self)
150 for attrname in result.child_attrs:
151 value = getattr(result, attrname)
152 if isinstance(value, list):
153 setattr(result, attrname, [x for x in value])
158 # There are 4 phases of parse tree processing, applied in order to
159 # all the statements in a given scope-block:
161 # (0) analyse_control_flow
162 # Create the control flow tree into which state can be asserted and
165 # (1) analyse_declarations
166 # Make symbol table entries for all declarations at the current
167 # level, both explicit (def, cdef, etc.) and implicit (assignment
168 # to an otherwise undeclared name).
170 # (2) analyse_expressions
171 # Determine the result types of expressions and fill in the
172 # 'type' attribute of each ExprNode. Insert coercion nodes into the
173 # tree where needed to convert to and from Python objects.
174 # Allocate temporary locals for intermediate results. Fill
175 # in the 'result_code' attribute of each ExprNode with a C code
179 # Emit C code for all declarations, statements and expressions.
180 # Recursively applies the 3 processing phases to the bodies of
184 def analyse_control_flow(self, env):
187 def analyse_declarations(self, env):
190 def analyse_expressions(self, env):
191 raise InternalError("analyse_expressions not implemented for %s" % \
192 self.__class__.__name__)
194 def generate_code(self, code):
195 raise InternalError("generate_code not implemented for %s" % \
196 self.__class__.__name__)
198 def annotate(self, code):
199 # mro does the wrong thing
200 if isinstance(self, BlockNode):
201 self.body.annotate(code)
206 except AttributeError:
208 if not self.child_attrs:
211 for attr in self.child_attrs:
212 child = getattr(self, attr)
213 # Sometimes lists, sometimes nodes
216 elif isinstance(child, list):
218 pos = max(pos, c.end_pos())
220 pos = max(pos, child.end_pos())
224 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
226 return "<...nesting level cutoff...>"
227 if encountered is None:
229 if id(self) in encountered:
230 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
231 encountered.add(id(self))
233 def dump_child(x, level):
234 if isinstance(x, Node):
235 return x.dump(level, filter_out, cutoff-1, encountered)
236 elif isinstance(x, list):
237 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
242 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
244 return "<%s (%d)>" % (self.__class__.__name__, id(self))
247 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
248 for key, value in attrs:
249 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
250 res += "%s>" % indent
253 class CompilerDirectivesNode(Node):
255 Sets compiler directives for the children nodes
257 # directives {string:value} A dictionary holding the right value for
258 # *all* possible directives.
260 child_attrs = ["body"]
262 def analyse_control_flow(self, env):
264 env.directives = self.directives
265 self.body.analyse_control_flow(env)
268 def analyse_declarations(self, env):
270 env.directives = self.directives
271 self.body.analyse_declarations(env)
274 def analyse_expressions(self, env):
276 env.directives = self.directives
277 self.body.analyse_expressions(env)
280 def generate_function_definitions(self, env, code):
281 env_old = env.directives
282 code_old = code.globalstate.directives
283 code.globalstate.directives = self.directives
284 self.body.generate_function_definitions(env, code)
285 env.directives = env_old
286 code.globalstate.directives = code_old
288 def generate_execution_code(self, code):
289 old = code.globalstate.directives
290 code.globalstate.directives = self.directives
291 self.body.generate_execution_code(code)
292 code.globalstate.directives = old
294 def annotate(self, code):
295 old = code.globalstate.directives
296 code.globalstate.directives = self.directives
297 self.body.annotate(code)
298 code.globalstate.directives = old
300 class BlockNode(object):
301 # Mixin class for nodes representing a declaration block.
303 def generate_cached_builtins_decls(self, env, code):
304 entries = env.global_scope().undeclared_cached_builtins
305 for entry in entries:
306 code.globalstate.add_cached_builtin_decl(entry)
310 class StatListNode(Node):
311 # stats a list of StatNode
313 child_attrs = ["stats"]
315 def create_analysed(pos, env, *args, **kw):
316 node = StatListNode(pos, *args, **kw)
317 return node # No node-specific analysis necesarry
318 create_analysed = staticmethod(create_analysed)
320 def analyse_control_flow(self, env):
321 for stat in self.stats:
322 stat.analyse_control_flow(env)
324 def analyse_declarations(self, env):
325 #print "StatListNode.analyse_declarations" ###
326 for stat in self.stats:
327 stat.analyse_declarations(env)
329 def analyse_expressions(self, env):
330 #print "StatListNode.analyse_expressions" ###
331 for stat in self.stats:
332 stat.analyse_expressions(env)
334 def generate_function_definitions(self, env, code):
335 #print "StatListNode.generate_function_definitions" ###
336 for stat in self.stats:
337 stat.generate_function_definitions(env, code)
339 def generate_execution_code(self, code):
340 #print "StatListNode.generate_execution_code" ###
341 for stat in self.stats:
342 code.mark_pos(stat.pos)
343 stat.generate_execution_code(code)
345 def annotate(self, code):
346 for stat in self.stats:
350 class StatNode(Node):
352 # Code generation for statements is split into the following subphases:
354 # (1) generate_function_definitions
355 # Emit C code for the definitions of any structs,
356 # unions, enums and functions defined in the current
359 # (2) generate_execution_code
360 # Emit C code for executable statements.
363 def generate_function_definitions(self, env, code):
366 def generate_execution_code(self, code):
367 raise InternalError("generate_execution_code not implemented for %s" % \
368 self.__class__.__name__)
371 class CDefExternNode(StatNode):
372 # include_file string or None
375 child_attrs = ["body"]
377 def analyse_declarations(self, env):
378 if self.include_file:
379 env.add_include_file(self.include_file)
380 old_cinclude_flag = env.in_cinclude
382 self.body.analyse_declarations(env)
383 env.in_cinclude = old_cinclude_flag
385 def analyse_expressions(self, env):
388 def generate_execution_code(self, code):
391 def annotate(self, code):
392 self.body.annotate(code)
395 class CDeclaratorNode(Node):
396 # Part of a C declaration.
398 # Processing during analyse_declarations phase:
401 # Returns (name, type) pair where name is the
402 # CNameDeclaratorNode of the name being declared
403 # and type is the type it is being declared as.
405 # calling_convention string Calling convention of CFuncDeclaratorNode
406 # for which this is a base
410 calling_convention = ""
413 class CNameDeclaratorNode(CDeclaratorNode):
414 # name string The Pyrex name being declared
415 # cname string or None C name, if specified
416 # default ExprNode or None the value assigned on declaration
418 child_attrs = ['default']
422 def analyse(self, base_type, env, nonempty = 0):
423 if nonempty and self.name == '':
424 # May have mistaken the name for the type.
425 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
426 error(self.pos, "Missing argument name")
427 elif base_type.is_void:
428 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
430 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
431 base_type = py_object_type
432 self.type = base_type
433 return self, base_type
435 class CPtrDeclaratorNode(CDeclaratorNode):
436 # base CDeclaratorNode
438 child_attrs = ["base"]
440 def analyse(self, base_type, env, nonempty = 0):
441 if base_type.is_pyobject:
443 "Pointer base type cannot be a Python object")
444 ptr_type = PyrexTypes.c_ptr_type(base_type)
445 return self.base.analyse(ptr_type, env, nonempty = nonempty)
447 class CArrayDeclaratorNode(CDeclaratorNode):
448 # base CDeclaratorNode
451 child_attrs = ["base", "dimension"]
453 def analyse(self, base_type, env, nonempty = 0):
455 self.dimension.analyse_const_expression(env)
456 if not self.dimension.type.is_int:
457 error(self.dimension.pos, "Array dimension not integer")
458 size = self.dimension.get_constant_result_code()
466 if not base_type.is_complete():
468 "Array element type '%s' is incomplete" % base_type)
469 if base_type.is_pyobject:
471 "Array element cannot be a Python object")
472 if base_type.is_cfunction:
474 "Array element cannot be a function")
475 array_type = PyrexTypes.c_array_type(base_type, size)
476 return self.base.analyse(array_type, env, nonempty = nonempty)
479 class CFuncDeclaratorNode(CDeclaratorNode):
480 # base CDeclaratorNode
481 # args [CArgDeclNode]
482 # has_varargs boolean
483 # exception_value ConstNode
484 # exception_check boolean True if PyErr_Occurred check needed
485 # nogil boolean Can be called without gil
486 # with_gil boolean Acquire gil around function body
488 child_attrs = ["base", "args", "exception_value"]
491 optional_arg_count = 0
493 def analyse(self, return_type, env, nonempty = 0):
497 for arg_node in self.args:
498 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
499 name = name_declarator.name
500 if name_declarator.cname:
502 "Function argument cannot have C name specification")
503 # Turn *[] argument into **
505 type = PyrexTypes.c_ptr_type(type.base_type)
506 # Catch attempted C-style func(void) decl
508 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
509 func_type_args.append(
510 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
512 self.optional_arg_count += 1
513 elif self.optional_arg_count:
514 error(self.pos, "Non-default argument follows default argument")
516 if self.optional_arg_count:
517 scope = StructOrUnionScope()
518 arg_count_member = '%sn' % Naming.pyrex_prefix
519 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
520 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
521 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
522 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
523 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
528 cname = struct_cname)
529 self.op_args_struct.defined_in_pxd = 1
530 self.op_args_struct.used = 1
534 if return_type.is_pyobject \
535 and (self.exception_value or self.exception_check) \
536 and self.exception_check != '+':
538 "Exception clause not allowed for function returning Python object")
540 if self.exception_value:
541 self.exception_value.analyse_const_expression(env)
542 exc_val = self.exception_value.get_constant_result_code()
543 if self.exception_check == '+':
544 exc_val_type = self.exception_value.type
545 env.add_include_file('stdexcept')
546 if not exc_val_type.is_error and \
547 not exc_val_type.is_pyobject and \
548 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
549 error(self.exception_value.pos,
550 "Exception value must be a Python exception or cdef function with no arguments.")
552 if not return_type.assignable_from(self.exception_value.type):
553 error(self.exception_value.pos,
554 "Exception value incompatible with function return type")
555 exc_check = self.exception_check
556 if return_type.is_array:
558 "Function cannot return an array")
559 if return_type.is_cfunction:
561 "Function cannot return a function")
562 func_type = PyrexTypes.CFuncType(
563 return_type, func_type_args, self.has_varargs,
564 optional_arg_count = self.optional_arg_count,
565 exception_value = exc_val, exception_check = exc_check,
566 calling_convention = self.base.calling_convention,
567 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
568 if self.optional_arg_count:
569 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
570 return self.base.analyse(func_type, env)
573 class CArgDeclNode(Node):
574 # Item in a function declaration argument list.
576 # base_type CBaseTypeNode
577 # declarator CDeclaratorNode
578 # not_none boolean Tagged with 'not None'
579 # default ExprNode or None
580 # default_value PyObjectConst constant for default value
581 # is_self_arg boolean Is the "self" arg of an extension type method
582 # is_kw_only boolean Is a keyword-only argument
584 child_attrs = ["base_type", "declarator", "default"]
589 name_declarator = None
592 def analyse(self, env, nonempty = 0):
593 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
594 if self.type is None:
595 # The parser may missinterpret names as types...
597 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
599 self.declarator.name = self.base_type.name
600 self.base_type.name = None
601 self.base_type.is_basic_c_type = False
604 could_be_name = False
605 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
606 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
607 self.declarator.name = self.base_type.arg_name
608 return self.declarator.analyse(base_type, env, nonempty = nonempty)
610 return self.name_declarator, self.type
612 def calculate_default_value_code(self, code):
613 if self.default_value is None:
615 if self.default.is_literal:
616 # will not output any code, just assign the result_code
617 self.default.generate_evaluation_code(code)
618 return self.type.cast_code(self.default.result())
619 self.default_value = code.get_argument_default_const(self.type)
620 return self.default_value
622 def annotate(self, code):
624 self.default.annotate(code)
627 class CBaseTypeNode(Node):
628 # Abstract base class for C base type nodes.
630 # Processing during analyse_declarations phase:
637 class CAnalysedBaseTypeNode(Node):
642 def analyse(self, env, could_be_name = False):
645 class CSimpleBaseTypeNode(CBaseTypeNode):
647 # module_path [string] Qualifying name components
648 # is_basic_c_type boolean
651 # is_self_arg boolean Is self argument of C method
654 arg_name = None # in case the argument name was interpreted as a type
656 def analyse(self, env, could_be_name = False):
657 # Return type descriptor.
658 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
660 if self.is_basic_c_type:
661 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
663 error(self.pos, "Unrecognised type modifier combination")
664 elif self.name == "object" and not self.module_path:
665 type = py_object_type
666 elif self.name is None:
667 if self.is_self_arg and env.is_c_class_scope:
668 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
669 type = env.parent_type
671 type = py_object_type
674 scope = env.find_imported_module(self.module_path, self.pos)
678 if scope.is_c_class_scope:
679 scope = scope.global_scope()
680 entry = scope.lookup(self.name)
681 if entry and entry.is_type:
684 if self.is_self_arg and env.is_c_class_scope:
685 type = env.parent_type
687 type = py_object_type
688 self.arg_name = self.name
690 error(self.pos, "'%s' is not a type identifier" % self.name)
694 return PyrexTypes.error_type
696 class CBufferAccessTypeNode(CBaseTypeNode):
698 # positional_args [ExprNode] List of positional arguments
699 # keyword_args DictNode Keyword arguments
700 # base_type_node CBaseTypeNode
703 # type PyrexType.BufferType ...containing the right options
706 child_attrs = ["base_type_node", "positional_args",
707 "keyword_args", "dtype_node"]
713 def analyse(self, env, could_be_name = False):
714 base_type = self.base_type_node.analyse(env)
715 if base_type.is_error: return base_type
718 options = Buffer.analyse_buffer_options(
721 self.positional_args,
723 base_type.buffer_defaults)
725 self.type = PyrexTypes.BufferType(base_type, **options)
728 class CComplexBaseTypeNode(CBaseTypeNode):
729 # base_type CBaseTypeNode
730 # declarator CDeclaratorNode
732 child_attrs = ["base_type", "declarator"]
734 def analyse(self, env, could_be_name = False):
735 base = self.base_type.analyse(env, could_be_name)
736 _, type = self.declarator.analyse(base, env)
740 class CVarDefNode(StatNode):
741 # C variable definition or forward/extern function declaration.
743 # visibility 'private' or 'public' or 'extern'
744 # base_type CBaseTypeNode
745 # declarators [CDeclaratorNode]
748 # need_properties [entry]
750 # decorators [cython.locals(...)] or None
751 # directive_locals { string : NameNode } locals defined by cython.locals(...)
753 child_attrs = ["base_type", "declarators"]
757 directive_locals = {}
759 def analyse_declarations(self, env, dest_scope = None):
762 self.dest_scope = dest_scope
763 base_type = self.base_type.analyse(env)
764 if (dest_scope.is_c_class_scope
765 and self.visibility == 'public'
766 and base_type.is_pyobject
767 and (base_type.is_builtin_type or base_type.is_extension_type)):
768 self.need_properties = []
770 visibility = 'private'
772 need_property = False
773 visibility = self.visibility
775 for declarator in self.declarators:
776 name_declarator, type = declarator.analyse(base_type, env)
777 if not type.is_complete():
778 if not (self.visibility == 'extern' and type.is_array):
779 error(declarator.pos,
780 "Variable type '%s' is incomplete" % type)
781 if self.visibility == 'extern' and type.is_pyobject:
782 error(declarator.pos,
783 "Python object cannot be declared extern")
784 name = name_declarator.name
785 cname = name_declarator.cname
787 error(declarator.pos, "Missing name in declaration.")
789 if type.is_cfunction:
790 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
791 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
793 if entry is not None:
794 entry.directive_locals = self.directive_locals
796 if self.directive_locals:
797 s.error("Decorators can only be followed by functions")
798 if self.in_pxd and self.visibility != 'extern':
800 "Only 'extern' C variable declaration allowed in .pxd file")
801 entry = dest_scope.declare_var(name, type, declarator.pos,
802 cname = cname, visibility = visibility, is_cdef = 1)
804 self.need_properties.append(entry)
805 entry.needs_property = 1
808 class CStructOrUnionDefNode(StatNode):
810 # cname string or None
811 # kind "struct" or "union"
812 # typedef_flag boolean
813 # visibility "public" or "private"
815 # attributes [CVarDefNode] or None
818 child_attrs = ["attributes"]
820 def analyse_declarations(self, env):
822 if self.attributes is not None:
823 scope = StructOrUnionScope(self.name)
824 self.entry = env.declare_struct_or_union(
825 self.name, self.kind, scope, self.typedef_flag, self.pos,
826 self.cname, visibility = self.visibility)
827 if self.attributes is not None:
828 if self.in_pxd and not env.in_cinclude:
829 self.entry.defined_in_pxd = 1
830 for attr in self.attributes:
831 attr.analyse_declarations(env, scope)
832 if self.visibility != 'extern':
833 need_typedef_indirection = False
834 for attr in scope.var_entries:
837 type = type.base_type
838 if type == self.entry.type:
839 error(attr.pos, "Struct cannot contain itself as a member.")
840 if self.typedef_flag:
842 type = type.base_type
843 if type == self.entry.type:
844 need_typedef_indirection = True
845 if need_typedef_indirection:
846 # C can't handle typedef structs that refer to themselves.
847 struct_entry = self.entry
848 self.entry = env.declare_typedef(
849 self.name, struct_entry.type, self.pos,
850 cname = self.cname, visibility='ignore')
851 struct_entry.type.typedef_flag = False
852 # FIXME: this might be considered a hack ;-)
853 struct_entry.cname = struct_entry.type.cname = '_' + self.cname
855 def analyse_expressions(self, env):
858 def generate_execution_code(self, code):
862 class CEnumDefNode(StatNode):
863 # name string or None
864 # cname string or None
865 # items [CEnumDefItemNode]
866 # typedef_flag boolean
867 # visibility "public" or "private"
871 child_attrs = ["items"]
873 def analyse_declarations(self, env):
874 self.entry = env.declare_enum(self.name, self.pos,
875 cname = self.cname, typedef_flag = self.typedef_flag,
876 visibility = self.visibility)
877 if self.items is not None:
878 if self.in_pxd and not env.in_cinclude:
879 self.entry.defined_in_pxd = 1
880 for item in self.items:
881 item.analyse_declarations(env, self.entry)
883 def analyse_expressions(self, env):
884 if self.visibility == 'public':
885 self.temp = env.allocate_temp_pyobject()
886 env.release_temp(self.temp)
888 def generate_execution_code(self, code):
889 if self.visibility == 'public':
890 for item in self.entry.enum_values:
891 code.putln("%s = PyInt_FromLong(%s); %s" % (
894 code.error_goto_if_null(self.temp, item.pos)))
895 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
899 code.error_goto(item.pos)))
900 code.putln("%s = 0;" % self.temp)
903 class CEnumDefItemNode(StatNode):
905 # cname string or None
906 # value ExprNode or None
908 child_attrs = ["value"]
910 def analyse_declarations(self, env, enum_entry):
912 self.value.analyse_const_expression(env)
913 if not self.value.type.is_int:
914 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
915 self.value.analyse_const_expression(env)
916 entry = env.declare_const(self.name, enum_entry.type,
917 self.value, self.pos, cname = self.cname,
918 visibility = enum_entry.visibility)
919 enum_entry.enum_values.append(entry)
922 class CTypeDefNode(StatNode):
923 # base_type CBaseTypeNode
924 # declarator CDeclaratorNode
925 # visibility "public" or "private"
928 child_attrs = ["base_type", "declarator"]
930 def analyse_declarations(self, env):
931 base = self.base_type.analyse(env)
932 name_declarator, type = self.declarator.analyse(base, env)
933 name = name_declarator.name
934 cname = name_declarator.cname
935 entry = env.declare_typedef(name, type, self.pos,
936 cname = cname, visibility = self.visibility)
937 if self.in_pxd and not env.in_cinclude:
938 entry.defined_in_pxd = 1
940 def analyse_expressions(self, env):
942 def generate_execution_code(self, code):
946 class FuncDefNode(StatNode, BlockNode):
947 # Base class for function definition nodes.
949 # return_type PyrexType
950 # #filename string C name of filename string const
952 # needs_closure boolean Whether or not this function has inner functions/classes/yield
953 # directive_locals { string : NameNode } locals defined by cython.locals(...)
957 needs_closure = False
959 def analyse_default_values(self, env):
960 genv = env.global_scope()
961 for arg in self.args:
964 arg.default.analyse_types(env)
965 arg.default = arg.default.coerce_to(arg.type, genv)
966 arg.default.allocate_temps(genv)
969 "This argument cannot have a default value")
972 def need_gil_acquisition(self, lenv):
975 def create_local_scope(self, env):
977 while env.is_py_class_scope or env.is_c_class_scope:
978 env = env.outer_scope
979 if self.needs_closure:
980 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
982 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
983 lenv.return_type = self.return_type
984 type = self.entry.type
985 if type.is_cfunction:
986 lenv.nogil = type.nogil and not type.with_gil
987 self.local_scope = lenv
990 def generate_function_definitions(self, env, code):
993 lenv = self.local_scope
995 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
996 self.entry.scope.is_c_class_scope)
998 # Generate C code for header and body of function
999 code.enter_cfunc_scope()
1000 code.return_from_error_cleanup_label = code.new_label()
1002 # ----- Top-level constants used by this function
1003 code.mark_pos(self.pos)
1004 self.generate_cached_builtins_decls(lenv, code)
1005 # ----- Function header
1008 self.py_func.generate_function_header(code,
1009 with_pymethdef = env.is_py_class_scope,
1011 self.generate_function_header(code,
1012 with_pymethdef = env.is_py_class_scope)
1013 # ----- Local variable declarations
1014 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1015 self.generate_argument_declarations(lenv, code)
1016 if self.needs_closure:
1017 code.putln("/* TODO: declare and create scope object */")
1018 code.put_var_declarations(lenv.var_entries)
1020 if not self.return_type.is_void:
1021 if self.return_type.is_pyobject:
1025 (self.return_type.declaration_code(
1026 Naming.retval_cname),
1028 tempvardecl_code = code.insertion_point()
1029 self.generate_keyword_list(code)
1030 # ----- Extern library function declarations
1031 lenv.generate_library_function_declarations(code)
1032 # ----- GIL acquisition
1033 acquire_gil = self.need_gil_acquisition(lenv)
1035 env.use_utility_code(force_init_threads_utility_code)
1036 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1037 # ----- Automatic lead-ins for certain special functions
1039 code.put_setup_refcount_context(self.entry.name)
1040 if is_getbuffer_slot:
1041 self.getbuffer_init(code)
1042 # ----- Fetch arguments
1043 self.generate_argument_parsing_code(env, code)
1044 # If an argument is assigned to in the body, we must
1045 # incref it to properly keep track of refcounts.
1046 for entry in lenv.arg_entries:
1047 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1048 code.put_var_incref(entry)
1049 # ----- Initialise local variables
1050 for entry in lenv.var_entries:
1051 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1052 code.put_init_var_to_py_none(entry)
1053 # ----- Initialise local buffer auxiliary variables
1054 for entry in lenv.var_entries + lenv.arg_entries:
1055 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1056 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1057 # ----- Check and convert arguments
1058 self.generate_argument_type_tests(code)
1059 # ----- Acquire buffer arguments
1060 for entry in lenv.arg_entries:
1061 if entry.type.is_buffer:
1062 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1063 # ----- Function body
1064 self.body.generate_execution_code(code)
1065 # ----- Default return value
1067 if self.return_type.is_pyobject:
1068 #if self.return_type.is_extension_type:
1069 # lhs = "(PyObject *)%s" % Naming.retval_cname
1071 lhs = Naming.retval_cname
1072 code.put_init_to_py_none(lhs, self.return_type)
1074 val = self.return_type.default_value
1076 code.putln("%s = %s;" % (Naming.retval_cname, val))
1077 # ----- Error cleanup
1078 if code.error_label in code.labels_used:
1079 code.put_goto(code.return_label)
1080 code.put_label(code.error_label)
1081 # cleanup temps the old way
1082 code.put_var_xdecrefs(lenv.temp_entries)
1083 # cleanup temps the new way
1084 for cname, type in code.funcstate.all_managed_temps():
1085 code.put_xdecref(cname, type)
1087 # Clean up buffers -- this calls a Python function
1088 # so need to save and restore error state
1089 buffers_present = len(lenv.buffer_entries) > 0
1091 code.globalstate.use_utility_code(restore_exception_utility_code)
1092 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1093 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1094 for entry in lenv.buffer_entries:
1095 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1096 #code.putln("%s = 0;" % entry.cname)
1097 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1099 err_val = self.error_value()
1100 exc_check = self.caller_will_check_exceptions()
1101 if err_val is not None or exc_check:
1102 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1104 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1105 % self.entry.qualified_name, 0)
1107 '__Pyx_WriteUnraisable("%s");' %
1108 self.entry.qualified_name)
1109 env.use_utility_code(unraisable_exception_utility_code)
1110 env.use_utility_code(restore_exception_utility_code)
1111 default_retval = self.return_type.default_value
1112 if err_val is None and default_retval:
1113 err_val = default_retval
1114 if err_val is not None:
1117 Naming.retval_cname,
1120 if is_getbuffer_slot:
1121 self.getbuffer_error_cleanup(code)
1123 # If we are using the non-error cleanup section we should
1124 # jump past it if we have an error. The if-test below determine
1125 # whether this section is used.
1126 if buffers_present or is_getbuffer_slot:
1127 code.put_goto(code.return_from_error_cleanup_label)
1130 # ----- Non-error return cleanup
1131 # If you add anything here, remember to add a condition to the
1132 # if-test above in the error block (so that it can jump past this
1134 code.put_label(code.return_label)
1135 for entry in lenv.buffer_entries:
1137 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1138 if is_getbuffer_slot:
1139 self.getbuffer_normal_cleanup(code)
1140 # ----- Return cleanup for both error and no-error return
1141 code.put_label(code.return_from_error_cleanup_label)
1142 if not Options.init_local_none:
1143 for entry in lenv.var_entries:
1144 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1145 entry.xdecref_cleanup = 1
1146 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1147 # Decref any increfed args
1148 for entry in lenv.arg_entries:
1149 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1150 code.put_var_decref(entry)
1152 # code.putln("/* TODO: decref scope object */")
1154 # This code is duplicated in ModuleNode.generate_module_init_func
1156 default_retval = self.return_type.default_value
1157 err_val = self.error_value()
1158 if err_val is None and default_retval:
1159 err_val = default_retval
1160 if self.return_type.is_pyobject:
1161 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1163 code.put_finish_refcount_context()
1166 code.putln("PyGILState_Release(_save);")
1168 if not self.return_type.is_void:
1169 code.putln("return %s;" % Naming.retval_cname)
1172 # ----- Go back and insert temp variable declarations
1173 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1174 tempvardecl_code.put_temp_declarations(code.funcstate)
1175 # ----- Python version
1176 code.exit_cfunc_scope()
1178 self.py_func.generate_function_definitions(env, code)
1179 self.generate_wrapper_functions(code)
1181 def declare_argument(self, env, arg):
1182 if arg.type.is_void:
1183 error(arg.pos, "Invalid use of 'void'")
1184 elif not arg.type.is_complete() and not arg.type.is_array:
1186 "Argument type '%s' is incomplete" % arg.type)
1187 return env.declare_arg(arg.name, arg.type, arg.pos)
1189 def generate_wrapper_functions(self, code):
1192 def generate_execution_code(self, code):
1193 # Evaluate and store argument default values
1194 for arg in self.args:
1195 default = arg.default
1197 if not default.is_literal:
1198 default.generate_evaluation_code(code)
1199 default.make_owned_reference(code)
1200 result = default.result_as(arg.type)
1203 arg.calculate_default_value_code(code),
1205 if arg.type.is_pyobject:
1206 code.put_giveref(default.result())
1207 default.generate_post_assignment_code(code)
1208 default.free_temps(code)
1209 # For Python class methods, create and store function object
1211 self.assmt.generate_execution_code(code)
1214 # Special code for the __getbuffer__ function
1216 def getbuffer_init(self, code):
1217 info = self.local_scope.arg_entries[1].cname
1218 # Python 3.0 betas have a bug in memoryview which makes it call
1219 # getbuffer with a NULL parameter. For now we work around this;
1220 # the following line should be removed when this bug is fixed.
1221 code.putln("if (%s == NULL) return 0;" % info)
1222 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1223 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1225 def getbuffer_error_cleanup(self, code):
1226 info = self.local_scope.arg_entries[1].cname
1227 code.put_gotref("%s->obj" % info)
1228 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1231 def getbuffer_normal_cleanup(self, code):
1232 info = self.local_scope.arg_entries[1].cname
1233 code.putln("if (%s->obj == Py_None) {" % info)
1234 code.put_gotref("Py_None")
1235 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1238 class CFuncDefNode(FuncDefNode):
1239 # C function definition.
1241 # modifiers ['inline']
1242 # visibility 'private' or 'public' or 'extern'
1243 # base_type CBaseTypeNode
1244 # declarator CDeclaratorNode
1247 # decorators [DecoratorNode] list of decorators
1249 # with_gil boolean Acquire GIL around body
1251 # py_func wrapper for calling from Python
1252 # overridable whether or not this is a cpdef function
1253 # inline_in_pxd whether this is an inline function in a pxd file
1255 child_attrs = ["base_type", "declarator", "body", "py_func"]
1257 inline_in_pxd = False
1259 directive_locals = {}
1261 def unqualified_name(self):
1262 return self.entry.name
1264 def analyse_declarations(self, env):
1265 if 'locals' in env.directives and env.directives['locals']:
1266 self.directive_locals = env.directives['locals']
1267 directive_locals = self.directive_locals
1268 base_type = self.base_type.analyse(env)
1269 # The 2 here is because we need both function and argument names.
1270 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1271 if not type.is_cfunction:
1273 "Suite attached to non-function declaration")
1274 # Remember the actual type according to the function header
1275 # written here, because the type in the symbol table entry
1276 # may be different if we're overriding a C method inherited
1277 # from the base type of an extension type.
1279 type.is_overridable = self.overridable
1280 declarator = self.declarator
1281 while not hasattr(declarator, 'args'):
1282 declarator = declarator.base
1283 self.args = declarator.args
1284 for formal_arg, type_arg in zip(self.args, type.args):
1285 formal_arg.type = type_arg.type
1286 formal_arg.name = type_arg.name
1287 formal_arg.cname = type_arg.cname
1288 name = name_declarator.name
1289 cname = name_declarator.cname
1290 self.entry = env.declare_cfunction(
1291 name, type, self.pos,
1292 cname = cname, visibility = self.visibility,
1293 defining = self.body is not None,
1294 api = self.api, modifiers = self.modifiers)
1295 self.entry.inline_func_in_pxd = self.inline_in_pxd
1296 self.return_type = type.return_type
1298 if self.overridable and not env.is_module_scope:
1299 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1300 # An error will be produced in the cdef function
1301 self.overridable = False
1303 if self.overridable:
1305 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1306 self.py_func = DefNode(pos = self.pos,
1307 name = self.entry.name,
1310 starstar_arg = None,
1312 body = py_func_body,
1314 self.py_func.is_module_scope = env.is_module_scope
1315 self.py_func.analyse_declarations(env)
1316 self.entry.as_variable = self.py_func.entry
1317 # Reset scope entry the above cfunction
1318 env.entries[name] = self.entry
1319 if not env.is_module_scope or Options.lookup_module_cpdef:
1320 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1321 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1323 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1325 args = self.type.args
1326 if omit_optional_args:
1327 args = args[:len(args) - self.type.optional_arg_count]
1328 arg_names = [arg.name for arg in args]
1330 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1332 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1333 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1334 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1335 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)
1336 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1338 def declare_arguments(self, env):
1339 for arg in self.type.args:
1341 error(arg.pos, "Missing argument name")
1342 self.declare_argument(env, arg)
1344 def need_gil_acquisition(self, lenv):
1345 return self.type.with_gil
1347 def gil_check(self, env):
1349 with_gil = type.with_gil
1350 if type.nogil and not with_gil:
1351 if type.return_type.is_pyobject:
1353 "Function with Python return type cannot be declared nogil")
1354 for entry in env.var_entries + env.temp_entries:
1355 if entry.type.is_pyobject:
1356 error(self.pos, "Function declared nogil has Python locals or temporaries")
1358 def analyse_expressions(self, env):
1359 self.local_scope.directives = env.directives
1360 if self.py_func is not None:
1361 # this will also analyse the default values
1362 self.py_func.analyse_expressions(env)
1364 self.analyse_default_values(env)
1366 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1369 visibility = self.entry.visibility
1370 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1371 arg_decls.append(arg.declaration_code())
1372 if with_dispatch and self.overridable:
1373 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1374 if type.optional_arg_count and with_opt_args:
1375 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1376 if type.has_varargs:
1377 arg_decls.append("...")
1379 arg_decls = ["void"]
1381 cname = self.entry.func_cname
1382 entity = type.function_header_code(cname, ', '.join(arg_decls))
1383 if visibility == 'public':
1384 dll_linkage = "DL_EXPORT"
1387 header = self.return_type.declaration_code(entity,
1388 dll_linkage = dll_linkage)
1389 if visibility == 'extern':
1390 storage_class = "%s " % Naming.extern_c_macro
1391 elif visibility == 'public':
1394 storage_class = "static "
1395 code.putln("%s%s %s {" % (
1397 ' '.join(self.modifiers).upper(), # macro forms
1400 def generate_argument_declarations(self, env, code):
1401 for arg in self.args:
1403 result = arg.calculate_default_value_code(code)
1404 code.putln('%s = %s;' % (
1405 arg.type.declaration_code(arg.cname), result))
1407 def generate_keyword_list(self, code):
1410 def generate_argument_parsing_code(self, env, code):
1412 if self.type.optional_arg_count:
1413 code.putln('if (%s) {' % Naming.optional_args_cname)
1414 for arg in self.args:
1416 # FIXME: simple name prefixing doesn't work when
1417 # argument name mangling is in place
1418 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1419 declarator = arg.declarator
1420 while not hasattr(declarator, 'name'):
1421 declarator = declarator.base
1422 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1424 for _ in range(self.type.optional_arg_count):
1428 def generate_argument_conversion_code(self, code):
1431 def generate_argument_type_tests(self, code):
1432 # Generate type tests for args whose type in a parent
1433 # class is a supertype of the declared type.
1434 for arg in self.type.args:
1435 if arg.needs_type_test:
1436 self.generate_arg_type_test(arg, code)
1438 def generate_arg_type_test(self, arg, code):
1439 # Generate type test for one argument.
1440 if arg.type.typeobj_is_available():
1441 typeptr_cname = arg.type.typeptr_cname
1442 arg_code = "((PyObject *)%s)" % arg.cname
1444 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1449 type.is_builtin_type,
1450 code.error_goto(arg.pos)))
1452 error(arg.pos, "Cannot test type of extern C class "
1453 "without type object name specification")
1455 def error_value(self):
1456 if self.return_type.is_pyobject:
1460 return self.entry.type.exception_value
1462 def caller_will_check_exceptions(self):
1463 return self.entry.type.exception_check
1465 def generate_wrapper_functions(self, code):
1466 # If the C signature of a function has changed, we need to generate
1467 # wrappers to put in the slots here.
1470 func_type = entry.type
1471 while entry.prev_entry is not None:
1473 entry = entry.prev_entry
1474 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1476 self.generate_function_header(code,
1478 with_dispatch = entry.type.is_overridable,
1479 with_opt_args = entry.type.optional_arg_count,
1480 cname = entry.func_cname)
1481 if not self.return_type.is_void:
1483 args = self.type.args
1484 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1485 if entry.type.is_overridable:
1486 arglist.append(Naming.skip_dispatch_cname)
1487 elif func_type.is_overridable:
1489 if entry.type.optional_arg_count:
1490 arglist.append(Naming.optional_args_cname)
1491 elif func_type.optional_arg_count:
1492 arglist.append('NULL')
1493 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1497 class PyArgDeclNode(Node):
1498 # Argument which must be a Python object (used
1499 # for * and ** arguments).
1502 # entry Symtab.Entry
1506 class DecoratorNode(Node):
1509 # decorator NameNode or CallNode
1510 child_attrs = ['decorator']
1513 class DefNode(FuncDefNode):
1514 # A Python function definition.
1516 # name string the Python name of the function
1517 # decorators [DecoratorNode] list of decorators
1518 # args [CArgDeclNode] formal arguments
1519 # star_arg PyArgDeclNode or None * argument
1520 # starstar_arg PyArgDeclNode or None ** argument
1521 # doc EncodedString or None
1524 # The following subnode is constructed internally
1525 # when the def statement is inside a Python class definition.
1527 # assmt AssignmentNode Function construction/assignment
1529 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1533 num_required_kw_args = 0
1534 reqd_kw_flags_cname = "0"
1540 def __init__(self, pos, **kwds):
1541 FuncDefNode.__init__(self, pos, **kwds)
1543 for arg in self.args:
1550 self.num_kwonly_args = k
1551 self.num_required_kw_args = rk
1552 self.num_required_args = r
1554 def as_cfunction(self, cfunc=None, scope=None):
1556 error(self.star_arg.pos, "cdef function cannot have star argument")
1557 if self.starstar_arg:
1558 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1561 for formal_arg in self.args:
1562 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1563 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1565 type = py_object_type,
1566 pos = formal_arg.pos))
1567 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1569 has_varargs = False,
1570 exception_value = None,
1571 exception_check = False,
1574 is_overridable = True)
1575 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1577 cfunc_type = cfunc.type
1578 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1579 error(self.pos, "wrong number of arguments")
1580 error(declarator.pos, "previous declaration here")
1581 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1582 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1583 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1584 formal_arg.type = type_arg.type
1585 formal_arg.name_declarator = name_declarator
1587 if cfunc_type.exception_value is None:
1588 exception_value = None
1590 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1591 declarator = CFuncDeclaratorNode(self.pos,
1592 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1594 has_varargs = False,
1595 exception_check = cfunc_type.exception_check,
1596 exception_value = exception_value,
1597 with_gil = cfunc_type.with_gil,
1598 nogil = cfunc_type.nogil)
1599 return CFuncDefNode(self.pos,
1601 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1602 declarator = declarator,
1605 overridable = cfunc_type.is_overridable,
1607 with_gil = cfunc_type.with_gil,
1608 nogil = cfunc_type.nogil,
1609 visibility = 'private',
1611 directive_locals = cfunc.directive_locals)
1613 def analyse_declarations(self, env):
1614 if 'locals' in env.directives:
1615 directive_locals = env.directives['locals']
1617 directive_locals = {}
1618 self.directive_locals = directive_locals
1619 for arg in self.args:
1620 if hasattr(arg, 'name'):
1622 name_declarator = None
1624 base_type = arg.base_type.analyse(env)
1625 name_declarator, type = \
1626 arg.declarator.analyse(base_type, env)
1627 arg.name = name_declarator.name
1628 if arg.name in directive_locals:
1629 type_node = directive_locals[arg.name]
1630 other_type = type_node.analyse_as_type(env)
1631 if other_type is None:
1632 error(type_node.pos, "Not a type")
1633 elif (type is not PyrexTypes.py_object_type
1634 and not type.same_as(other_type)):
1635 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1636 error(type_node.pos, "Previous declaration here")
1639 if name_declarator and name_declarator.cname:
1641 "Python function argument cannot have C name specification")
1642 arg.type = type.as_argument_type()
1644 arg.needs_conversion = 0
1645 arg.needs_type_test = 0
1647 if arg.not_none and not arg.type.is_extension_type:
1649 "Only extension type arguments can have 'not None'")
1650 self.declare_pyfunction(env)
1651 self.analyse_signature(env)
1652 self.return_type = self.entry.signature.return_type()
1654 def analyse_signature(self, env):
1655 any_type_tests_needed = 0
1656 # Use the simpler calling signature for zero- and one-argument functions.
1657 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1658 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1659 if len(self.args) == 0:
1660 self.entry.signature = TypeSlots.pyfunction_noargs
1661 elif len(self.args) == 1:
1662 if self.args[0].default is None and not self.args[0].kw_only:
1663 self.entry.signature = TypeSlots.pyfunction_onearg
1664 elif self.entry.signature is TypeSlots.pymethod_signature:
1665 if len(self.args) == 1:
1666 self.entry.signature = TypeSlots.unaryfunc
1667 elif len(self.args) == 2:
1668 if self.args[1].default is None and not self.args[1].kw_only:
1669 self.entry.signature = TypeSlots.ibinaryfunc
1670 elif self.entry.is_special:
1671 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1672 sig = self.entry.signature
1673 nfixed = sig.num_fixed_args()
1674 for i in range(nfixed):
1675 if i < len(self.args):
1678 if sig.is_self_arg(i):
1680 arg.hdr_type = arg.type = env.parent_type
1681 arg.needs_conversion = 0
1683 arg.hdr_type = sig.fixed_arg_type(i)
1684 if not arg.type.same_as(arg.hdr_type):
1685 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1686 arg.needs_type_test = 1
1687 any_type_tests_needed = 1
1689 arg.needs_conversion = 1
1690 if arg.needs_conversion:
1691 arg.hdr_cname = Naming.arg_prefix + arg.name
1693 arg.hdr_cname = Naming.var_prefix + arg.name
1695 self.bad_signature()
1697 if nfixed < len(self.args):
1698 if not sig.has_generic_args:
1699 self.bad_signature()
1700 for arg in self.args:
1701 if arg.is_generic and \
1702 (arg.type.is_extension_type or arg.type.is_builtin_type):
1703 arg.needs_type_test = 1
1704 any_type_tests_needed = 1
1705 if any_type_tests_needed:
1706 env.use_utility_code(arg_type_test_utility_code)
1708 def bad_signature(self):
1709 sig = self.entry.signature
1710 expected_str = "%d" % sig.num_fixed_args()
1711 if sig.has_generic_args:
1712 expected_str = expected_str + " or more"
1714 if name.startswith("__") and name.endswith("__"):
1715 desc = "Special method"
1719 "%s %s has wrong number of arguments "
1720 "(%d declared, %s expected)" % (
1721 desc, self.name, len(self.args), expected_str))
1723 def signature_has_nongeneric_args(self):
1724 argcount = len(self.args)
1725 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1729 def signature_has_generic_args(self):
1730 return self.entry.signature.has_generic_args
1732 def declare_pyfunction(self, env):
1733 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1735 entry = env.lookup_here(self.name)
1736 if entry and entry.type.is_cfunction and not self.is_wrapper:
1737 warning(self.pos, "Overriding cdef method with def method.", 5)
1738 entry = env.declare_pyfunction(self.name, self.pos)
1740 prefix = env.scope_prefix
1741 entry.func_cname = \
1742 Naming.pyfunc_prefix + prefix + name
1743 entry.pymethdef_cname = \
1744 Naming.pymethdef_prefix + prefix + name
1745 if Options.docstrings:
1746 entry.doc = embed_position(self.pos, self.doc)
1748 Naming.funcdoc_prefix + prefix + name
1752 def declare_arguments(self, env):
1753 for arg in self.args:
1755 error(arg.pos, "Missing argument name")
1756 if arg.needs_conversion:
1757 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1758 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1759 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1760 if arg.type.is_pyobject:
1761 arg.entry.init = "0"
1762 arg.entry.init_to_none = 0
1764 arg.entry = self.declare_argument(env, arg)
1766 arg.entry.is_self_arg = arg.is_self_arg
1768 if arg.is_self_arg or \
1769 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1770 arg.entry.is_declared_generic = 1
1771 self.declare_python_arg(env, self.star_arg)
1772 self.declare_python_arg(env, self.starstar_arg)
1774 def declare_python_arg(self, env, arg):
1776 entry = env.declare_var(arg.name,
1777 PyrexTypes.py_object_type, arg.pos)
1780 entry.init_to_none = 0
1781 entry.xdecref_cleanup = 1
1783 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1785 def analyse_expressions(self, env):
1786 self.local_scope.directives = env.directives
1787 self.analyse_default_values(env)
1788 if env.is_py_class_scope:
1789 self.synthesize_assignment_node(env)
1791 def synthesize_assignment_node(self, env):
1793 self.assmt = SingleAssignmentNode(self.pos,
1794 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1795 rhs = ExprNodes.UnboundMethodNode(self.pos,
1796 function = ExprNodes.PyCFunctionNode(self.pos,
1797 pymethdef_cname = self.entry.pymethdef_cname)))
1798 self.assmt.analyse_declarations(env)
1799 self.assmt.analyse_expressions(env)
1801 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1803 sig = self.entry.signature
1804 if sig.has_dummy_arg:
1805 arg_code_list.append(
1806 "PyObject *%s" % Naming.self_cname)
1807 for arg in self.args:
1808 if not arg.is_generic:
1810 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1812 arg_code_list.append(
1813 arg.hdr_type.declaration_code(arg.hdr_cname))
1814 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1815 arg_code_list.append("PyObject *unused")
1816 if sig.has_generic_args:
1817 arg_code_list.append(
1818 "PyObject *%s, PyObject *%s"
1819 % (Naming.args_cname, Naming.kwds_cname))
1820 arg_code = ", ".join(arg_code_list)
1821 dc = self.return_type.declaration_code(self.entry.func_cname)
1822 header = "static %s(%s)" % (dc, arg_code)
1823 code.putln("%s; /*proto*/" % header)
1826 if self.entry.doc and Options.docstrings:
1827 docstr = self.entry.doc
1828 if not isinstance(docstr, str):
1829 docstr = docstr.utf8encode()
1831 'static char %s[] = "%s";' % (
1832 self.entry.doc_cname,
1833 split_docstring(escape_byte_string(docstr))))
1836 "static PyMethodDef %s = " %
1837 self.entry.pymethdef_cname)
1838 code.put_pymethoddef(self.entry, ";")
1839 code.putln("%s {" % header)
1841 def generate_argument_declarations(self, env, code):
1842 for arg in self.args:
1843 if arg.is_generic: # or arg.needs_conversion:
1844 if arg.needs_conversion:
1845 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1847 code.put_var_declaration(arg.entry)
1849 def generate_keyword_list(self, code):
1850 if self.signature_has_generic_args() and \
1851 self.signature_has_nongeneric_args():
1853 "static PyObject **%s[] = {" %
1854 Naming.pykwdlist_cname)
1855 for arg in self.args:
1857 pystring_cname = code.intern_identifier(arg.name)
1858 code.put('&%s,' % pystring_cname)
1861 def generate_argument_parsing_code(self, env, code):
1862 # Generate PyArg_ParseTuple call for generic
1863 # arguments, if any.
1864 if self.entry.signature.has_dummy_arg:
1865 # get rid of unused argument warning
1866 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1868 old_error_label = code.new_error_label()
1869 our_error_label = code.error_label
1870 end_label = code.new_label("argument_unpacking_done")
1872 has_kwonly_args = self.num_kwonly_args > 0
1873 has_star_or_kw_args = self.star_arg is not None \
1874 or self.starstar_arg is not None or has_kwonly_args
1876 if not self.signature_has_generic_args():
1877 if has_star_or_kw_args:
1878 error(self.pos, "This method cannot have * or keyword arguments")
1879 self.generate_argument_conversion_code(code)
1881 elif not self.signature_has_nongeneric_args():
1882 # func(*args) or func(**kw) or func(*args, **kw)
1883 self.generate_stararg_copy_code(code)
1886 positional_args = []
1889 for arg in self.args:
1890 arg_entry = arg.entry
1894 if not arg.is_self_arg:
1896 kw_only_args.append(arg)
1898 positional_args.append(arg)
1900 kw_only_args.append(arg)
1903 error(arg.pos, "Non-default argument following default argument")
1904 elif not arg.is_self_arg:
1905 positional_args.append(arg)
1907 self.generate_tuple_and_keyword_parsing_code(
1908 positional_args, kw_only_args, end_label, code)
1910 code.error_label = old_error_label
1911 if code.label_used(our_error_label):
1912 if not code.label_used(end_label):
1913 code.put_goto(end_label)
1914 code.put_label(our_error_label)
1915 if has_star_or_kw_args:
1916 self.generate_arg_decref(self.star_arg, code)
1917 if self.starstar_arg:
1918 if self.starstar_arg.entry.xdecref_cleanup:
1919 code.put_var_xdecref(self.starstar_arg.entry)
1921 code.put_var_decref(self.starstar_arg.entry)
1922 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1923 code.putln("return %s;" % self.error_value())
1924 if code.label_used(end_label):
1925 code.put_label(end_label)
1927 def generate_arg_assignment(self, arg, item, code):
1928 if arg.type.is_pyobject:
1930 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1931 code.putln("%s = %s;" % (arg.entry.cname, item))
1933 func = arg.type.from_py_function
1935 code.putln("%s = %s(%s); %s" % (
1939 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1941 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1943 def generate_arg_xdecref(self, arg, code):
1945 code.put_var_xdecref(arg.entry)
1947 def generate_arg_decref(self, arg, code):
1949 code.put_var_decref(arg.entry)
1951 def generate_stararg_copy_code(self, code):
1952 if not self.star_arg:
1953 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1954 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1956 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1957 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1960 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1962 if self.starstar_arg:
1964 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1966 kwarg_check = "%s" % Naming.kwds_cname
1968 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1969 Naming.kwds_cname, Naming.kwds_cname)
1971 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1972 kwarg_check, Naming.kwds_cname, self.name,
1973 bool(self.starstar_arg), self.error_value()))
1975 if self.starstar_arg:
1976 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1977 self.starstar_arg.entry.cname,
1980 code.putln("if (unlikely(!%s)) return %s;" % (
1981 self.starstar_arg.entry.cname, self.error_value()))
1982 self.starstar_arg.entry.xdecref_cleanup = 0
1983 code.put_gotref(self.starstar_arg.entry.cname)
1987 code.put_incref(Naming.args_cname, py_object_type)
1988 code.putln("%s = %s;" % (
1989 self.star_arg.entry.cname,
1991 self.star_arg.entry.xdecref_cleanup = 0
1993 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1994 kw_only_args, success_label, code):
1995 argtuple_error_label = code.new_label("argtuple_error")
1997 min_positional_args = self.num_required_args - self.num_required_kw_args
1998 if len(self.args) > 0 and self.args[0].is_self_arg:
1999 min_positional_args -= 1
2000 max_positional_args = len(positional_args)
2001 has_fixed_positional_count = not self.star_arg and \
2002 min_positional_args == max_positional_args
2004 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2005 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2006 if self.num_required_kw_args:
2007 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2009 if self.starstar_arg or self.star_arg:
2010 self.generate_stararg_init_code(max_positional_args, code)
2012 # --- optimised code when we receive keyword arguments
2013 if self.num_required_kw_args:
2014 likely_hint = "likely"
2016 likely_hint = "unlikely"
2017 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2018 self.generate_keyword_unpacking_code(
2019 min_positional_args, max_positional_args,
2020 has_fixed_positional_count,
2021 positional_args, kw_only_args, argtuple_error_label, code)
2023 # --- optimised code when we do not receive any keyword arguments
2024 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2025 # Python raises arg tuple related errors first, so we must
2026 # check the length here
2027 if min_positional_args == max_positional_args and not self.star_arg:
2031 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2032 Naming.args_cname, compare, min_positional_args))
2033 code.put_goto(argtuple_error_label)
2035 if self.num_required_kw_args:
2036 # pure error case: keywords required but not passed
2037 if max_positional_args > min_positional_args and not self.star_arg:
2038 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2039 Naming.args_cname, max_positional_args))
2040 code.put_goto(argtuple_error_label)
2041 code.putln('} else {')
2042 for i, arg in enumerate(kw_only_args):
2044 pystring_cname = code.intern_identifier(arg.name)
2045 # required keyword-only argument missing
2046 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2047 self.name.utf8encode(),
2049 code.putln(code.error_goto(self.pos))
2052 elif min_positional_args == max_positional_args:
2053 # parse the exact number of positional arguments from the
2055 code.putln('} else {')
2056 for i, arg in enumerate(positional_args):
2057 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2058 self.generate_arg_assignment(arg, item, code)
2059 self.generate_arg_default_assignments(code)
2062 # parse the positional arguments from the variable length
2064 code.putln('} else {')
2065 self.generate_arg_default_assignments(code)
2066 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2068 code.putln('default:')
2069 reversed_args = list(enumerate(positional_args))[::-1]
2070 for i, arg in reversed_args:
2071 if i >= min_positional_args-1:
2072 if min_positional_args > 1:
2073 code.putln('case %2d:' % (i+1)) # pure code beautification
2075 code.put('case %2d: ' % (i+1))
2076 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2077 self.generate_arg_assignment(arg, item, code)
2078 if min_positional_args == 0:
2079 code.put('case 0: ')
2080 code.putln('break;')
2082 if min_positional_args:
2083 for i in range(min_positional_args-1, -1, -1):
2084 code.putln('case %2d:' % i)
2085 code.put_goto(argtuple_error_label)
2087 code.put('default: ')
2088 code.put_goto(argtuple_error_label)
2093 if code.label_used(argtuple_error_label):
2094 code.put_goto(success_label)
2095 code.put_label(argtuple_error_label)
2096 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2097 self.name.utf8encode(), has_fixed_positional_count,
2098 min_positional_args, max_positional_args,
2100 code.putln(code.error_goto(self.pos))
2102 def generate_arg_default_assignments(self, code):
2103 for arg in self.args:
2104 if arg.is_generic and arg.default:
2108 arg.calculate_default_value_code(code)))
2110 def generate_stararg_init_code(self, max_positional_args, code):
2111 if self.starstar_arg:
2112 self.starstar_arg.entry.xdecref_cleanup = 0
2113 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2114 self.starstar_arg.entry.cname,
2115 self.starstar_arg.entry.cname,
2116 self.error_value()))
2117 code.put_gotref(self.starstar_arg.entry.cname)
2119 self.star_arg.entry.xdecref_cleanup = 0
2120 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2122 max_positional_args))
2123 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2124 self.star_arg.entry.cname, Naming.args_cname,
2125 max_positional_args, Naming.args_cname))
2126 code.put_gotref(self.star_arg.entry.cname)
2127 if self.starstar_arg:
2129 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2130 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2131 code.putln('return %s;' % self.error_value())
2134 code.putln("if (unlikely(!%s)) return %s;" % (
2135 self.star_arg.entry.cname, self.error_value()))
2136 code.putln('} else {')
2137 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2138 code.put_incref(Naming.empty_tuple, py_object_type)
2141 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2142 has_fixed_positional_count, positional_args,
2143 kw_only_args, argtuple_error_label, code):
2144 all_args = tuple(positional_args) + tuple(kw_only_args)
2145 max_args = len(all_args)
2148 for i, arg in enumerate(all_args):
2149 if arg.default and arg.type.is_pyobject:
2150 default_value = arg.calculate_default_value_code(code)
2151 if arg.type is not PyrexTypes.py_object_type:
2152 default_value = "(PyObject*)"+default_value
2153 default_args.append((i, default_value))
2155 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2157 # it looks funny to separate the init-to-0 from setting the
2158 # default value, but C89 needs this
2159 code.putln("PyObject* values[%d] = {%s};" % (
2160 max_args, ','.join(['0']*max_args)))
2161 for i, default_value in default_args:
2162 code.putln('values[%d] = %s;' % (i, default_value))
2164 # parse the tuple and check that it's not too long
2165 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2167 code.putln('default:')
2168 for i in range(max_positional_args-1, -1, -1):
2169 code.put('case %2d: ' % (i+1))
2170 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2171 i, Naming.args_cname, i))
2172 code.putln('case 0: break;')
2173 if not self.star_arg:
2174 code.put('default: ') # more arguments than allowed
2175 code.put_goto(argtuple_error_label)
2178 # now fill up the positional/required arguments with values
2180 if self.num_required_args or max_positional_args > 0:
2181 last_required_arg = -1
2182 for i, arg in enumerate(all_args):
2184 last_required_arg = i
2185 if last_required_arg < max_positional_args:
2186 last_required_arg = max_positional_args-1
2187 num_required_args = self.num_required_args
2188 if max_positional_args > 0:
2189 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2190 for i, arg in enumerate(all_args[:last_required_arg+1]):
2191 if max_positional_args > 0 and i <= max_positional_args:
2192 if self.star_arg and i == max_positional_args:
2193 code.putln('default:')
2195 code.putln('case %2d:' % i)
2196 pystring_cname = code.intern_identifier(arg.name)
2199 # handled separately below
2201 code.putln('if (kw_args > %d) {' % num_required_args)
2202 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2203 Naming.kwds_cname, pystring_cname))
2204 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2207 num_required_args -= 1
2208 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2209 i, Naming.kwds_cname, pystring_cname))
2210 code.putln('if (likely(values[%d])) kw_args--;' % i);
2211 if i < min_positional_args:
2213 # special case: we know arg 0 is missing
2215 code.put_goto(argtuple_error_label)
2217 # print the correct number of values (args or
2218 # kwargs) that were passed into positional
2219 # arguments up to this point
2220 code.putln('else {')
2221 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2222 self.name.utf8encode(), has_fixed_positional_count,
2223 min_positional_args, max_positional_args, i))
2224 code.putln(code.error_goto(self.pos))
2227 code.putln('else {')
2228 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2229 self.name.utf8encode(), pystring_cname))
2230 code.putln(code.error_goto(self.pos))
2232 if max_positional_args > 0:
2235 if kw_only_args and not self.starstar_arg:
2236 # unpack optional keyword-only arguments
2237 # checking for interned strings in a dict is faster than iterating
2238 # but it's too likely that we must iterate if we expect **kwargs
2240 for i, arg in enumerate(all_args[max_positional_args:]):
2241 if not arg.kw_only or not arg.default:
2243 optional_args.append((i+max_positional_args, arg))
2245 # this mimics an unrolled loop so that we can "break" out of it
2246 code.putln('while (kw_args > 0) {')
2247 code.putln('PyObject* value;')
2248 for i, arg in optional_args:
2249 pystring_cname = code.intern_identifier(arg.name)
2251 'value = PyDict_GetItem(%s, %s);' % (
2252 Naming.kwds_cname, pystring_cname))
2254 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2255 code.putln('break;')
2258 code.putln('if (unlikely(kw_args > 0)) {')
2259 # non-positional/-required kw args left in dict: default args,
2260 # kw-only args, **kwargs or error
2262 # This is sort of a catch-all: except for checking required
2263 # arguments, this will always do the right thing for unpacking
2264 # keyword arguments, so that we can concentrate on optimising
2265 # common cases above.
2266 if max_positional_args == 0:
2269 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2270 Naming.args_cname, max_positional_args,
2271 Naming.args_cname, max_positional_args))
2272 pos_arg_count = "used_pos_args"
2274 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2275 code.globalstate.use_utility_code(parse_keywords_utility_code)
2277 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2279 Naming.pykwdlist_cname,
2280 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2282 self.name.utf8encode()))
2283 code.putln(code.error_goto(self.pos))
2286 # convert arg values to their final type and assign them
2287 for i, arg in enumerate(all_args):
2288 if arg.default and not arg.type.is_pyobject:
2289 code.putln("if (values[%d]) {" % i)
2290 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2291 if arg.default and not arg.type.is_pyobject:
2292 code.putln('} else {')
2296 arg.calculate_default_value_code(code)))
2299 def generate_argument_conversion_code(self, code):
2300 # Generate code to convert arguments from
2301 # signature type to declared type, if needed.
2302 for arg in self.args:
2303 if arg.needs_conversion:
2304 self.generate_arg_conversion(arg, code)
2306 def generate_arg_conversion(self, arg, code):
2307 # Generate conversion code for one argument.
2308 old_type = arg.hdr_type
2310 if old_type.is_pyobject:
2312 code.putln("if (%s) {" % arg.hdr_cname)
2314 code.putln("assert(%s); {" % arg.hdr_cname)
2315 self.generate_arg_conversion_from_pyobject(arg, code)
2317 elif new_type.is_pyobject:
2318 self.generate_arg_conversion_to_pyobject(arg, code)
2320 if new_type.assignable_from(old_type):
2322 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2325 "Cannot convert 1 argument from '%s' to '%s'" %
2326 (old_type, new_type))
2328 def generate_arg_conversion_from_pyobject(self, arg, code):
2330 func = new_type.from_py_function
2331 # copied from CoerceFromPyTypeNode
2333 code.putln("%s = %s(%s); %s" % (
2337 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2340 "Cannot convert Python object argument to type '%s'"
2343 def generate_arg_conversion_to_pyobject(self, arg, code):
2344 old_type = arg.hdr_type
2345 func = old_type.to_py_function
2347 code.putln("%s = %s(%s); %s" % (
2351 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2352 code.put_var_gotref(arg.entry)
2355 "Cannot convert argument of type '%s' to Python object"
2358 def generate_argument_type_tests(self, code):
2359 # Generate type tests for args whose signature
2360 # type is PyObject * and whose declared type is
2361 # a subtype thereof.
2362 for arg in self.args:
2363 if arg.needs_type_test:
2364 self.generate_arg_type_test(arg, code)
2366 def generate_arg_type_test(self, arg, code):
2367 # Generate type test for one argument.
2368 if arg.type.typeobj_is_available():
2369 typeptr_cname = arg.type.typeptr_cname
2370 arg_code = "((PyObject *)%s)" % arg.entry.cname
2372 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2377 arg.type.is_builtin_type,
2378 code.error_goto(arg.pos)))
2380 error(arg.pos, "Cannot test type of extern C class "
2381 "without type object name specification")
2383 def error_value(self):
2384 return self.entry.signature.error_value
2386 def caller_will_check_exceptions(self):
2389 class OverrideCheckNode(StatNode):
2390 # A Node for dispatching to the def method if it
2399 child_attrs = ['body']
2403 def analyse_expressions(self, env):
2404 self.args = env.arg_entries
2405 if self.py_func.is_module_scope:
2410 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2411 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2412 call_node = ExprNodes.SimpleCallNode(self.pos,
2413 function=self.func_node,
2414 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2415 self.body = ReturnStatNode(self.pos, value=call_node)
2416 self.body.analyse_expressions(env)
2418 def generate_execution_code(self, code):
2419 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2420 # Check to see if we are an extension type
2421 if self.py_func.is_module_scope:
2422 self_arg = "((PyObject *)%s)" % Naming.module_cname
2424 self_arg = "((PyObject *)%s)" % self.args[0].cname
2425 code.putln("/* Check if called by wrapper */")
2426 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2427 code.putln("/* Check if overriden in Python */")
2428 if self.py_func.is_module_scope:
2429 code.putln("else {")
2431 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2432 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2433 # need to get attribute manually--scope would return cdef method
2434 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2435 self.func_node.result(), self_arg, interned_attr_cname, err))
2436 code.put_gotref(self.func_node.py_result())
2437 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2438 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2439 self.func_node.result(), self.py_func.entry.func_cname)
2440 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2441 self.body.generate_execution_code(code)
2443 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2446 class ClassDefNode(StatNode, BlockNode):
2449 class PyClassDefNode(ClassDefNode):
2450 # A Python class definition.
2452 # name EncodedString Name of the class
2453 # doc string or None
2454 # body StatNode Attribute definition code
2455 # entry Symtab.Entry
2456 # scope PyClassScope
2458 # The following subnodes are constructed internally:
2460 # dict DictNode Class dictionary
2461 # classobj ClassNode Class object
2462 # target NameNode Variable to assign class object to
2464 child_attrs = ["body", "dict", "classobj", "target"]
2466 def __init__(self, pos, name, bases, doc, body):
2467 StatNode.__init__(self, pos)
2472 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2473 if self.doc and Options.docstrings:
2474 doc = embed_position(self.pos, self.doc)
2475 doc_node = ExprNodes.StringNode(pos, value = doc)
2478 self.classobj = ExprNodes.ClassNode(pos, name = name,
2479 bases = bases, dict = self.dict, doc = doc_node)
2480 self.target = ExprNodes.NameNode(pos, name = name)
2482 def as_cclass(self):
2484 Return this node as if it were declared as an extension class
2486 bases = self.classobj.bases.args
2488 base_class_name = None
2489 base_class_module = None
2490 elif len(bases) == 1:
2493 from ExprNodes import AttributeNode, NameNode
2494 while isinstance(base, AttributeNode):
2495 path.insert(0, base.attribute)
2497 if isinstance(base, NameNode):
2498 path.insert(0, base.name)
2499 base_class_name = path[-1]
2501 base_class_module = u'.'.join(path[:-1])
2503 base_class_module = None
2505 error(self.classobj.bases.args.pos, "Invalid base class")
2507 error(self.classobj.bases.args.pos, "C class may only have one base class")
2510 return CClassDefNode(self.pos,
2511 visibility = 'private',
2513 class_name = self.name,
2514 base_class_module = base_class_module,
2515 base_class_name = base_class_name,
2520 def create_scope(self, env):
2522 while env.is_py_class_scope or env.is_c_class_scope:
2523 env = env.outer_scope
2524 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2527 def analyse_declarations(self, env):
2528 self.target.analyse_target_declaration(env)
2529 cenv = self.create_scope(env)
2530 cenv.class_obj_cname = self.target.entry.cname
2531 self.body.analyse_declarations(cenv)
2533 def analyse_expressions(self, env):
2534 self.dict.analyse_expressions(env)
2535 self.classobj.analyse_expressions(env)
2536 genv = env.global_scope()
2538 self.body.analyse_expressions(cenv)
2539 self.target.analyse_target_expression(env, self.classobj)
2540 self.dict.release_temp(env)
2541 #self.classobj.release_temp(env)
2542 #self.target.release_target_temp(env)
2544 def generate_function_definitions(self, env, code):
2545 self.body.generate_function_definitions(self.scope, code)
2547 def generate_execution_code(self, code):
2548 code.pyclass_stack.append(self)
2550 self.dict.generate_evaluation_code(code)
2551 self.classobj.generate_evaluation_code(code)
2552 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2553 self.body.generate_execution_code(code)
2554 self.target.generate_assignment_code(self.classobj, code)
2555 self.dict.generate_disposal_code(code)
2556 self.dict.free_temps(code)
2557 code.pyclass_stack.pop()
2560 class CClassDefNode(ClassDefNode):
2561 # An extension type definition.
2563 # visibility 'private' or 'public' or 'extern'
2564 # typedef_flag boolean
2566 # module_name string or None For import of extern type objects
2567 # class_name string Unqualified name of class
2568 # as_name string or None Name to declare as in this scope
2569 # base_class_module string or None Module containing the base class
2570 # base_class_name string or None Name of the base class
2571 # objstruct_name string or None Specified C name of object struct
2572 # typeobj_name string or None Specified C name of type object
2573 # in_pxd boolean Is in a .pxd file
2574 # doc string or None
2575 # body StatNode or None
2576 # entry Symtab.Entry
2577 # base_type PyExtensionType or None
2578 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2579 # buffer_defaults_pos
2581 child_attrs = ["body"]
2582 buffer_defaults_node = None
2583 buffer_defaults_pos = None
2584 typedef_flag = False
2586 objstruct_name = None
2589 def analyse_declarations(self, env):
2590 #print "CClassDefNode.analyse_declarations:", self.class_name
2591 #print "...visibility =", self.visibility
2592 #print "...module_name =", self.module_name
2595 if self.buffer_defaults_node:
2596 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2597 env, [], self.buffer_defaults_node,
2598 need_complete=False)
2600 buffer_defaults = None
2602 if env.in_cinclude and not self.objstruct_name:
2603 error(self.pos, "Object struct name specification required for "
2604 "C class defined in 'extern from' block")
2605 self.base_type = None
2606 # Now that module imports are cached, we need to
2607 # import the modules for extern classes.
2608 if self.module_name:
2610 for module in env.cimported_modules:
2611 if module.name == self.module_name:
2612 self.module = module
2613 if self.module is None:
2614 self.module = ModuleScope(self.module_name, None, env.context)
2615 self.module.has_extern_class = 1
2616 env.add_imported_module(self.module)
2618 if self.base_class_name:
2619 if self.base_class_module:
2620 base_class_scope = env.find_module(self.base_class_module, self.pos)
2622 base_class_scope = env
2623 if self.base_class_name == 'object':
2624 # extension classes are special and don't need to inherit from object
2625 if base_class_scope is None or base_class_scope.lookup('object') is None:
2626 self.base_class_name = None
2627 self.base_class_module = None
2628 base_class_scope = None
2629 if base_class_scope:
2630 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2631 if base_class_entry:
2632 if not base_class_entry.is_type:
2633 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2634 elif not base_class_entry.type.is_extension_type:
2635 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2636 elif not base_class_entry.type.is_complete():
2637 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2639 self.base_type = base_class_entry.type
2640 has_body = self.body is not None
2641 if self.module_name and self.visibility != 'extern':
2642 module_path = self.module_name.split(".")
2643 home_scope = env.find_imported_module(module_path, self.pos)
2649 if self.visibility == 'extern':
2650 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2651 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2653 self.entry = home_scope.declare_c_class(
2654 name = self.class_name,
2656 defining = has_body and self.in_pxd,
2657 implementing = has_body and not self.in_pxd,
2658 module_name = self.module_name,
2659 base_type = self.base_type,
2660 objstruct_cname = self.objstruct_name,
2661 typeobj_cname = self.typeobj_name,
2662 visibility = self.visibility,
2663 typedef_flag = self.typedef_flag,
2665 buffer_defaults = buffer_defaults)
2666 if home_scope is not env and self.visibility == 'extern':
2667 env.add_imported_entry(self.class_name, self.entry, pos)
2668 scope = self.entry.type.scope
2670 if self.doc and Options.docstrings:
2671 scope.doc = embed_position(self.pos, self.doc)
2674 self.body.analyse_declarations(scope)
2678 scope.implemented = 1
2679 env.allocate_vtable_names(self.entry)
2681 def analyse_expressions(self, env):
2683 scope = self.entry.type.scope
2684 self.body.analyse_expressions(scope)
2686 def generate_function_definitions(self, env, code):
2688 self.body.generate_function_definitions(
2689 self.entry.type.scope, code)
2691 def generate_execution_code(self, code):
2692 # This is needed to generate evaluation code for
2693 # default values of method arguments.
2695 self.body.generate_execution_code(code)
2697 def annotate(self, code):
2699 self.body.annotate(code)
2702 class PropertyNode(StatNode):
2703 # Definition of a property in an extension type.
2706 # doc EncodedString or None Doc string
2709 child_attrs = ["body"]
2711 def analyse_declarations(self, env):
2712 entry = env.declare_property(self.name, self.doc, self.pos)
2714 self.body.analyse_declarations(entry.scope)
2716 def analyse_expressions(self, env):
2717 self.body.analyse_expressions(env)
2719 def generate_function_definitions(self, env, code):
2720 self.body.generate_function_definitions(env, code)
2722 def generate_execution_code(self, code):
2725 def annotate(self, code):
2726 self.body.annotate(code)
2729 class GlobalNode(StatNode):
2730 # Global variable declaration.
2736 def analyse_declarations(self, env):
2737 for name in self.names:
2738 env.declare_global(name, self.pos)
2740 def analyse_expressions(self, env):
2743 def generate_execution_code(self, code):
2747 class ExprStatNode(StatNode):
2748 # Expression used as a statement.
2752 child_attrs = ["expr"]
2754 def analyse_declarations(self, env):
2756 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2757 func = self.expr.function.as_cython_attribute()
2758 if func == u'declare':
2759 args, kwds = self.expr.explicit_args_kwds()
2761 error(self.expr.pos, "Variable names must be specified.")
2762 for var, type_node in kwds.key_value_pairs:
2763 type = type_node.analyse_as_type(env)
2765 error(type_node.pos, "Unknown type")
2767 env.declare_var(var.value, type, var.pos, is_cdef = True)
2768 self.__class__ = PassStatNode
2770 def analyse_expressions(self, env):
2771 self.expr.analyse_expressions(env)
2772 self.expr.release_temp(env)
2774 def generate_execution_code(self, code):
2775 self.expr.generate_evaluation_code(code)
2776 if not self.expr.is_temp and self.expr.result():
2777 code.putln("%s;" % self.expr.result())
2778 self.expr.generate_disposal_code(code)
2779 self.expr.free_temps(code)
2781 def annotate(self, code):
2782 self.expr.annotate(code)
2785 class AssignmentNode(StatNode):
2786 # Abstract base class for assignment nodes.
2788 # The analyse_expressions and generate_execution_code
2789 # phases of assignments are split into two sub-phases
2790 # each, to enable all the right hand sides of a
2791 # parallel assignment to be evaluated before assigning
2792 # to any of the left hand sides.
2794 def analyse_expressions(self, env):
2795 self.analyse_types(env)
2796 self.allocate_rhs_temps(env)
2797 self.allocate_lhs_temps(env)
2799 # def analyse_expressions(self, env):
2800 # self.analyse_expressions_1(env)
2801 # self.analyse_expressions_2(env)
2803 def generate_execution_code(self, code):
2804 self.generate_rhs_evaluation_code(code)
2805 self.generate_assignment_code(code)
2808 class SingleAssignmentNode(AssignmentNode):
2809 # The simplest case:
2813 # lhs ExprNode Left hand side
2814 # rhs ExprNode Right hand side
2815 # first bool Is this guaranteed the first assignment to lhs?
2817 child_attrs = ["lhs", "rhs"]
2819 declaration_only = False
2821 def analyse_declarations(self, env):
2824 # handle declarations of the form x = cython.foo()
2825 if isinstance(self.rhs, ExprNodes.CallNode):
2826 func_name = self.rhs.function.as_cython_attribute()
2828 args, kwds = self.rhs.explicit_args_kwds()
2830 if func_name in ['declare', 'typedef']:
2831 if len(args) > 2 or kwds is not None:
2832 error(rhs.pos, "Can only declare one type at a time.")
2834 type = args[0].analyse_as_type(env)
2836 error(args[0].pos, "Unknown type")
2839 if func_name == 'declare':
2840 if isinstance(lhs, ExprNodes.NameNode):
2841 vars = [(lhs.name, lhs.pos)]
2842 elif isinstance(lhs, ExprNodes.TupleNode):
2843 vars = [(var.name, var.pos) for var in lhs.args]
2845 error(lhs.pos, "Invalid declaration")
2847 for var, pos in vars:
2848 env.declare_var(var, type, pos, is_cdef = True)
2853 self.declaration_only = True
2855 self.declaration_only = True
2856 if not isinstance(lhs, ExprNodes.NameNode):
2857 error(lhs.pos, "Invalid declaration.")
2858 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2860 elif func_name in ['struct', 'union']:
2861 self.declaration_only = True
2862 if len(args) > 0 or kwds is None:
2863 error(rhs.pos, "Struct or union members must be given by name.")
2866 for member, type_node in kwds.key_value_pairs:
2867 type = type_node.analyse_as_type(env)
2869 error(type_node.pos, "Unknown type")
2871 members.append((member.value, type, member.pos))
2872 if len(members) < len(kwds.key_value_pairs):
2874 if not isinstance(self.lhs, ExprNodes.NameNode):
2875 error(self.lhs.pos, "Invalid declaration.")
2876 name = self.lhs.name
2877 scope = StructOrUnionScope(name)
2878 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2879 for member, type, pos in members:
2880 scope.declare_var(member, type, pos)
2882 if self.declaration_only:
2885 self.lhs.analyse_target_declaration(env)
2887 def analyse_types(self, env, use_temp = 0):
2888 self.rhs.analyse_types(env)
2889 self.lhs.analyse_target_types(env)
2890 self.lhs.gil_assignment_check(env)
2891 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2893 self.rhs = self.rhs.coerce_to_temp(env)
2895 def allocate_rhs_temps(self, env):
2896 self.rhs.allocate_temps(env)
2898 def allocate_lhs_temps(self, env):
2899 self.lhs.allocate_target_temps(env, self.rhs)
2900 #self.lhs.release_target_temp(env)
2901 #self.rhs.release_temp(env)
2903 def generate_rhs_evaluation_code(self, code):
2904 self.rhs.generate_evaluation_code(code)
2906 def generate_assignment_code(self, code):
2907 self.lhs.generate_assignment_code(self.rhs, code)
2909 def annotate(self, code):
2910 self.lhs.annotate(code)
2911 self.rhs.annotate(code)
2914 class CascadedAssignmentNode(AssignmentNode):
2915 # An assignment with multiple left hand sides:
2919 # lhs_list [ExprNode] Left hand sides
2920 # rhs ExprNode Right hand sides
2924 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2926 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2927 coerced_rhs_list = None
2929 def analyse_declarations(self, env):
2930 for lhs in self.lhs_list:
2931 lhs.analyse_target_declaration(env)
2933 def analyse_types(self, env, use_temp = 0):
2934 self.rhs.analyse_types(env)
2936 self.rhs = self.rhs.coerce_to_temp(env)
2938 self.rhs = self.rhs.coerce_to_simple(env)
2939 from ExprNodes import CloneNode
2940 self.coerced_rhs_list = []
2941 for lhs in self.lhs_list:
2942 lhs.analyse_target_types(env)
2943 lhs.gil_assignment_check(env)
2944 rhs = CloneNode(self.rhs)
2945 rhs = rhs.coerce_to(lhs.type, env)
2946 self.coerced_rhs_list.append(rhs)
2948 def allocate_rhs_temps(self, env):
2949 self.rhs.allocate_temps(env)
2951 def allocate_lhs_temps(self, env):
2952 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2953 rhs.allocate_temps(env)
2954 lhs.allocate_target_temps(env, rhs)
2955 #lhs.release_target_temp(env)
2956 #rhs.release_temp(env)
2957 self.rhs.release_temp(env)
2959 def generate_rhs_evaluation_code(self, code):
2960 self.rhs.generate_evaluation_code(code)
2962 def generate_assignment_code(self, code):
2963 for i in range(len(self.lhs_list)):
2964 lhs = self.lhs_list[i]
2965 rhs = self.coerced_rhs_list[i]
2966 rhs.generate_evaluation_code(code)
2967 lhs.generate_assignment_code(rhs, code)
2968 # Assignment has disposed of the cloned RHS
2969 self.rhs.generate_disposal_code(code)
2970 self.rhs.free_temps(code)
2972 def annotate(self, code):
2973 for i in range(len(self.lhs_list)):
2974 lhs = self.lhs_list[i].annotate(code)
2975 rhs = self.coerced_rhs_list[i].annotate(code)
2976 self.rhs.annotate(code)
2979 class ParallelAssignmentNode(AssignmentNode):
2980 # A combined packing/unpacking assignment:
2984 # This has been rearranged by the parser into
2986 # a = d ; b = e ; c = f
2988 # but we must evaluate all the right hand sides
2989 # before assigning to any of the left hand sides.
2991 # stats [AssignmentNode] The constituent assignments
2993 child_attrs = ["stats"]
2995 def analyse_declarations(self, env):
2996 for stat in self.stats:
2997 stat.analyse_declarations(env)
2999 def analyse_expressions(self, env):
3000 for stat in self.stats:
3001 stat.analyse_types(env, use_temp = 1)
3002 stat.allocate_rhs_temps(env)
3003 for stat in self.stats:
3004 stat.allocate_lhs_temps(env)
3006 # def analyse_expressions(self, env):
3007 # for stat in self.stats:
3008 # stat.analyse_expressions_1(env, use_temp = 1)
3009 # for stat in self.stats:
3010 # stat.analyse_expressions_2(env)
3012 def generate_execution_code(self, code):
3013 for stat in self.stats:
3014 stat.generate_rhs_evaluation_code(code)
3015 for stat in self.stats:
3016 stat.generate_assignment_code(code)
3018 def annotate(self, code):
3019 for stat in self.stats:
3023 class InPlaceAssignmentNode(AssignmentNode):
3024 # An in place arithmatic operand:
3030 # lhs ExprNode Left hand side
3031 # rhs ExprNode Right hand side
3032 # op char one of "+-*/%^&|"
3033 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3035 # This code is a bit tricky because in order to obey Python
3036 # semantics the sub-expressions (e.g. indices) of the lhs must
3037 # not be evaluated twice. So we must re-use the values calculated
3038 # in evaluation phase for the assignment phase as well.
3039 # Fortunately, the type of the lhs node is fairly constrained
3040 # (it must be a NameNode, AttributeNode, or IndexNode).
3042 child_attrs = ["lhs", "rhs"]
3045 def analyse_declarations(self, env):
3046 self.lhs.analyse_target_declaration(env)
3048 def analyse_types(self, env):
3049 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3050 self.rhs.analyse_types(env)
3051 self.lhs.analyse_target_types(env)
3052 if Options.incref_local_binop and self.dup.type.is_pyobject:
3053 self.dup = self.dup.coerce_to_temp(env)
3055 def allocate_rhs_temps(self, env):
3057 if self.lhs.type.is_pyobject:
3058 self.rhs = self.rhs.coerce_to_pyobject(env)
3059 elif self.rhs.type.is_pyobject:
3060 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3061 if self.lhs.type.is_pyobject:
3062 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3063 self.result_value.allocate_temps(env)
3065 # self.rhs = self.rhs.coerce_to_temp(env)
3066 self.rhs.allocate_temps(env)
3067 self.dup.allocate_subexpr_temps(env)
3068 self.dup.allocate_temp(env)
3070 def allocate_lhs_temps(self, env):
3071 self.lhs.allocate_target_temps(env, self.rhs)
3072 # self.lhs.release_target_temp(env)
3073 self.dup.release_temp(env)
3074 if self.dup.is_temp:
3075 self.dup.release_subexpr_temps(env)
3076 # self.rhs.release_temp(env)
3077 if self.lhs.type.is_pyobject:
3078 self.result_value.release_temp(env)
3080 def generate_execution_code(self, code):
3082 self.rhs.generate_evaluation_code(code)
3083 self.dup.generate_subexpr_evaluation_code(code)
3084 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3085 # This is because we're manually messing with subexpr nodes
3086 if self.dup.is_temp:
3087 self.dup.allocate_temp_result(code)
3088 # self.dup.generate_result_code is run only if it is not buffer access
3089 if self.operator == "**":
3093 if self.lhs.type.is_pyobject:
3094 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3095 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3096 self.dup.generate_result_code(code)
3098 "%s = %s(%s, %s%s); %s" % (
3099 self.result_value.result(),
3100 self.py_operation_function(),
3101 self.dup.py_result(),
3102 self.rhs.py_result(),
3104 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3105 code.put_gotref(self.result_value.py_result())
3106 self.result_value.generate_evaluation_code(code) # May be a type check...
3107 self.rhs.generate_disposal_code(code)
3108 self.rhs.free_temps(code)
3109 self.dup.generate_disposal_code(code)
3110 self.dup.free_temps(code)
3111 self.lhs.generate_assignment_code(self.result_value, code)
3113 c_op = self.operator
3117 if self.lhs.type.is_int and self.rhs.type.is_int:
3118 error(self.pos, "** with two C int types is ambiguous")
3120 error(self.pos, "No C inplace power operator")
3121 # have to do assignment directly to avoid side-effects
3122 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3123 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3125 self.dup.generate_result_code(code)
3126 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3127 self.rhs.generate_disposal_code(code)
3128 self.rhs.free_temps(code)
3129 if self.dup.is_temp:
3130 self.dup.generate_subexpr_disposal_code(code)
3131 self.dup.free_subexpr_temps(code)
3133 def create_dup_node(self, env):
3136 self.dup.analyse_types(env)
3137 if isinstance(self.lhs, ExprNodes.NameNode):
3138 target_lhs = ExprNodes.NameNode(self.dup.pos,
3139 name = self.dup.name,
3140 is_temp = self.dup.is_temp,
3141 entry = self.dup.entry)
3142 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3143 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3144 obj = ExprNodes.CloneNode(self.lhs.obj),
3145 attribute = self.dup.attribute,
3146 is_temp = self.dup.is_temp)
3147 elif isinstance(self.lhs, ExprNodes.IndexNode):
3149 index = ExprNodes.CloneNode(self.lhs.index)
3152 if self.lhs.indices:
3153 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3156 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3157 base = ExprNodes.CloneNode(self.dup.base),
3160 is_temp = self.dup.is_temp)
3163 self.lhs = target_lhs
3166 def py_operation_function(self):
3167 return self.py_functions[self.operator]
3170 "|": "PyNumber_InPlaceOr",
3171 "^": "PyNumber_InPlaceXor",
3172 "&": "PyNumber_InPlaceAnd",
3173 "+": "PyNumber_InPlaceAdd",
3174 "-": "PyNumber_InPlaceSubtract",
3175 "*": "PyNumber_InPlaceMultiply",
3176 "/": "PyNumber_InPlaceDivide",
3177 "%": "PyNumber_InPlaceRemainder",
3178 "<<": "PyNumber_InPlaceLshift",
3179 ">>": "PyNumber_InPlaceRshift",
3180 "**": "PyNumber_InPlacePower",
3181 "//": "PyNumber_InPlaceFloorDivide",
3184 def annotate(self, code):
3185 self.lhs.annotate(code)
3186 self.rhs.annotate(code)
3187 self.dup.annotate(code)
3190 class PrintStatNode(StatNode):
3193 # arg_tuple TupleNode
3194 # append_newline boolean
3196 child_attrs = ["arg_tuple"]
3198 def analyse_expressions(self, env):
3199 self.arg_tuple.analyse_expressions(env)
3200 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3201 self.arg_tuple.release_temp(env)
3202 env.use_utility_code(printing_utility_code)
3203 if len(self.arg_tuple.args) == 1 and self.append_newline:
3204 env.use_utility_code(printing_one_utility_code)
3206 gil_check = StatNode._gil_check
3207 gil_message = "Python print statement"
3209 def generate_execution_code(self, code):
3210 if len(self.arg_tuple.args) == 1 and self.append_newline:
3211 arg = self.arg_tuple.args[0]
3212 arg.generate_evaluation_code(code)
3215 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3217 code.error_goto(self.pos)))
3218 arg.generate_disposal_code(code)
3219 arg.free_temps(code)
3221 self.arg_tuple.generate_evaluation_code(code)
3223 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3224 self.arg_tuple.py_result(),
3225 self.append_newline,
3226 code.error_goto(self.pos)))
3227 self.arg_tuple.generate_disposal_code(code)
3228 self.arg_tuple.free_temps(code)
3230 def annotate(self, code):
3231 self.arg_tuple.annotate(code)
3234 class ExecStatNode(StatNode):
3239 child_attrs = ["args"]
3241 def analyse_expressions(self, env):
3242 for i, arg in enumerate(self.args):
3243 arg.analyse_expressions(env)
3244 arg = arg.coerce_to_pyobject(env)
3245 arg.release_temp(env)
3247 self.temp_result = env.allocate_temp_pyobject()
3248 env.release_temp(self.temp_result)
3249 env.use_utility_code(Builtin.pyexec_utility_code)
3251 gil_check = StatNode._gil_check
3252 gil_message = "Python exec statement"
3254 def generate_execution_code(self, code):
3256 for arg in self.args:
3257 arg.generate_evaluation_code(code)
3258 args.append( arg.py_result() )
3259 args = tuple(args + ['0', '0'][:3-len(args)])
3260 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3261 (self.temp_result,) + args))
3262 for arg in self.args:
3263 arg.generate_disposal_code(code)
3264 arg.free_temps(code)
3266 code.error_goto_if_null(self.temp_result, self.pos))
3267 code.put_gotref(self.temp_result)
3268 code.put_decref_clear(self.temp_result, py_object_type)
3270 def annotate(self, code):
3271 for arg in self.args:
3275 class DelStatNode(StatNode):
3280 child_attrs = ["args"]
3282 def analyse_declarations(self, env):
3283 for arg in self.args:
3284 arg.analyse_target_declaration(env)
3286 def analyse_expressions(self, env):
3287 for arg in self.args:
3288 arg.analyse_target_expression(env, None)
3289 if not arg.type.is_pyobject:
3290 error(arg.pos, "Deletion of non-Python object")
3291 #arg.release_target_temp(env)
3293 def gil_check(self, env):
3294 for arg in self.args:
3295 if arg.type.is_pyobject:
3296 self._gil_check(env)
3298 gil_message = "Deleting Python object"
3300 def generate_execution_code(self, code):
3301 for arg in self.args:
3302 if arg.type.is_pyobject:
3303 arg.generate_deletion_code(code)
3304 # else error reported earlier
3306 def annotate(self, code):
3307 for arg in self.args:
3311 class PassStatNode(StatNode):
3316 def analyse_expressions(self, env):
3319 def generate_execution_code(self, code):
3323 class BreakStatNode(StatNode):
3327 def analyse_expressions(self, env):
3330 def generate_execution_code(self, code):
3331 if not code.break_label:
3332 error(self.pos, "break statement not inside loop")
3334 code.put_goto(code.break_label)
3337 class ContinueStatNode(StatNode):
3341 def analyse_expressions(self, env):
3344 def generate_execution_code(self, code):
3345 if code.funcstate.in_try_finally:
3346 error(self.pos, "continue statement inside try of try...finally")
3347 elif not code.continue_label:
3348 error(self.pos, "continue statement not inside loop")
3350 code.put_goto(code.continue_label)
3353 class ReturnStatNode(StatNode):
3356 # value ExprNode or None
3357 # return_type PyrexType
3358 # temps_in_use [Entry] Temps in use at time of return
3360 child_attrs = ["value"]
3362 def analyse_expressions(self, env):
3363 return_type = env.return_type
3364 self.return_type = return_type
3365 self.temps_in_use = env.temps_in_use()
3367 error(self.pos, "Return not inside a function body")
3370 self.value.analyse_types(env)
3371 if return_type.is_void or return_type.is_returncode:
3372 error(self.value.pos,
3373 "Return with value in void function")
3375 self.value = self.value.coerce_to(env.return_type, env)
3376 self.value.allocate_temps(env)
3377 self.value.release_temp(env)
3379 if (not return_type.is_void
3380 and not return_type.is_pyobject
3381 and not return_type.is_returncode):
3382 error(self.pos, "Return value required")
3384 def gil_check(self, env):
3385 if self.return_type.is_pyobject:
3386 self._gil_check(env)
3388 gil_message = "Returning Python object"
3390 def generate_execution_code(self, code):
3391 code.mark_pos(self.pos)
3392 if not self.return_type:
3393 # error reported earlier
3395 if self.return_type.is_pyobject:
3396 code.put_xdecref(Naming.retval_cname,
3399 self.value.generate_evaluation_code(code)
3400 self.value.make_owned_reference(code)
3403 Naming.retval_cname,
3404 self.value.result_as(self.return_type)))
3405 self.value.generate_post_assignment_code(code)
3406 self.value.free_temps(code)
3408 if self.return_type.is_pyobject:
3409 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3410 elif self.return_type.is_returncode:
3413 Naming.retval_cname,
3414 self.return_type.default_value))
3415 # free temps the old way
3416 for entry in self.temps_in_use:
3417 code.put_var_decref_clear(entry)
3418 # free temps the new way
3419 for cname, type in code.funcstate.temps_holding_reference():
3420 code.put_decref_clear(cname, type)
3423 # code.return_label)
3424 code.put_goto(code.return_label)
3426 def annotate(self, code):
3428 self.value.annotate(code)
3431 class RaiseStatNode(StatNode):
3434 # exc_type ExprNode or None
3435 # exc_value ExprNode or None
3436 # exc_tb ExprNode or None
3438 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3440 def analyse_expressions(self, env):
3442 self.exc_type.analyse_types(env)
3443 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3444 self.exc_type.allocate_temps(env)
3446 self.exc_value.analyse_types(env)
3447 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3448 self.exc_value.allocate_temps(env)
3450 self.exc_tb.analyse_types(env)
3451 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3452 self.exc_tb.allocate_temps(env)
3454 self.exc_type.release_temp(env)
3456 self.exc_value.release_temp(env)
3458 self.exc_tb.release_temp(env)
3459 env.use_utility_code(raise_utility_code)
3460 env.use_utility_code(restore_exception_utility_code)
3462 gil_check = StatNode._gil_check
3463 gil_message = "Raising exception"
3465 def generate_execution_code(self, code):
3467 self.exc_type.generate_evaluation_code(code)
3468 type_code = self.exc_type.py_result()
3472 self.exc_value.generate_evaluation_code(code)
3473 value_code = self.exc_value.py_result()
3477 self.exc_tb.generate_evaluation_code(code)
3478 tb_code = self.exc_tb.py_result()
3481 if self.exc_type or self.exc_value or self.exc_tb:
3483 "__Pyx_Raise(%s, %s, %s);" % (
3490 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3492 obj.generate_disposal_code(code)
3493 obj.free_temps(code)
3495 code.error_goto(self.pos))
3497 def annotate(self, code):
3499 self.exc_type.annotate(code)
3501 self.exc_value.annotate(code)
3503 self.exc_tb.annotate(code)
3506 class ReraiseStatNode(StatNode):
3510 def analyse_expressions(self, env):
3511 env.use_utility_code(raise_utility_code)
3512 env.use_utility_code(restore_exception_utility_code)
3514 gil_check = StatNode._gil_check
3515 gil_message = "Raising exception"
3517 def generate_execution_code(self, code):
3518 vars = code.funcstate.exc_vars
3520 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3521 code.putln(code.error_goto(self.pos))
3523 error(self.pos, "Reraise not inside except clause")
3526 class AssertStatNode(StatNode):
3530 # value ExprNode or None
3532 child_attrs = ["cond", "value"]
3534 def analyse_expressions(self, env):
3535 self.cond = self.cond.analyse_boolean_expression(env)
3537 self.value.analyse_types(env)
3538 self.value = self.value.coerce_to_pyobject(env)
3539 self.value.allocate_temps(env)
3540 self.cond.release_temp(env)
3542 self.value.release_temp(env)
3543 #env.recycle_pending_temps() # TEMPORARY
3545 gil_check = StatNode._gil_check
3546 gil_message = "Raising exception"
3548 def generate_execution_code(self, code):
3549 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3550 self.cond.generate_evaluation_code(code)
3552 "if (unlikely(!%s)) {" %
3555 self.value.generate_evaluation_code(code)
3557 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3558 self.value.py_result())
3559 self.value.generate_disposal_code(code)
3560 self.value.free_temps(code)
3563 "PyErr_SetNone(PyExc_AssertionError);")
3565 code.error_goto(self.pos))
3568 self.cond.generate_disposal_code(code)
3569 self.cond.free_temps(code)
3570 code.putln("#endif")
3572 def annotate(self, code):
3573 self.cond.annotate(code)
3575 self.value.annotate(code)
3578 class IfStatNode(StatNode):
3581 # if_clauses [IfClauseNode]
3582 # else_clause StatNode or None
3584 child_attrs = ["if_clauses", "else_clause"]
3586 def analyse_control_flow(self, env):
3587 env.start_branching(self.pos)
3588 for if_clause in self.if_clauses:
3589 if_clause.analyse_control_flow(env)
3590 env.next_branch(if_clause.end_pos())
3591 if self.else_clause:
3592 self.else_clause.analyse_control_flow(env)
3593 env.finish_branching(self.end_pos())
3595 def analyse_declarations(self, env):
3596 for if_clause in self.if_clauses:
3597 if_clause.analyse_declarations(env)
3598 if self.else_clause:
3599 self.else_clause.analyse_declarations(env)
3601 def analyse_expressions(self, env):
3602 for if_clause in self.if_clauses:
3603 if_clause.analyse_expressions(env)
3604 if self.else_clause:
3605 self.else_clause.analyse_expressions(env)
3607 def generate_execution_code(self, code):
3608 code.mark_pos(self.pos)
3609 end_label = code.new_label()
3610 for if_clause in self.if_clauses:
3611 if_clause.generate_execution_code(code, end_label)
3612 if self.else_clause:
3613 code.putln("/*else*/ {")
3614 self.else_clause.generate_execution_code(code)
3616 code.put_label(end_label)
3618 def annotate(self, code):
3619 for if_clause in self.if_clauses:
3620 if_clause.annotate(code)
3621 if self.else_clause:
3622 self.else_clause.annotate(code)
3625 class IfClauseNode(Node):
3626 # if or elif clause in an if statement
3628 # condition ExprNode
3631 child_attrs = ["condition", "body"]
3633 def analyse_control_flow(self, env):
3634 self.body.analyse_control_flow(env)
3636 def analyse_declarations(self, env):
3637 self.condition.analyse_declarations(env)
3638 self.body.analyse_declarations(env)
3640 def analyse_expressions(self, env):
3642 self.condition.analyse_temp_boolean_expression(env)
3643 self.condition.release_temp(env)
3644 self.body.analyse_expressions(env)
3646 def generate_execution_code(self, code, end_label):
3647 self.condition.generate_evaluation_code(code)
3650 self.condition.result())
3651 self.condition.generate_disposal_code(code)
3652 self.condition.free_temps(code)
3653 self.body.generate_execution_code(code)
3657 code.put_goto(end_label)
3660 def annotate(self, code):
3661 self.condition.annotate(code)
3662 self.body.annotate(code)
3665 class SwitchCaseNode(StatNode):
3666 # Generated in the optimization of an if-elif-else node
3668 # conditions [ExprNode]
3671 child_attrs = ['conditions', 'body']
3673 def generate_execution_code(self, code):
3674 for cond in self.conditions:
3675 code.mark_pos(cond.pos)
3676 cond.generate_evaluation_code(code)
3677 code.putln("case %s:" % cond.result())
3678 self.body.generate_execution_code(code)
3679 code.putln("break;")
3681 def annotate(self, code):
3682 for cond in self.conditions:
3684 self.body.annotate(code)
3686 class SwitchStatNode(StatNode):
3687 # Generated in the optimization of an if-elif-else node
3690 # cases [SwitchCaseNode]
3691 # else_clause StatNode or None
3693 child_attrs = ['test', 'cases', 'else_clause']
3695 def generate_execution_code(self, code):
3696 code.putln("switch (%s) {" % self.test.result())
3697 for case in self.cases:
3698 case.generate_execution_code(code)
3699 if self.else_clause is not None:
3700 code.putln("default:")
3701 self.else_clause.generate_execution_code(code)
3702 code.putln("break;")
3705 def annotate(self, code):
3706 self.test.annotate(code)
3707 for case in self.cases:
3709 if self.else_clause is not None:
3710 self.else_clause.annotate(code)
3712 class LoopNode(object):
3714 def analyse_control_flow(self, env):
3715 env.start_branching(self.pos)
3716 self.body.analyse_control_flow(env)
3717 env.next_branch(self.body.end_pos())
3718 if self.else_clause:
3719 self.else_clause.analyse_control_flow(env)
3720 env.finish_branching(self.end_pos())
3723 class WhileStatNode(LoopNode, StatNode):
3726 # condition ExprNode
3728 # else_clause StatNode
3730 child_attrs = ["condition", "body", "else_clause"]
3732 def analyse_declarations(self, env):
3733 self.body.analyse_declarations(env)
3734 if self.else_clause:
3735 self.else_clause.analyse_declarations(env)
3737 def analyse_expressions(self, env):
3739 self.condition.analyse_temp_boolean_expression(env)
3740 self.condition.release_temp(env)
3741 #env.recycle_pending_temps() # TEMPORARY
3742 self.body.analyse_expressions(env)
3743 if self.else_clause:
3744 self.else_clause.analyse_expressions(env)
3746 def generate_execution_code(self, code):
3747 old_loop_labels = code.new_loop_labels()
3750 self.condition.generate_evaluation_code(code)
3751 self.condition.generate_disposal_code(code)
3754 self.condition.result())
3755 self.condition.free_temps(code)
3756 self.body.generate_execution_code(code)
3757 code.put_label(code.continue_label)
3759 break_label = code.break_label
3760 code.set_loop_labels(old_loop_labels)
3761 if self.else_clause:
3762 code.putln("/*else*/ {")
3763 self.else_clause.generate_execution_code(code)
3765 code.put_label(break_label)
3767 def annotate(self, code):
3768 self.condition.annotate(code)
3769 self.body.annotate(code)
3770 if self.else_clause:
3771 self.else_clause.annotate(code)
3774 def ForStatNode(pos, **kw):
3775 if 'iterator' in kw:
3776 return ForInStatNode(pos, **kw)
3778 return ForFromStatNode(pos, **kw)
3780 class ForInStatNode(LoopNode, StatNode):
3784 # iterator IteratorNode
3786 # else_clause StatNode
3787 # item NextNode used internally
3789 child_attrs = ["target", "iterator", "body", "else_clause"]
3792 def analyse_declarations(self, env):
3793 self.target.analyse_target_declaration(env)
3794 self.body.analyse_declarations(env)
3795 if self.else_clause:
3796 self.else_clause.analyse_declarations(env)
3798 def analyse_expressions(self, env):
3800 self.target.analyse_target_types(env)
3801 self.iterator.analyse_expressions(env)
3802 self.item = ExprNodes.NextNode(self.iterator, env)
3803 self.item = self.item.coerce_to(self.target.type, env)
3804 self.item.allocate_temps(env)
3805 self.target.allocate_target_temps(env, self.item)
3806 #self.item.release_temp(env)
3807 #self.target.release_target_temp(env)
3808 self.body.analyse_expressions(env)
3809 if self.else_clause:
3810 self.else_clause.analyse_expressions(env)
3811 self.iterator.release_temp(env)
3813 def generate_execution_code(self, code):
3814 old_loop_labels = code.new_loop_labels()
3815 self.iterator.allocate_counter_temp(code)
3816 self.iterator.generate_evaluation_code(code)
3819 self.item.generate_evaluation_code(code)
3820 self.target.generate_assignment_code(self.item, code)
3821 self.body.generate_execution_code(code)
3822 code.put_label(code.continue_label)
3825 break_label = code.break_label
3826 code.set_loop_labels(old_loop_labels)
3827 if self.else_clause:
3828 code.putln("/*else*/ {")
3829 self.else_clause.generate_execution_code(code)
3831 code.put_label(break_label)
3832 self.iterator.release_counter_temp(code)
3833 self.iterator.generate_disposal_code(code)
3834 self.iterator.free_temps(code)
3836 def annotate(self, code):
3837 self.target.annotate(code)
3838 self.iterator.annotate(code)
3839 self.body.annotate(code)
3840 if self.else_clause:
3841 self.else_clause.annotate(code)
3842 self.item.annotate(code)
3845 class ForFromStatNode(LoopNode, StatNode):
3846 # for name from expr rel name rel expr
3853 # step ExprNode or None
3855 # else_clause StatNode or None
3861 # loopvar_node ExprNode (usually a NameNode or temp node)
3862 # py_loopvar_node PyTempNode or None
3863 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3865 is_py_target = False
3867 py_loopvar_node = None
3870 def analyse_declarations(self, env):
3871 self.target.analyse_target_declaration(env)
3872 self.body.analyse_declarations(env)
3873 if self.else_clause:
3874 self.else_clause.analyse_declarations(env)
3876 def analyse_expressions(self, env):
3878 self.target.analyse_target_types(env)
3879 self.bound1.analyse_types(env)
3880 self.bound2.analyse_types(env)
3881 if self.step is not None:
3882 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3883 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3884 self.step.analyse_types(env)
3886 target_type = self.target.type
3887 if self.target.type.is_numeric:
3888 loop_type = self.target.type
3890 loop_type = PyrexTypes.c_int_type
3891 if not self.bound1.type.is_pyobject:
3892 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3893 if not self.bound2.type.is_pyobject:
3894 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3895 if self.step is not None and not self.step.type.is_pyobject:
3896 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3897 self.bound1 = self.bound1.coerce_to(loop_type, env)
3898 self.bound2 = self.bound2.coerce_to(loop_type, env)
3899 if not self.bound2.is_literal:
3900 self.bound2 = self.bound2.coerce_to_temp(env)
3901 if self.step is not None:
3902 self.step = self.step.coerce_to(loop_type, env)
3903 if not self.step.is_literal:
3904 self.step = self.step.coerce_to_temp(env)
3906 target_type = self.target.type
3907 if not (target_type.is_pyobject or target_type.is_numeric):
3908 error(self.target.pos,
3909 "for-from loop variable must be c numeric type or Python object")
3910 if target_type.is_numeric:
3911 self.is_py_target = False
3912 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3913 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3914 self.loopvar_node = self.target
3915 self.py_loopvar_node = None
3917 self.is_py_target = True
3918 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3919 c_loopvar_node.allocate_temps(env)
3920 self.loopvar_node = c_loopvar_node
3921 self.py_loopvar_node = \
3922 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3923 self.bound1.allocate_temps(env)
3924 self.bound2.allocate_temps(env)
3925 if self.step is not None:
3926 self.step.allocate_temps(env)
3927 if self.is_py_target:
3928 self.py_loopvar_node.allocate_temps(env)
3929 self.target.allocate_target_temps(env, self.py_loopvar_node)
3930 #self.target.release_target_temp(env)
3931 #self.py_loopvar_node.release_temp(env)
3932 self.body.analyse_expressions(env)
3933 if self.is_py_target:
3934 c_loopvar_node.release_temp(env)
3935 if self.else_clause:
3936 self.else_clause.analyse_expressions(env)
3937 self.bound1.release_temp(env)
3938 self.bound2.release_temp(env)
3939 if self.step is not None:
3940 self.step.release_temp(env)
3942 def generate_execution_code(self, code):
3943 old_loop_labels = code.new_loop_labels()
3944 from_range = self.from_range
3945 self.bound1.generate_evaluation_code(code)
3946 self.bound2.generate_evaluation_code(code)
3947 offset, incop = self.relation_table[self.relation1]
3948 if self.step is not None:
3949 self.step.generate_evaluation_code(code)
3950 step = self.step.result()
3951 incop = "%s=%s" % (incop[0], step)
3953 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3955 loopvar_name = self.loopvar_node.result()
3957 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3959 self.bound1.result(), offset,
3960 loopvar_name, self.relation2, self.bound2.result(),
3961 loopvar_name, incop))
3962 if self.py_loopvar_node:
3963 self.py_loopvar_node.generate_evaluation_code(code)
3964 self.target.generate_assignment_code(self.py_loopvar_node, code)
3966 code.putln("%s = %s;" % (
3967 self.target.result(), loopvar_name))
3968 self.body.generate_execution_code(code)
3969 code.put_label(code.continue_label)
3970 if self.py_loopvar_node:
3971 # Reassign py variable to loop var here.
3972 # (For consistancy, should rarely come up in practice.)
3974 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, self.target, None)
3975 from_py_node.temp_code = loopvar_name
3976 from_py_node.generate_result_code(code)
3978 if self.py_loopvar_node:
3979 # This is potentially wasteful, but we don't want the semantics to
3980 # depend on whether or not the loop is a python type.
3981 self.py_loopvar_node.generate_evaluation_code(code)
3982 self.target.generate_assignment_code(self.py_loopvar_node, code)
3983 break_label = code.break_label
3984 code.set_loop_labels(old_loop_labels)
3985 if self.else_clause:
3986 code.putln("/*else*/ {")
3987 self.else_clause.generate_execution_code(code)
3989 code.put_label(break_label)
3990 self.bound1.generate_disposal_code(code)
3991 self.bound1.free_temps(code)
3992 self.bound2.generate_disposal_code(code)
3993 self.bound2.free_temps(code)
3994 if self.step is not None:
3995 self.step.generate_disposal_code(code)
3996 self.step.free_temps(code)
3998 code.funcstate.release_temp(loopvar_name)
4001 # {relop : (initial offset, increment op)}
4008 def annotate(self, code):
4009 self.target.annotate(code)
4010 self.bound1.annotate(code)
4011 self.bound2.annotate(code)
4013 self.bound2.annotate(code)
4014 self.body.annotate(code)
4015 if self.else_clause:
4016 self.else_clause.annotate(code)
4019 class WithStatNode(StatNode):
4021 Represents a Python with statement.
4023 This is only used at parse tree level; and is not present in
4024 analysis or generation phases.
4026 # manager The with statement manager object
4027 # target Node (lhs expression)
4029 child_attrs = ["manager", "target", "body"]
4031 class TryExceptStatNode(StatNode):
4032 # try .. except statement
4035 # except_clauses [ExceptClauseNode]
4036 # else_clause StatNode or None
4037 # cleanup_list [Entry] old style temps to clean up on error
4039 child_attrs = ["body", "except_clauses", "else_clause"]
4041 def analyse_control_flow(self, env):
4042 env.start_branching(self.pos)
4043 self.body.analyse_control_flow(env)
4044 successful_try = env.control_flow # grab this for later
4045 env.next_branch(self.body.end_pos())
4046 env.finish_branching(self.body.end_pos())
4048 env.start_branching(self.except_clauses[0].pos)
4049 for except_clause in self.except_clauses:
4050 except_clause.analyse_control_flow(env)
4051 env.next_branch(except_clause.end_pos())
4053 # the else cause it executed only when the try clause finishes
4054 env.control_flow.incoming = successful_try
4055 if self.else_clause:
4056 self.else_clause.analyse_control_flow(env)
4057 env.finish_branching(self.end_pos())
4059 def analyse_declarations(self, env):
4060 self.body.analyse_declarations(env)
4061 for except_clause in self.except_clauses:
4062 except_clause.analyse_declarations(env)
4063 if self.else_clause:
4064 self.else_clause.analyse_declarations(env)
4065 env.use_utility_code(reset_exception_utility_code)
4067 def analyse_expressions(self, env):
4068 self.body.analyse_expressions(env)
4069 self.cleanup_list = env.free_temp_entries[:]
4070 default_clause_seen = 0
4071 for except_clause in self.except_clauses:
4072 except_clause.analyse_expressions(env)
4073 if default_clause_seen:
4074 error(except_clause.pos, "default 'except:' must be last")
4075 if not except_clause.pattern:
4076 default_clause_seen = 1
4077 self.has_default_clause = default_clause_seen
4078 if self.else_clause:
4079 self.else_clause.analyse_expressions(env)
4081 gil_check = StatNode._gil_check
4082 gil_message = "Try-except statement"
4084 def generate_execution_code(self, code):
4085 old_return_label = code.return_label
4086 old_break_label = code.break_label
4087 old_continue_label = code.continue_label
4088 old_error_label = code.new_error_label()
4089 our_error_label = code.error_label
4090 except_end_label = code.new_label('exception_handled')
4091 except_error_label = code.new_label('except_error')
4092 except_return_label = code.new_label('except_return')
4093 try_return_label = code.new_label('try_return')
4094 try_break_label = code.new_label('try_break')
4095 try_continue_label = code.new_label('try_continue')
4096 try_end_label = code.new_label('try_end')
4099 code.putln("PyObject %s;" %
4100 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4101 code.putln("__Pyx_ExceptionSave(%s);" %
4102 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4103 for var in Naming.exc_save_vars:
4104 code.put_xgotref(var)
4107 code.return_label = try_return_label
4108 code.break_label = try_break_label
4109 code.continue_label = try_continue_label
4110 self.body.generate_execution_code(code)
4113 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4114 code.error_label = except_error_label
4115 code.return_label = except_return_label
4116 if self.else_clause:
4119 self.else_clause.generate_execution_code(code)
4122 for var in Naming.exc_save_vars:
4123 code.put_xdecref_clear(var, py_object_type)
4124 code.put_goto(try_end_label)
4125 if code.label_used(try_return_label):
4126 code.put_label(try_return_label)
4127 for var in Naming.exc_save_vars:
4128 code.put_xdecref_clear(var, py_object_type)
4129 code.put_goto(old_return_label)
4130 code.put_label(our_error_label)
4131 code.put_var_xdecrefs_clear(self.cleanup_list)
4132 for temp_name, type in temps_to_clean_up:
4133 code.put_xdecref_clear(temp_name, type)
4134 for except_clause in self.except_clauses:
4135 except_clause.generate_handling_code(code, except_end_label)
4137 error_label_used = code.label_used(except_error_label)
4138 if error_label_used or not self.has_default_clause:
4139 if error_label_used:
4140 code.put_label(except_error_label)
4141 for var in Naming.exc_save_vars:
4142 code.put_xdecref(var, py_object_type)
4143 code.put_goto(old_error_label)
4145 if code.label_used(try_break_label):
4146 code.put_label(try_break_label)
4147 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4148 code.putln("__Pyx_ExceptionReset(%s);" %
4149 ', '.join(Naming.exc_save_vars))
4150 code.put_goto(old_break_label)
4152 if code.label_used(try_continue_label):
4153 code.put_label(try_continue_label)
4154 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4155 code.putln("__Pyx_ExceptionReset(%s);" %
4156 ', '.join(Naming.exc_save_vars))
4157 code.put_goto(old_continue_label)
4159 if code.label_used(except_return_label):
4160 code.put_label(except_return_label)
4161 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4162 code.putln("__Pyx_ExceptionReset(%s);" %
4163 ', '.join(Naming.exc_save_vars))
4164 code.put_goto(old_return_label)
4166 if code.label_used(except_end_label):
4167 code.put_label(except_end_label)
4168 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4169 code.putln("__Pyx_ExceptionReset(%s);" %
4170 ', '.join(Naming.exc_save_vars))
4171 code.put_label(try_end_label)
4174 code.return_label = old_return_label
4175 code.break_label = old_break_label
4176 code.continue_label = old_continue_label
4177 code.error_label = old_error_label
4179 def annotate(self, code):
4180 self.body.annotate(code)
4181 for except_node in self.except_clauses:
4182 except_node.annotate(code)
4183 if self.else_clause:
4184 self.else_clause.annotate(code)
4187 class ExceptClauseNode(Node):
4188 # Part of try ... except statement.
4191 # target ExprNode or None
4193 # excinfo_target NameNode or None optional target for exception info
4194 # match_flag string result of exception match
4195 # exc_value ExcValueNode used internally
4196 # function_name string qualified name of enclosing function
4197 # exc_vars (string * 3) local exception variables
4199 # excinfo_target is never set by the parser, but can be set by a transform
4200 # in order to extract more extensive information about the exception as a
4201 # sys.exc_info()-style tuple into a target variable
4203 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4206 excinfo_target = None
4208 def analyse_declarations(self, env):
4210 self.target.analyse_target_declaration(env)
4211 if self.excinfo_target is not None:
4212 self.excinfo_target.analyse_target_declaration(env)
4213 self.body.analyse_declarations(env)
4215 def analyse_expressions(self, env):
4217 genv = env.global_scope()
4218 self.function_name = env.qualified_name
4220 self.pattern.analyse_expressions(env)
4221 self.pattern = self.pattern.coerce_to_pyobject(env)
4222 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4223 self.pattern.release_temp(env)
4224 env.release_temp(self.match_flag)
4226 if self.target or self.excinfo_target:
4227 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4229 self.exc_vars = None
4232 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4233 self.exc_value.allocate_temps(env)
4234 self.target.analyse_target_expression(env, self.exc_value)
4235 if self.excinfo_target is not None:
4237 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4238 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4239 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4240 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4242 self.excinfo_tuple.analyse_expressions(env)
4243 self.excinfo_tuple.allocate_temps(env)
4244 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4246 self.body.analyse_expressions(env)
4249 for var in self.exc_vars:
4250 env.release_temp(var)
4252 def generate_handling_code(self, code, end_label):
4253 code.mark_pos(self.pos)
4255 self.pattern.generate_evaluation_code(code)
4257 "%s = PyErr_ExceptionMatches(%s);" % (
4259 self.pattern.py_result()))
4260 self.pattern.generate_disposal_code(code)
4261 self.pattern.free_temps(code)
4266 code.putln("/*except:*/ {")
4269 exc_vars = self.exc_vars
4270 elif not getattr(self.body, 'stats', True):
4271 # most simple case: no exception variable, empty body (pass)
4272 # => reset the exception state, done
4273 code.putln("PyErr_Restore(0,0,0);")
4274 code.put_goto(end_label)
4278 # during type analysis, we didn't know if we need the
4279 # exception value, but apparently, we do
4280 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4284 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4285 # We always have to fetch the exception value even if
4286 # there is no target, because this also normalises the
4287 # exception and stores it in the thread state.
4288 code.globalstate.use_utility_code(get_exception_utility_code)
4289 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4290 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4291 code.error_goto(self.pos)))
4295 self.exc_value.generate_evaluation_code(code)
4296 self.target.generate_assignment_code(self.exc_value, code)
4297 if self.excinfo_target is not None:
4298 self.excinfo_tuple.generate_evaluation_code(code)
4299 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4302 old_break_label, old_continue_label = code.break_label, code.continue_label
4303 code.break_label = code.new_label('except_break')
4304 code.continue_label = code.new_label('except_continue')
4306 old_exc_vars = code.funcstate.exc_vars
4307 code.funcstate.exc_vars = exc_vars
4308 self.body.generate_execution_code(code)
4309 code.funcstate.exc_vars = old_exc_vars
4310 for var in exc_vars:
4311 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4312 code.put_goto(end_label)
4314 if code.label_used(code.break_label):
4315 code.put_label(code.break_label)
4316 for var in exc_vars:
4317 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4318 code.put_goto(old_break_label)
4319 code.break_label = old_break_label
4321 if code.label_used(code.continue_label):
4322 code.put_label(code.continue_label)
4323 for var in exc_vars:
4324 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4325 code.put_goto(old_continue_label)
4326 code.continue_label = old_continue_label
4328 if not self.exc_vars:
4329 # clean up locally allocated temps
4330 for temp in exc_vars:
4331 code.funcstate.release_temp(temp)
4336 def annotate(self, code):
4338 self.pattern.annotate(code)
4340 self.target.annotate(code)
4341 self.body.annotate(code)
4344 class TryFinallyStatNode(StatNode):
4345 # try ... finally statement
4348 # finally_clause StatNode
4350 # cleanup_list [Entry] old_style temps to clean up on error
4352 # The plan is that we funnel all continue, break
4353 # return and error gotos into the beginning of the
4354 # finally block, setting a variable to remember which
4355 # one we're doing. At the end of the finally block, we
4356 # switch on the variable to figure out where to go.
4357 # In addition, if we're doing an error, we save the
4358 # exception on entry to the finally block and restore
4361 child_attrs = ["body", "finally_clause"]
4363 preserve_exception = 1
4365 disallow_continue_in_try_finally = 0
4366 # There doesn't seem to be any point in disallowing
4367 # continue in the try block, since we have no problem
4370 def create_analysed(pos, env, body, finally_clause):
4371 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4372 node.cleanup_list = []
4374 create_analysed = staticmethod(create_analysed)
4376 def analyse_control_flow(self, env):
4377 env.start_branching(self.pos)
4378 self.body.analyse_control_flow(env)
4379 env.next_branch(self.body.end_pos())
4380 env.finish_branching(self.body.end_pos())
4381 self.finally_clause.analyse_control_flow(env)
4383 def analyse_declarations(self, env):
4384 self.body.analyse_declarations(env)
4385 self.finally_clause.analyse_declarations(env)
4387 def analyse_expressions(self, env):
4388 self.body.analyse_expressions(env)
4389 self.cleanup_list = env.free_temp_entries[:]
4390 self.finally_clause.analyse_expressions(env)
4392 gil_check = StatNode._gil_check
4393 gil_message = "Try-finally statement"
4395 def generate_execution_code(self, code):
4396 old_error_label = code.error_label
4397 old_labels = code.all_new_labels()
4398 new_labels = code.get_all_labels()
4399 new_error_label = code.error_label
4400 catch_label = code.new_label()
4403 if self.disallow_continue_in_try_finally:
4404 was_in_try_finally = code.funcstate.in_try_finally
4405 code.funcstate.in_try_finally = 1
4406 self.body.generate_execution_code(code)
4407 if self.disallow_continue_in_try_finally:
4408 code.funcstate.in_try_finally = was_in_try_finally
4411 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4415 error_label_used = 0
4416 for i, new_label in enumerate(new_labels):
4417 if new_label in code.labels_used:
4418 cases_used.append(i)
4419 if new_label == new_error_label:
4420 error_label_used = 1
4421 error_label_case = i
4425 if error_label_used and self.preserve_exception:
4427 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4429 "int %s;" % Naming.exc_lineno_name)
4430 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4431 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4432 code.putln(exc_var_init_zero)
4434 exc_var_init_zero = None
4435 code.use_label(catch_label)
4437 "__pyx_why = 0; goto %s;" % catch_label)
4438 for i in cases_used:
4439 new_label = new_labels[i]
4440 #if new_label and new_label != "<try>":
4441 if new_label == new_error_label and self.preserve_exception:
4442 self.put_error_catcher(code,
4443 new_error_label, i+1, catch_label, temps_to_clean_up)
4445 code.put('%s: ' % new_label)
4446 if exc_var_init_zero:
4447 code.putln(exc_var_init_zero)
4448 code.putln("__pyx_why = %s; goto %s;" % (
4451 code.put_label(catch_label)
4452 code.set_all_labels(old_labels)
4453 if error_label_used:
4454 code.new_error_label()
4455 finally_error_label = code.error_label
4456 self.finally_clause.generate_execution_code(code)
4457 if error_label_used:
4458 if finally_error_label in code.labels_used and self.preserve_exception:
4459 over_label = code.new_label()
4460 code.put_goto(over_label);
4461 code.put_label(finally_error_label)
4462 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4463 for var in Naming.exc_vars:
4464 code.putln("Py_XDECREF(%s);" % var)
4466 code.put_goto(old_error_label)
4467 code.put_label(over_label)
4468 code.error_label = old_error_label
4471 "switch (__pyx_why) {")
4472 for i in cases_used:
4473 old_label = old_labels[i]
4474 if old_label == old_error_label and self.preserve_exception:
4475 self.put_error_uncatcher(code, i+1, old_error_label)
4477 code.use_label(old_label)
4479 "case %s: goto %s;" % (
4487 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4488 code.globalstate.use_utility_code(restore_exception_utility_code)
4495 code.put_var_xdecrefs_clear(self.cleanup_list)
4496 for temp_name, type in temps_to_clean_up:
4497 code.put_xdecref_clear(temp_name, type)
4499 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4503 Naming.exc_lineno_name, Naming.lineno_cname))
4507 code.put_goto(catch_label)
4511 def put_error_uncatcher(self, code, i, error_label):
4512 code.globalstate.use_utility_code(restore_exception_utility_code)
4517 "__Pyx_ErrRestore(%s, %s, %s);" %
4521 Naming.lineno_cname, Naming.exc_lineno_name))
4522 for var in Naming.exc_vars:
4526 code.put_goto(error_label)
4530 def annotate(self, code):
4531 self.body.annotate(code)
4532 self.finally_clause.annotate(code)
4535 class GILStatNode(TryFinallyStatNode):
4536 # 'with gil' or 'with nogil' statement
4538 # state string 'gil' or 'nogil'
4542 preserve_exception = 0
4544 def __init__(self, pos, state, body):
4546 TryFinallyStatNode.__init__(self, pos,
4548 finally_clause = GILExitNode(pos, state = state))
4550 def analyse_expressions(self, env):
4551 env.use_utility_code(force_init_threads_utility_code)
4552 was_nogil = env.nogil
4554 TryFinallyStatNode.analyse_expressions(self, env)
4555 env.nogil = was_nogil
4557 def gil_check(self, env):
4560 def generate_execution_code(self, code):
4561 code.mark_pos(self.pos)
4562 if self.state == 'gil':
4563 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4565 code.putln("{ PyThreadState *_save;")
4566 code.putln("Py_UNBLOCK_THREADS")
4567 TryFinallyStatNode.generate_execution_code(self, code)
4571 class GILExitNode(StatNode):
4572 # Used as the 'finally' block in a GILStatNode
4574 # state string 'gil' or 'nogil'
4578 def analyse_expressions(self, env):
4581 def generate_execution_code(self, code):
4582 if self.state == 'gil':
4583 code.putln("PyGILState_Release();")
4585 code.putln("Py_BLOCK_THREADS")
4588 class CImportStatNode(StatNode):
4591 # module_name string Qualified name of module being imported
4592 # as_name string or None Name specified in "as" clause, if any
4596 def analyse_declarations(self, env):
4597 if not env.is_module_scope:
4598 error(self.pos, "cimport only allowed at module level")
4600 module_scope = env.find_module(self.module_name, self.pos)
4601 if "." in self.module_name:
4602 names = [EncodedString(name) for name in self.module_name.split(".")]
4604 top_module_scope = env.context.find_submodule(top_name)
4605 module_scope = top_module_scope
4606 for name in names[1:]:
4607 submodule_scope = module_scope.find_submodule(name)
4608 module_scope.declare_module(name, submodule_scope, self.pos)
4609 module_scope = submodule_scope
4611 env.declare_module(self.as_name, module_scope, self.pos)
4613 env.declare_module(top_name, top_module_scope, self.pos)
4615 name = self.as_name or self.module_name
4616 env.declare_module(name, module_scope, self.pos)
4618 def analyse_expressions(self, env):
4621 def generate_execution_code(self, code):
4625 class FromCImportStatNode(StatNode):
4626 # from ... cimport statement
4628 # module_name string Qualified name of module
4629 # imported_names [(pos, name, as_name, kind)] Names to be imported
4633 def analyse_declarations(self, env):
4634 if not env.is_module_scope:
4635 error(self.pos, "cimport only allowed at module level")
4637 module_scope = env.find_module(self.module_name, self.pos)
4638 env.add_imported_module(module_scope)
4639 for pos, name, as_name, kind in self.imported_names:
4641 for local_name, entry in module_scope.entries.items():
4642 env.add_imported_entry(local_name, entry, pos)
4644 entry = module_scope.lookup(name)
4646 if kind and not self.declaration_matches(entry, kind):
4647 entry.redeclared(pos)
4649 if kind == 'struct' or kind == 'union':
4650 entry = module_scope.declare_struct_or_union(name,
4651 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4652 elif kind == 'class':
4653 entry = module_scope.declare_c_class(name, pos = pos,
4654 module_name = self.module_name)
4656 error(pos, "Name '%s' not declared in module '%s'"
4657 % (name, self.module_name))
4660 local_name = as_name or name
4661 env.add_imported_entry(local_name, entry, pos)
4663 def declaration_matches(self, entry, kind):
4664 if not entry.is_type:
4668 if not type.is_extension_type:
4671 if not type.is_struct_or_union:
4673 if kind != type.kind:
4677 def analyse_expressions(self, env):
4680 def generate_execution_code(self, code):
4684 class FromImportStatNode(StatNode):
4685 # from ... import statement
4688 # items [(string, NameNode)]
4689 # interned_items [(string, NameNode, ExprNode)]
4690 # item PyTempNode used internally
4691 # import_star boolean used internally
4693 child_attrs = ["module"]
4696 def analyse_declarations(self, env):
4697 for name, target in self.items:
4699 if not env.is_module_scope:
4700 error(self.pos, "import * only allowed at module level")
4702 env.has_import_star = 1
4703 self.import_star = 1
4705 target.analyse_target_declaration(env)
4707 def analyse_expressions(self, env):
4709 self.module.analyse_expressions(env)
4710 self.item = ExprNodes.PyTempNode(self.pos, env)
4711 self.item.allocate_temp(env)
4712 self.interned_items = []
4713 for name, target in self.items:
4715 for _, entry in env.entries.items():
4716 if not entry.is_type and entry.type.is_extension_type:
4717 env.use_utility_code(ExprNodes.type_test_utility_code)
4720 entry = env.lookup(target.name)
4721 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4722 continue # already cimported
4723 target.analyse_target_expression(env, None)
4724 if target.type is py_object_type:
4727 coerced_item = self.item.coerce_to(target.type, env)
4728 self.interned_items.append(
4729 (name, target, coerced_item))
4730 #target.release_target_temp(env) # was release_temp ?!?
4731 self.module.release_temp(env)
4732 self.item.release_temp(env)
4734 def generate_execution_code(self, code):
4735 self.module.generate_evaluation_code(code)
4736 if self.import_star:
4738 'if (%s(%s) < 0) %s;' % (
4740 self.module.py_result(),
4741 code.error_goto(self.pos)))
4742 for name, target, coerced_item in self.interned_items:
4743 cname = code.intern_identifier(name)
4745 '%s = PyObject_GetAttr(%s, %s); %s' % (
4747 self.module.py_result(),
4749 code.error_goto_if_null(self.item.result(), self.pos)))
4750 code.put_gotref(self.item.py_result())
4751 if coerced_item is None:
4752 target.generate_assignment_code(self.item, code)
4754 coerced_item.allocate_temp_result(code)
4755 coerced_item.generate_result_code(code)
4756 target.generate_assignment_code(coerced_item, code)
4757 if self.item.result() != coerced_item.result():
4758 code.put_decref_clear(self.item.result(), self.item.type)
4759 self.module.generate_disposal_code(code)
4760 self.module.free_temps(code)
4764 #------------------------------------------------------------------------------------
4766 # Runtime support code
4768 #------------------------------------------------------------------------------------
4770 utility_function_predeclarations = \
4773 #define INLINE __inline__
4775 #define INLINE __inline
4780 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4784 static int %(skip_dispatch_cname)s = 0;
4786 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4788 if Options.gcc_branch_hints:
4789 branch_prediction_macros = \
4792 /* Test for GCC > 2.95 */
4793 #if __GNUC__ > 2 || \
4794 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4795 #define likely(x) __builtin_expect(!!(x), 1)
4796 #define unlikely(x) __builtin_expect(!!(x), 0)
4797 #else /* __GNUC__ > 2 ... */
4798 #define likely(x) (x)
4799 #define unlikely(x) (x)
4800 #endif /* __GNUC__ > 2 ... */
4801 #else /* __GNUC__ */
4802 #define likely(x) (x)
4803 #define unlikely(x) (x)
4804 #endif /* __GNUC__ */
4807 branch_prediction_macros = \
4809 #define likely(x) (x)
4810 #define unlikely(x) (x)
4813 #get_name_predeclaration = \
4814 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4816 #get_name_interned_predeclaration = \
4817 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4819 #------------------------------------------------------------------------------------
4821 printing_utility_code = UtilityCode(
4823 static int __Pyx_Print(PyObject *, int); /*proto*/
4824 #if PY_MAJOR_VERSION >= 3
4825 static PyObject* %s = 0;
4826 static PyObject* %s = 0;
4828 """ % (Naming.print_function, Naming.print_function_kwargs),
4830 #if PY_MAJOR_VERSION < 3
4831 static PyObject *__Pyx_GetStdout(void) {
4832 PyObject *f = PySys_GetObject((char *)"stdout");
4834 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4839 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4844 if (!(f = __Pyx_GetStdout()))
4846 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4847 if (PyFile_SoftSpace(f, 1)) {
4848 if (PyFile_WriteString(" ", f) < 0)
4851 v = PyTuple_GET_ITEM(arg_tuple, i);
4852 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4854 if (PyString_Check(v)) {
4855 char *s = PyString_AsString(v);
4856 Py_ssize_t len = PyString_Size(v);
4858 isspace(Py_CHARMASK(s[len-1])) &&
4860 PyFile_SoftSpace(f, 0);
4864 if (PyFile_WriteString("\n", f) < 0)
4866 PyFile_SoftSpace(f, 0);
4871 #else /* Python 3 has a print function */
4873 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4874 PyObject* kwargs = 0;
4875 PyObject* result = 0;
4876 PyObject* end_string;
4877 if (!%(PRINT_FUNCTION)s) {
4878 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4879 if (!%(PRINT_FUNCTION)s)
4883 if (!%(PRINT_KWARGS)s) {
4884 %(PRINT_KWARGS)s = PyDict_New();
4885 if (!%(PRINT_KWARGS)s)
4887 end_string = PyUnicode_FromStringAndSize(" ", 1);
4890 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4891 Py_DECREF(end_string);
4894 Py_DECREF(end_string);
4896 kwargs = %(PRINT_KWARGS)s;
4898 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4906 """ % {'BUILTINS' : Naming.builtins_cname,
4907 'PRINT_FUNCTION' : Naming.print_function,
4908 'PRINT_KWARGS' : Naming.print_function_kwargs}
4912 printing_one_utility_code = UtilityCode(
4914 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4917 #if PY_MAJOR_VERSION < 3
4919 static int __Pyx_PrintOne(PyObject *o) {
4921 if (!(f = __Pyx_GetStdout()))
4923 if (PyFile_SoftSpace(f, 0)) {
4924 if (PyFile_WriteString(" ", f) < 0)
4927 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4929 if (PyFile_WriteString("\n", f) < 0)
4932 /* the line below is just to avoid compiler
4933 * compiler warnings about unused functions */
4934 return __Pyx_Print(NULL, 0);
4937 #else /* Python 3 has a print function */
4939 static int __Pyx_PrintOne(PyObject *o) {
4941 PyObject* arg_tuple = PyTuple_New(1);
4942 if (unlikely(!arg_tuple))
4945 PyTuple_SET_ITEM(arg_tuple, 0, o);
4946 res = __Pyx_Print(arg_tuple, 1);
4947 Py_DECREF(arg_tuple);
4953 requires=[printing_utility_code])
4957 #------------------------------------------------------------------------------------
4959 # The following function is based on do_raise() from ceval.c.
4961 raise_utility_code = UtilityCode(
4963 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4966 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4970 /* First, check the traceback argument, replacing None with NULL. */
4971 if (tb == Py_None) {
4975 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4976 PyErr_SetString(PyExc_TypeError,
4977 "raise: arg 3 must be a traceback or None");
4980 /* Next, replace a missing value with None */
4981 if (value == NULL) {
4985 #if PY_VERSION_HEX < 0x02050000
4986 if (!PyClass_Check(type))
4988 if (!PyType_Check(type))
4991 /* Raising an instance. The value should be a dummy. */
4992 if (value != Py_None) {
4993 PyErr_SetString(PyExc_TypeError,
4994 "instance exception may not have a separate value");
4997 /* Normalize to raise <class>, <instance> */
5000 #if PY_VERSION_HEX < 0x02050000
5001 if (PyInstance_Check(type)) {
5002 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5007 PyErr_SetString(PyExc_TypeError,
5008 "raise: exception must be an old-style class or instance");
5012 type = (PyObject*) Py_TYPE(type);
5014 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5015 PyErr_SetString(PyExc_TypeError,
5016 "raise: exception class must be a subclass of BaseException");
5021 __Pyx_ErrRestore(type, value, tb);
5031 #------------------------------------------------------------------------------------
5033 reraise_utility_code = UtilityCode(
5035 static void __Pyx_ReRaise(void); /*proto*/
5038 static void __Pyx_ReRaise(void) {
5039 PyThreadState *tstate = PyThreadState_GET();
5040 PyObject* tmp_type = tstate->curexc_type;
5041 PyObject* tmp_value = tstate->curexc_value;
5042 PyObject* tmp_tb = tstate->curexc_traceback;
5043 tstate->curexc_type = tstate->exc_type;
5044 tstate->curexc_value = tstate->exc_value;
5045 tstate->curexc_traceback = tstate->exc_traceback;
5046 tstate->exc_type = 0;
5047 tstate->exc_value = 0;
5048 tstate->exc_traceback = 0;
5049 Py_XDECREF(tmp_type);
5050 Py_XDECREF(tmp_value);
5055 #------------------------------------------------------------------------------------
5057 arg_type_test_utility_code = UtilityCode(
5059 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5060 const char *name, int exact); /*proto*/
5063 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5064 const char *name, int exact)
5067 PyErr_Format(PyExc_SystemError, "Missing type object");
5070 if (none_allowed && obj == Py_None) return 1;
5072 if (Py_TYPE(obj) == type) return 1;
5075 if (PyObject_TypeCheck(obj, type)) return 1;
5077 PyErr_Format(PyExc_TypeError,
5078 "Argument '%s' has incorrect type (expected %s, got %s)",
5079 name, type->tp_name, Py_TYPE(obj)->tp_name);
5084 #------------------------------------------------------------------------------------
5086 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5087 # many or too few positional arguments were found. This handles
5088 # Py_ssize_t formatting correctly.
5090 raise_argtuple_invalid_utility_code = UtilityCode(
5092 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5093 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5096 static void __Pyx_RaiseArgtupleInvalid(
5097 const char* func_name,
5101 Py_ssize_t num_found)
5103 Py_ssize_t num_expected;
5104 const char *number, *more_or_less;
5106 if (num_found < num_min) {
5107 num_expected = num_min;
5108 more_or_less = "at least";
5110 num_expected = num_max;
5111 more_or_less = "at most";
5114 more_or_less = "exactly";
5116 number = (num_expected == 1) ? "" : "s";
5117 PyErr_Format(PyExc_TypeError,
5118 #if PY_VERSION_HEX < 0x02050000
5119 "%s() takes %s %d positional argument%s (%d given)",
5121 "%s() takes %s %zd positional argument%s (%zd given)",
5123 func_name, more_or_less, num_expected, number, num_found);
5127 raise_keyword_required_utility_code = UtilityCode(
5129 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5132 static INLINE void __Pyx_RaiseKeywordRequired(
5133 const char* func_name,
5136 PyErr_Format(PyExc_TypeError,
5137 #if PY_MAJOR_VERSION >= 3
5138 "%s() needs keyword-only argument %U", func_name, kw_name);
5140 "%s() needs keyword-only argument %s", func_name,
5141 PyString_AS_STRING(kw_name));
5146 raise_double_keywords_utility_code = UtilityCode(
5148 static void __Pyx_RaiseDoubleKeywordsError(
5149 const char* func_name, PyObject* kw_name); /*proto*/
5152 static void __Pyx_RaiseDoubleKeywordsError(
5153 const char* func_name,
5156 PyErr_Format(PyExc_TypeError,
5157 #if PY_MAJOR_VERSION >= 3
5158 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5160 "%s() got multiple values for keyword argument '%s'", func_name,
5161 PyString_AS_STRING(kw_name));
5166 #------------------------------------------------------------------------------------
5168 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5169 # were passed to a function, or if any keywords were passed to a
5170 # function that does not accept them.
5172 keyword_string_check_utility_code = UtilityCode(
5174 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5175 const char* function_name, int kw_allowed); /*proto*/
5178 static INLINE int __Pyx_CheckKeywordStrings(
5180 const char* function_name,
5185 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5186 #if PY_MAJOR_VERSION < 3
5187 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5189 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5191 goto invalid_keyword_type;
5193 if ((!kw_allowed) && unlikely(key))
5194 goto invalid_keyword;
5196 invalid_keyword_type:
5197 PyErr_Format(PyExc_TypeError,
5198 "%s() keywords must be strings", function_name);
5201 PyErr_Format(PyExc_TypeError,
5202 #if PY_MAJOR_VERSION < 3
5203 "%s() got an unexpected keyword argument '%s'",
5204 function_name, PyString_AsString(key));
5206 "%s() got an unexpected keyword argument '%U'",
5207 function_name, key);
5213 #------------------------------------------------------------------------------------
5215 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5216 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5217 # keywords will raise an invalid keyword error.
5219 # Three kinds of errors are checked: 1) non-string keywords, 2)
5220 # unexpected keywords and 3) overlap with positional arguments.
5222 # If num_posargs is greater 0, it denotes the number of positional
5223 # arguments that were passed and that must therefore not appear
5224 # amongst the keywords as well.
5226 # This method does not check for required keyword arguments.
5229 parse_keywords_utility_code = UtilityCode(
5231 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5232 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5233 const char* function_name); /*proto*/
5236 static int __Pyx_ParseOptionalKeywords(
5238 PyObject **argnames[],
5241 Py_ssize_t num_pos_args,
5242 const char* function_name)
5244 PyObject *key = 0, *value = 0;
5247 PyObject*** first_kw_arg = argnames + num_pos_args;
5249 while (PyDict_Next(kwds, &pos, &key, &value)) {
5250 name = first_kw_arg;
5251 while (*name && (**name != key)) name++;
5253 values[name-argnames] = value;
5255 #if PY_MAJOR_VERSION < 3
5256 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5258 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5260 goto invalid_keyword_type;
5262 for (name = first_kw_arg; *name; name++) {
5263 #if PY_MAJOR_VERSION >= 3
5264 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5265 PyUnicode_Compare(**name, key) == 0) break;
5267 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5268 _PyString_Eq(**name, key)) break;
5272 values[name-argnames] = value;
5274 /* unexpected keyword found */
5275 for (name=argnames; name != first_kw_arg; name++) {
5276 if (**name == key) goto arg_passed_twice;
5277 #if PY_MAJOR_VERSION >= 3
5278 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5279 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5281 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5282 _PyString_Eq(**name, key)) goto arg_passed_twice;
5286 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5288 goto invalid_keyword;
5296 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5298 invalid_keyword_type:
5299 PyErr_Format(PyExc_TypeError,
5300 "%s() keywords must be strings", function_name);
5303 PyErr_Format(PyExc_TypeError,
5304 #if PY_MAJOR_VERSION < 3
5305 "%s() got an unexpected keyword argument '%s'",
5306 function_name, PyString_AsString(key));
5308 "%s() got an unexpected keyword argument '%U'",
5309 function_name, key);
5316 #------------------------------------------------------------------------------------
5318 traceback_utility_code = UtilityCode(
5320 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5323 #include "compile.h"
5324 #include "frameobject.h"
5325 #include "traceback.h"
5327 static void __Pyx_AddTraceback(const char *funcname) {
5328 PyObject *py_srcfile = 0;
5329 PyObject *py_funcname = 0;
5330 PyObject *py_globals = 0;
5331 PyObject *empty_string = 0;
5332 PyCodeObject *py_code = 0;
5333 PyFrameObject *py_frame = 0;
5335 #if PY_MAJOR_VERSION < 3
5336 py_srcfile = PyString_FromString(%(FILENAME)s);
5338 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5340 if (!py_srcfile) goto bad;
5342 #if PY_MAJOR_VERSION < 3
5343 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5345 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5349 #if PY_MAJOR_VERSION < 3
5350 py_funcname = PyString_FromString(funcname);
5352 py_funcname = PyUnicode_FromString(funcname);
5355 if (!py_funcname) goto bad;
5356 py_globals = PyModule_GetDict(%(GLOBALS)s);
5357 if (!py_globals) goto bad;
5358 #if PY_MAJOR_VERSION < 3
5359 empty_string = PyString_FromStringAndSize("", 0);
5361 empty_string = PyBytes_FromStringAndSize("", 0);
5363 if (!empty_string) goto bad;
5364 py_code = PyCode_New(
5365 0, /*int argcount,*/
5366 #if PY_MAJOR_VERSION >= 3
5367 0, /*int kwonlyargcount,*/
5370 0, /*int stacksize,*/
5372 empty_string, /*PyObject *code,*/
5373 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5374 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5375 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5376 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5377 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5378 py_srcfile, /*PyObject *filename,*/
5379 py_funcname, /*PyObject *name,*/
5380 %(LINENO)s, /*int firstlineno,*/
5381 empty_string /*PyObject *lnotab*/
5383 if (!py_code) goto bad;
5384 py_frame = PyFrame_New(
5385 PyThreadState_GET(), /*PyThreadState *tstate,*/
5386 py_code, /*PyCodeObject *code,*/
5387 py_globals, /*PyObject *globals,*/
5388 0 /*PyObject *locals*/
5390 if (!py_frame) goto bad;
5391 py_frame->f_lineno = %(LINENO)s;
5392 PyTraceBack_Here(py_frame);
5394 Py_XDECREF(py_srcfile);
5395 Py_XDECREF(py_funcname);
5396 Py_XDECREF(empty_string);
5397 Py_XDECREF(py_code);
5398 Py_XDECREF(py_frame);
5401 'FILENAME': Naming.filename_cname,
5402 'LINENO': Naming.lineno_cname,
5403 'CFILENAME': Naming.cfilenm_cname,
5404 'CLINENO': Naming.clineno_cname,
5405 'GLOBALS': Naming.module_cname,
5406 'EMPTY_TUPLE' : Naming.empty_tuple,
5409 restore_exception_utility_code = UtilityCode(
5411 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5412 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5415 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5416 PyObject *tmp_type, *tmp_value, *tmp_tb;
5417 PyThreadState *tstate = PyThreadState_GET();
5419 #if PY_MAJOR_VERSION >= 3
5420 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5421 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5422 tmp_type = tstate->exc_type;
5423 tmp_value = tstate->exc_value;
5424 tmp_tb = tstate->exc_traceback;
5425 PyErr_NormalizeException(&type, &value, &tb);
5426 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5427 tstate->exc_type = 0;
5428 tstate->exc_value = 0;
5429 tstate->exc_traceback = 0;
5430 PyException_SetContext(value, tmp_value);
5431 Py_DECREF(tmp_type);
5436 tmp_type = tstate->curexc_type;
5437 tmp_value = tstate->curexc_value;
5438 tmp_tb = tstate->curexc_traceback;
5439 tstate->curexc_type = type;
5440 tstate->curexc_value = value;
5441 tstate->curexc_traceback = tb;
5442 Py_XDECREF(tmp_type);
5443 Py_XDECREF(tmp_value);
5447 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5448 PyThreadState *tstate = PyThreadState_GET();
5449 *type = tstate->curexc_type;
5450 *value = tstate->curexc_value;
5451 *tb = tstate->curexc_traceback;
5453 tstate->curexc_type = 0;
5454 tstate->curexc_value = 0;
5455 tstate->curexc_traceback = 0;
5460 #------------------------------------------------------------------------------------
5462 unraisable_exception_utility_code = UtilityCode(
5464 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5467 static void __Pyx_WriteUnraisable(const char *name) {
5468 PyObject *old_exc, *old_val, *old_tb;
5470 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5471 #if PY_MAJOR_VERSION < 3
5472 ctx = PyString_FromString(name);
5474 ctx = PyUnicode_FromString(name);
5476 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5478 PyErr_WriteUnraisable(Py_None);
5480 PyErr_WriteUnraisable(ctx);
5485 requires=[restore_exception_utility_code])
5487 #------------------------------------------------------------------------------------
5489 set_vtable_utility_code = UtilityCode(
5491 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5494 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5495 PyObject *pycobj = 0;
5498 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5501 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5514 #------------------------------------------------------------------------------------
5516 get_vtable_utility_code = UtilityCode(
5518 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5521 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5525 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5528 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5529 if (!*(void **)vtabptr)
5542 #------------------------------------------------------------------------------------
5544 init_string_tab_utility_code = UtilityCode(
5546 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5549 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5551 #if PY_MAJOR_VERSION < 3
5552 if (t->is_unicode && (!t->is_identifier)) {
5553 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5554 } else if (t->intern) {
5555 *t->p = PyString_InternFromString(t->s);
5557 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5559 #else /* Python 3+ has unicode identifiers */
5560 if (t->is_identifier || (t->is_unicode && t->intern)) {
5561 *t->p = PyUnicode_InternFromString(t->s);
5562 } else if (t->is_unicode) {
5563 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5565 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5576 #------------------------------------------------------------------------------------
5578 get_exception_utility_code = UtilityCode(
5580 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5583 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5584 PyObject *tmp_type, *tmp_value, *tmp_tb;
5585 PyThreadState *tstate = PyThreadState_GET();
5586 *type = tstate->curexc_type;
5587 *value = tstate->curexc_value;
5588 *tb = tstate->curexc_traceback;
5589 tstate->curexc_type = 0;
5590 tstate->curexc_value = 0;
5591 tstate->curexc_traceback = 0;
5592 PyErr_NormalizeException(type, value, tb);
5593 if (PyErr_Occurred())
5598 tmp_type = tstate->exc_type;
5599 tmp_value = tstate->exc_value;
5600 tmp_tb = tstate->exc_traceback;
5601 tstate->exc_type = *type;
5602 tstate->exc_value = *value;
5603 tstate->exc_traceback = *tb;
5604 /* Make sure tstate is in a consistent state when we XDECREF
5605 these objects (XDECREF may run arbitrary code). */
5606 Py_XDECREF(tmp_type);
5607 Py_XDECREF(tmp_value);
5619 #------------------------------------------------------------------------------------
5621 reset_exception_utility_code = UtilityCode(
5623 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5624 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5627 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5628 PyThreadState *tstate = PyThreadState_GET();
5629 *type = tstate->exc_type;
5630 *value = tstate->exc_value;
5631 *tb = tstate->exc_traceback;
5637 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5638 PyObject *tmp_type, *tmp_value, *tmp_tb;
5639 PyThreadState *tstate = PyThreadState_GET();
5640 tmp_type = tstate->exc_type;
5641 tmp_value = tstate->exc_value;
5642 tmp_tb = tstate->exc_traceback;
5643 tstate->exc_type = type;
5644 tstate->exc_value = value;
5645 tstate->exc_traceback = tb;
5646 Py_XDECREF(tmp_type);
5647 Py_XDECREF(tmp_value);
5652 #------------------------------------------------------------------------------------
5654 force_init_threads_utility_code = UtilityCode(
5656 #ifndef __PYX_FORCE_INIT_THREADS
5657 #if PY_VERSION_HEX < 0x02040200
5658 #define __PYX_FORCE_INIT_THREADS 1
5660 #define __PYX_FORCE_INIT_THREADS 0
5665 #------------------------------------------------------------------------------------