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 scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
519 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
520 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
521 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
522 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
527 cname = struct_cname)
528 self.op_args_struct.defined_in_pxd = 1
529 self.op_args_struct.used = 1
533 if return_type.is_pyobject \
534 and (self.exception_value or self.exception_check) \
535 and self.exception_check != '+':
537 "Exception clause not allowed for function returning Python object")
539 if self.exception_value:
540 self.exception_value.analyse_const_expression(env)
541 exc_val = self.exception_value.get_constant_result_code()
542 if self.exception_check == '+':
543 exc_val_type = self.exception_value.type
544 if not exc_val_type.is_error and \
545 not exc_val_type.is_pyobject and \
546 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
547 error(self.exception_value.pos,
548 "Exception value must be a Python exception or cdef function with no arguments.")
550 if not return_type.assignable_from(self.exception_value.type):
551 error(self.exception_value.pos,
552 "Exception value incompatible with function return type")
553 exc_check = self.exception_check
554 if return_type.is_array:
556 "Function cannot return an array")
557 if return_type.is_cfunction:
559 "Function cannot return a function")
560 func_type = PyrexTypes.CFuncType(
561 return_type, func_type_args, self.has_varargs,
562 optional_arg_count = self.optional_arg_count,
563 exception_value = exc_val, exception_check = exc_check,
564 calling_convention = self.base.calling_convention,
565 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
566 if self.optional_arg_count:
567 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
568 return self.base.analyse(func_type, env)
571 class CArgDeclNode(Node):
572 # Item in a function declaration argument list.
574 # base_type CBaseTypeNode
575 # declarator CDeclaratorNode
576 # not_none boolean Tagged with 'not None'
577 # default ExprNode or None
578 # default_value PyObjectConst constant for default value
579 # is_self_arg boolean Is the "self" arg of an extension type method
580 # is_kw_only boolean Is a keyword-only argument
582 child_attrs = ["base_type", "declarator", "default"]
587 name_declarator = None
590 def analyse(self, env, nonempty = 0):
591 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
592 if self.type is None:
593 # The parser may missinterpret names as types...
595 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
597 self.declarator.name = self.base_type.name
598 self.base_type.name = None
599 self.base_type.is_basic_c_type = False
602 could_be_name = False
603 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
604 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
605 self.declarator.name = self.base_type.arg_name
606 return self.declarator.analyse(base_type, env, nonempty = nonempty)
608 return self.name_declarator, self.type
610 def calculate_default_value_code(self, code):
611 if self.default_value is None:
613 if self.default.is_literal:
614 # will not output any code, just assign the result_code
615 self.default.generate_evaluation_code(code)
616 return self.type.cast_code(self.default.result())
617 self.default_value = code.get_argument_default_const(self.type)
618 return self.default_value
620 def annotate(self, code):
622 self.default.annotate(code)
625 class CBaseTypeNode(Node):
626 # Abstract base class for C base type nodes.
628 # Processing during analyse_declarations phase:
635 class CAnalysedBaseTypeNode(Node):
640 def analyse(self, env, could_be_name = False):
643 class CSimpleBaseTypeNode(CBaseTypeNode):
645 # module_path [string] Qualifying name components
646 # is_basic_c_type boolean
649 # is_self_arg boolean Is self argument of C method
652 arg_name = None # in case the argument name was interpreted as a type
654 def analyse(self, env, could_be_name = False):
655 # Return type descriptor.
656 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
658 if self.is_basic_c_type:
659 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
661 error(self.pos, "Unrecognised type modifier combination")
662 elif self.name == "object" and not self.module_path:
663 type = py_object_type
664 elif self.name is None:
665 if self.is_self_arg and env.is_c_class_scope:
666 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
667 type = env.parent_type
669 type = py_object_type
672 scope = env.find_imported_module(self.module_path, self.pos)
676 if scope.is_c_class_scope:
677 scope = scope.global_scope()
678 entry = scope.lookup(self.name)
679 if entry and entry.is_type:
682 if self.is_self_arg and env.is_c_class_scope:
683 type = env.parent_type
685 type = py_object_type
686 self.arg_name = self.name
688 error(self.pos, "'%s' is not a type identifier" % self.name)
692 return PyrexTypes.error_type
694 class CBufferAccessTypeNode(CBaseTypeNode):
696 # positional_args [ExprNode] List of positional arguments
697 # keyword_args DictNode Keyword arguments
698 # base_type_node CBaseTypeNode
701 # type PyrexType.BufferType ...containing the right options
704 child_attrs = ["base_type_node", "positional_args",
705 "keyword_args", "dtype_node"]
711 def analyse(self, env, could_be_name = False):
712 base_type = self.base_type_node.analyse(env)
713 if base_type.is_error: return base_type
716 options = Buffer.analyse_buffer_options(
719 self.positional_args,
721 base_type.buffer_defaults)
723 self.type = PyrexTypes.BufferType(base_type, **options)
726 class CComplexBaseTypeNode(CBaseTypeNode):
727 # base_type CBaseTypeNode
728 # declarator CDeclaratorNode
730 child_attrs = ["base_type", "declarator"]
732 def analyse(self, env, could_be_name = False):
733 base = self.base_type.analyse(env, could_be_name)
734 _, type = self.declarator.analyse(base, env)
738 class CVarDefNode(StatNode):
739 # C variable definition or forward/extern function declaration.
741 # visibility 'private' or 'public' or 'extern'
742 # base_type CBaseTypeNode
743 # declarators [CDeclaratorNode]
746 # need_properties [entry]
748 # decorators [cython.locals(...)] or None
749 # directive_locals { string : NameNode } locals defined by cython.locals(...)
751 child_attrs = ["base_type", "declarators"]
755 directive_locals = {}
757 def analyse_declarations(self, env, dest_scope = None):
760 self.dest_scope = dest_scope
761 base_type = self.base_type.analyse(env)
762 if (dest_scope.is_c_class_scope
763 and self.visibility == 'public'
764 and base_type.is_pyobject
765 and (base_type.is_builtin_type or base_type.is_extension_type)):
766 self.need_properties = []
768 visibility = 'private'
770 need_property = False
771 visibility = self.visibility
773 for declarator in self.declarators:
774 name_declarator, type = declarator.analyse(base_type, env)
775 if not type.is_complete():
776 if not (self.visibility == 'extern' and type.is_array):
777 error(declarator.pos,
778 "Variable type '%s' is incomplete" % type)
779 if self.visibility == 'extern' and type.is_pyobject:
780 error(declarator.pos,
781 "Python object cannot be declared extern")
782 name = name_declarator.name
783 cname = name_declarator.cname
785 error(declarator.pos, "Missing name in declaration.")
787 if type.is_cfunction:
788 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
789 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
791 if entry is not None:
792 entry.directive_locals = self.directive_locals
794 if self.directive_locals:
795 s.error("Decorators can only be followed by functions")
796 if self.in_pxd and self.visibility != 'extern':
798 "Only 'extern' C variable declaration allowed in .pxd file")
799 entry = dest_scope.declare_var(name, type, declarator.pos,
800 cname = cname, visibility = visibility, is_cdef = 1)
802 self.need_properties.append(entry)
803 entry.needs_property = 1
806 class CStructOrUnionDefNode(StatNode):
808 # cname string or None
809 # kind "struct" or "union"
810 # typedef_flag boolean
811 # visibility "public" or "private"
813 # attributes [CVarDefNode] or None
816 child_attrs = ["attributes"]
818 def analyse_declarations(self, env):
820 if self.attributes is not None:
821 scope = StructOrUnionScope(self.name)
822 self.entry = env.declare_struct_or_union(
823 self.name, self.kind, scope, self.typedef_flag, self.pos,
824 self.cname, visibility = self.visibility)
825 if self.attributes is not None:
826 if self.in_pxd and not env.in_cinclude:
827 self.entry.defined_in_pxd = 1
828 for attr in self.attributes:
829 attr.analyse_declarations(env, scope)
830 if self.visibility != 'extern':
831 need_typedef_indirection = False
832 for attr in scope.var_entries:
835 type = type.base_type
836 if type == self.entry.type:
837 error(attr.pos, "Struct cannot contain itself as a member.")
838 if self.typedef_flag:
840 type = type.base_type
841 if type == self.entry.type:
842 need_typedef_indirection = True
843 if need_typedef_indirection:
844 # C can't handle typedef structs that refer to themselves.
845 struct_entry = self.entry
846 self.entry = env.declare_typedef(
847 self.name, struct_entry.type, self.pos,
848 cname = self.cname, visibility='ignore')
849 struct_entry.type.typedef_flag = False
850 # FIXME: this might be considered a hack ;-)
851 struct_entry.cname = struct_entry.type.cname = '_' + self.cname
853 def analyse_expressions(self, env):
856 def generate_execution_code(self, code):
860 class CEnumDefNode(StatNode):
861 # name string or None
862 # cname string or None
863 # items [CEnumDefItemNode]
864 # typedef_flag boolean
865 # visibility "public" or "private"
869 child_attrs = ["items"]
871 def analyse_declarations(self, env):
872 self.entry = env.declare_enum(self.name, self.pos,
873 cname = self.cname, typedef_flag = self.typedef_flag,
874 visibility = self.visibility)
875 if self.items is not None:
876 if self.in_pxd and not env.in_cinclude:
877 self.entry.defined_in_pxd = 1
878 for item in self.items:
879 item.analyse_declarations(env, self.entry)
881 def analyse_expressions(self, env):
882 if self.visibility == 'public':
883 self.temp = env.allocate_temp_pyobject()
884 env.release_temp(self.temp)
886 def generate_execution_code(self, code):
887 if self.visibility == 'public':
888 for item in self.entry.enum_values:
889 code.putln("%s = PyInt_FromLong(%s); %s" % (
892 code.error_goto_if_null(self.temp, item.pos)))
893 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
897 code.error_goto(item.pos)))
898 code.putln("%s = 0;" % self.temp)
901 class CEnumDefItemNode(StatNode):
903 # cname string or None
904 # value ExprNode or None
906 child_attrs = ["value"]
908 def analyse_declarations(self, env, enum_entry):
910 self.value.analyse_const_expression(env)
911 if not self.value.type.is_int:
912 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
913 self.value.analyse_const_expression(env)
914 entry = env.declare_const(self.name, enum_entry.type,
915 self.value, self.pos, cname = self.cname,
916 visibility = enum_entry.visibility)
917 enum_entry.enum_values.append(entry)
920 class CTypeDefNode(StatNode):
921 # base_type CBaseTypeNode
922 # declarator CDeclaratorNode
923 # visibility "public" or "private"
926 child_attrs = ["base_type", "declarator"]
928 def analyse_declarations(self, env):
929 base = self.base_type.analyse(env)
930 name_declarator, type = self.declarator.analyse(base, env)
931 name = name_declarator.name
932 cname = name_declarator.cname
933 entry = env.declare_typedef(name, type, self.pos,
934 cname = cname, visibility = self.visibility)
935 if self.in_pxd and not env.in_cinclude:
936 entry.defined_in_pxd = 1
938 def analyse_expressions(self, env):
940 def generate_execution_code(self, code):
944 class FuncDefNode(StatNode, BlockNode):
945 # Base class for function definition nodes.
947 # return_type PyrexType
948 # #filename string C name of filename string const
950 # needs_closure boolean Whether or not this function has inner functions/classes/yield
951 # directive_locals { string : NameNode } locals defined by cython.locals(...)
955 needs_closure = False
957 def analyse_default_values(self, env):
958 genv = env.global_scope()
959 for arg in self.args:
962 arg.default.analyse_types(env)
963 arg.default = arg.default.coerce_to(arg.type, genv)
964 arg.default.allocate_temps(genv)
967 "This argument cannot have a default value")
970 def need_gil_acquisition(self, lenv):
973 def create_local_scope(self, env):
975 while env.is_py_class_scope or env.is_c_class_scope:
976 env = env.outer_scope
977 if self.needs_closure:
978 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
980 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
981 lenv.return_type = self.return_type
982 type = self.entry.type
983 if type.is_cfunction:
984 lenv.nogil = type.nogil and not type.with_gil
985 self.local_scope = lenv
988 def generate_function_definitions(self, env, code):
991 lenv = self.local_scope
993 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
994 self.entry.scope.is_c_class_scope)
996 # Generate C code for header and body of function
997 code.enter_cfunc_scope()
998 code.return_from_error_cleanup_label = code.new_label()
1000 # ----- Top-level constants used by this function
1001 code.mark_pos(self.pos)
1002 self.generate_cached_builtins_decls(lenv, code)
1003 # ----- Function header
1006 self.py_func.generate_function_header(code,
1007 with_pymethdef = env.is_py_class_scope,
1009 self.generate_function_header(code,
1010 with_pymethdef = env.is_py_class_scope)
1011 # ----- Local variable declarations
1012 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1013 self.generate_argument_declarations(lenv, code)
1014 if self.needs_closure:
1015 code.putln("/* TODO: declare and create scope object */")
1016 code.put_var_declarations(lenv.var_entries)
1018 if not self.return_type.is_void:
1019 if self.return_type.is_pyobject:
1023 (self.return_type.declaration_code(
1024 Naming.retval_cname),
1026 tempvardecl_code = code.insertion_point()
1027 self.generate_keyword_list(code)
1028 # ----- Extern library function declarations
1029 lenv.generate_library_function_declarations(code)
1030 # ----- GIL acquisition
1031 acquire_gil = self.need_gil_acquisition(lenv)
1033 env.use_utility_code(force_init_threads_utility_code)
1034 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1035 # ----- Automatic lead-ins for certain special functions
1037 code.put_setup_refcount_context(self.entry.name)
1038 if is_getbuffer_slot:
1039 self.getbuffer_init(code)
1040 # ----- Fetch arguments
1041 self.generate_argument_parsing_code(env, code)
1042 # If an argument is assigned to in the body, we must
1043 # incref it to properly keep track of refcounts.
1044 for entry in lenv.arg_entries:
1045 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1046 code.put_var_incref(entry)
1047 # ----- Initialise local variables
1048 for entry in lenv.var_entries:
1049 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1050 code.put_init_var_to_py_none(entry)
1051 # ----- Initialise local buffer auxiliary variables
1052 for entry in lenv.var_entries + lenv.arg_entries:
1053 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1054 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1055 # ----- Check and convert arguments
1056 self.generate_argument_type_tests(code)
1057 # ----- Acquire buffer arguments
1058 for entry in lenv.arg_entries:
1059 if entry.type.is_buffer:
1060 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1061 # ----- Function body
1062 self.body.generate_execution_code(code)
1063 # ----- Default return value
1065 if self.return_type.is_pyobject:
1066 #if self.return_type.is_extension_type:
1067 # lhs = "(PyObject *)%s" % Naming.retval_cname
1069 lhs = Naming.retval_cname
1070 code.put_init_to_py_none(lhs, self.return_type)
1072 val = self.return_type.default_value
1074 code.putln("%s = %s;" % (Naming.retval_cname, val))
1075 # ----- Error cleanup
1076 if code.error_label in code.labels_used:
1077 code.put_goto(code.return_label)
1078 code.put_label(code.error_label)
1079 # cleanup temps the old way
1080 code.put_var_xdecrefs(lenv.temp_entries)
1081 # cleanup temps the new way
1082 for cname, type in code.funcstate.all_managed_temps():
1083 code.put_xdecref(cname, type)
1085 # Clean up buffers -- this calls a Python function
1086 # so need to save and restore error state
1087 buffers_present = len(lenv.buffer_entries) > 0
1089 code.globalstate.use_utility_code(restore_exception_utility_code)
1090 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1091 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1092 for entry in lenv.buffer_entries:
1093 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1094 #code.putln("%s = 0;" % entry.cname)
1095 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1097 err_val = self.error_value()
1098 exc_check = self.caller_will_check_exceptions()
1099 if err_val is not None or exc_check:
1100 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1102 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1103 % self.entry.qualified_name, 0)
1105 '__Pyx_WriteUnraisable("%s");' %
1106 self.entry.qualified_name)
1107 env.use_utility_code(unraisable_exception_utility_code)
1108 env.use_utility_code(restore_exception_utility_code)
1109 default_retval = self.return_type.default_value
1110 if err_val is None and default_retval:
1111 err_val = default_retval
1112 if err_val is not None:
1115 Naming.retval_cname,
1118 if is_getbuffer_slot:
1119 self.getbuffer_error_cleanup(code)
1121 # If we are using the non-error cleanup section we should
1122 # jump past it if we have an error. The if-test below determine
1123 # whether this section is used.
1124 if buffers_present or is_getbuffer_slot:
1125 code.put_goto(code.return_from_error_cleanup_label)
1128 # ----- Non-error return cleanup
1129 # If you add anything here, remember to add a condition to the
1130 # if-test above in the error block (so that it can jump past this
1132 code.put_label(code.return_label)
1133 for entry in lenv.buffer_entries:
1135 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1136 if is_getbuffer_slot:
1137 self.getbuffer_normal_cleanup(code)
1138 # ----- Return cleanup for both error and no-error return
1139 code.put_label(code.return_from_error_cleanup_label)
1140 if not Options.init_local_none:
1141 for entry in lenv.var_entries:
1142 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1143 entry.xdecref_cleanup = 1
1144 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1145 # Decref any increfed args
1146 for entry in lenv.arg_entries:
1147 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1148 code.put_var_decref(entry)
1150 # code.putln("/* TODO: decref scope object */")
1152 # This code is duplicated in ModuleNode.generate_module_init_func
1154 default_retval = self.return_type.default_value
1155 err_val = self.error_value()
1156 if err_val is None and default_retval:
1157 err_val = default_retval
1158 if self.return_type.is_pyobject:
1159 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1161 code.put_finish_refcount_context()
1164 code.putln("PyGILState_Release(_save);")
1166 if not self.return_type.is_void:
1167 code.putln("return %s;" % Naming.retval_cname)
1170 # ----- Go back and insert temp variable declarations
1171 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1172 tempvardecl_code.put_temp_declarations(code.funcstate)
1173 # ----- Python version
1174 code.exit_cfunc_scope()
1176 self.py_func.generate_function_definitions(env, code)
1177 self.generate_wrapper_functions(code)
1179 def declare_argument(self, env, arg):
1180 if arg.type.is_void:
1181 error(arg.pos, "Invalid use of 'void'")
1182 elif not arg.type.is_complete() and not arg.type.is_array:
1184 "Argument type '%s' is incomplete" % arg.type)
1185 return env.declare_arg(arg.name, arg.type, arg.pos)
1187 def generate_wrapper_functions(self, code):
1190 def generate_execution_code(self, code):
1191 # Evaluate and store argument default values
1192 for arg in self.args:
1193 default = arg.default
1195 if not default.is_literal:
1196 default.generate_evaluation_code(code)
1197 default.make_owned_reference(code)
1198 result = default.result_as(arg.type)
1201 arg.calculate_default_value_code(code),
1203 if arg.type.is_pyobject:
1204 code.put_giveref(default.result())
1205 default.generate_post_assignment_code(code)
1206 default.free_temps(code)
1207 # For Python class methods, create and store function object
1209 self.assmt.generate_execution_code(code)
1212 # Special code for the __getbuffer__ function
1214 def getbuffer_init(self, code):
1215 info = self.local_scope.arg_entries[1].cname
1216 # Python 3.0 betas have a bug in memoryview which makes it call
1217 # getbuffer with a NULL parameter. For now we work around this;
1218 # the following line should be removed when this bug is fixed.
1219 code.putln("if (%s == NULL) return 0;" % info)
1220 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1221 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1223 def getbuffer_error_cleanup(self, code):
1224 info = self.local_scope.arg_entries[1].cname
1225 code.put_gotref("%s->obj" % info)
1226 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1229 def getbuffer_normal_cleanup(self, code):
1230 info = self.local_scope.arg_entries[1].cname
1231 code.putln("if (%s->obj == Py_None) {" % info)
1232 code.put_gotref("Py_None")
1233 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1236 class CFuncDefNode(FuncDefNode):
1237 # C function definition.
1239 # modifiers ['inline']
1240 # visibility 'private' or 'public' or 'extern'
1241 # base_type CBaseTypeNode
1242 # declarator CDeclaratorNode
1245 # decorators [DecoratorNode] list of decorators
1247 # with_gil boolean Acquire GIL around body
1249 # py_func wrapper for calling from Python
1250 # overridable whether or not this is a cpdef function
1251 # inline_in_pxd whether this is an inline function in a pxd file
1253 child_attrs = ["base_type", "declarator", "body", "py_func"]
1255 inline_in_pxd = False
1257 directive_locals = {}
1259 def unqualified_name(self):
1260 return self.entry.name
1262 def analyse_declarations(self, env):
1263 if 'locals' in env.directives and env.directives['locals']:
1264 self.directive_locals = env.directives['locals']
1265 directive_locals = self.directive_locals
1266 base_type = self.base_type.analyse(env)
1267 # The 2 here is because we need both function and argument names.
1268 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1269 if not type.is_cfunction:
1271 "Suite attached to non-function declaration")
1272 # Remember the actual type according to the function header
1273 # written here, because the type in the symbol table entry
1274 # may be different if we're overriding a C method inherited
1275 # from the base type of an extension type.
1277 type.is_overridable = self.overridable
1278 declarator = self.declarator
1279 while not hasattr(declarator, 'args'):
1280 declarator = declarator.base
1281 self.args = declarator.args
1282 for formal_arg, type_arg in zip(self.args, type.args):
1283 formal_arg.type = type_arg.type
1284 formal_arg.name = type_arg.name
1285 formal_arg.cname = type_arg.cname
1286 name = name_declarator.name
1287 cname = name_declarator.cname
1288 self.entry = env.declare_cfunction(
1289 name, type, self.pos,
1290 cname = cname, visibility = self.visibility,
1291 defining = self.body is not None,
1292 api = self.api, modifiers = self.modifiers)
1293 self.entry.inline_func_in_pxd = self.inline_in_pxd
1294 self.return_type = type.return_type
1296 if self.overridable and not env.is_module_scope:
1297 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1298 # An error will be produced in the cdef function
1299 self.overridable = False
1301 if self.overridable:
1303 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1304 self.py_func = DefNode(pos = self.pos,
1305 name = self.entry.name,
1308 starstar_arg = None,
1310 body = py_func_body,
1312 self.py_func.is_module_scope = env.is_module_scope
1313 self.py_func.analyse_declarations(env)
1314 self.entry.as_variable = self.py_func.entry
1315 # Reset scope entry the above cfunction
1316 env.entries[name] = self.entry
1317 if not env.is_module_scope or Options.lookup_module_cpdef:
1318 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1319 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1321 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1323 args = self.type.args
1324 if omit_optional_args:
1325 args = args[:len(args) - self.type.optional_arg_count]
1326 arg_names = [arg.name for arg in args]
1328 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1330 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1331 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1332 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1333 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)
1334 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1336 def declare_arguments(self, env):
1337 for arg in self.type.args:
1339 error(arg.pos, "Missing argument name")
1340 self.declare_argument(env, arg)
1342 def need_gil_acquisition(self, lenv):
1343 return self.type.with_gil
1345 def gil_check(self, env):
1347 with_gil = type.with_gil
1348 if type.nogil and not with_gil:
1349 if type.return_type.is_pyobject:
1351 "Function with Python return type cannot be declared nogil")
1352 for entry in env.var_entries + env.temp_entries:
1353 if entry.type.is_pyobject:
1354 error(self.pos, "Function declared nogil has Python locals or temporaries")
1356 def analyse_expressions(self, env):
1357 if self.py_func is not None:
1358 # this will also analyse the default values
1359 self.py_func.analyse_expressions(env)
1361 self.analyse_default_values(env)
1363 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1366 visibility = self.entry.visibility
1367 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1368 arg_decls.append(arg.declaration_code())
1369 if with_dispatch and self.overridable:
1370 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1371 if type.optional_arg_count and with_opt_args:
1372 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1373 if type.has_varargs:
1374 arg_decls.append("...")
1376 arg_decls = ["void"]
1378 cname = self.entry.func_cname
1379 entity = type.function_header_code(cname, ', '.join(arg_decls))
1380 if visibility == 'public':
1381 dll_linkage = "DL_EXPORT"
1384 header = self.return_type.declaration_code(entity,
1385 dll_linkage = dll_linkage)
1386 if visibility == 'extern':
1387 storage_class = "%s " % Naming.extern_c_macro
1388 elif visibility == 'public':
1391 storage_class = "static "
1392 code.putln("%s%s %s {" % (
1394 ' '.join(self.modifiers).upper(), # macro forms
1397 def generate_argument_declarations(self, env, code):
1398 for arg in self.args:
1400 result = arg.calculate_default_value_code(code)
1401 code.putln('%s = %s;' % (
1402 arg.type.declaration_code(arg.cname), result))
1404 def generate_keyword_list(self, code):
1407 def generate_argument_parsing_code(self, env, code):
1409 if self.type.optional_arg_count:
1410 code.putln('if (%s) {' % Naming.optional_args_cname)
1411 for arg in self.args:
1413 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1414 declarator = arg.declarator
1415 while not hasattr(declarator, 'name'):
1416 declarator = declarator.base
1417 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1419 for _ in range(self.type.optional_arg_count):
1423 def generate_argument_conversion_code(self, code):
1426 def generate_argument_type_tests(self, code):
1427 # Generate type tests for args whose type in a parent
1428 # class is a supertype of the declared type.
1429 for arg in self.type.args:
1430 if arg.needs_type_test:
1431 self.generate_arg_type_test(arg, code)
1433 def generate_arg_type_test(self, arg, code):
1434 # Generate type test for one argument.
1435 if arg.type.typeobj_is_available():
1436 typeptr_cname = arg.type.typeptr_cname
1437 arg_code = "((PyObject *)%s)" % arg.cname
1439 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1444 type.is_builtin_type,
1445 code.error_goto(arg.pos)))
1447 error(arg.pos, "Cannot test type of extern C class "
1448 "without type object name specification")
1450 def error_value(self):
1451 if self.return_type.is_pyobject:
1455 return self.entry.type.exception_value
1457 def caller_will_check_exceptions(self):
1458 return self.entry.type.exception_check
1460 def generate_wrapper_functions(self, code):
1461 # If the C signature of a function has changed, we need to generate
1462 # wrappers to put in the slots here.
1465 func_type = entry.type
1466 while entry.prev_entry is not None:
1468 entry = entry.prev_entry
1469 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1471 self.generate_function_header(code,
1473 with_dispatch = entry.type.is_overridable,
1474 with_opt_args = entry.type.optional_arg_count,
1475 cname = entry.func_cname)
1476 if not self.return_type.is_void:
1478 args = self.type.args
1479 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1480 if entry.type.is_overridable:
1481 arglist.append(Naming.skip_dispatch_cname)
1482 elif func_type.is_overridable:
1484 if entry.type.optional_arg_count:
1485 arglist.append(Naming.optional_args_cname)
1486 elif func_type.optional_arg_count:
1487 arglist.append('NULL')
1488 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1492 class PyArgDeclNode(Node):
1493 # Argument which must be a Python object (used
1494 # for * and ** arguments).
1497 # entry Symtab.Entry
1501 class DecoratorNode(Node):
1504 # decorator NameNode or CallNode
1505 child_attrs = ['decorator']
1508 class DefNode(FuncDefNode):
1509 # A Python function definition.
1511 # name string the Python name of the function
1512 # decorators [DecoratorNode] list of decorators
1513 # args [CArgDeclNode] formal arguments
1514 # star_arg PyArgDeclNode or None * argument
1515 # starstar_arg PyArgDeclNode or None ** argument
1516 # doc EncodedString or None
1519 # The following subnode is constructed internally
1520 # when the def statement is inside a Python class definition.
1522 # assmt AssignmentNode Function construction/assignment
1524 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1528 num_required_kw_args = 0
1529 reqd_kw_flags_cname = "0"
1535 def __init__(self, pos, **kwds):
1536 FuncDefNode.__init__(self, pos, **kwds)
1538 for arg in self.args:
1545 self.num_kwonly_args = k
1546 self.num_required_kw_args = rk
1547 self.num_required_args = r
1549 def as_cfunction(self, cfunc=None, scope=None):
1551 error(self.star_arg.pos, "cdef function cannot have star argument")
1552 if self.starstar_arg:
1553 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1556 for formal_arg in self.args:
1557 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1558 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1560 type = py_object_type,
1561 pos = formal_arg.pos))
1562 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1564 has_varargs = False,
1565 exception_value = None,
1566 exception_check = False,
1569 is_overridable = True)
1570 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1572 cfunc_type = cfunc.type
1573 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1574 error(self.pos, "wrong number of arguments")
1575 error(declarator.pos, "previous declaration here")
1576 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1577 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1578 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1579 formal_arg.type = type_arg.type
1580 formal_arg.name_declarator = name_declarator
1582 if cfunc_type.exception_value is None:
1583 exception_value = None
1585 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1586 declarator = CFuncDeclaratorNode(self.pos,
1587 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1589 has_varargs = False,
1590 exception_check = cfunc_type.exception_check,
1591 exception_value = exception_value,
1592 with_gil = cfunc_type.with_gil,
1593 nogil = cfunc_type.nogil)
1594 return CFuncDefNode(self.pos,
1596 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1597 declarator = declarator,
1600 overridable = cfunc_type.is_overridable,
1602 with_gil = cfunc_type.with_gil,
1603 nogil = cfunc_type.nogil,
1604 visibility = 'private',
1606 directive_locals = cfunc.directive_locals)
1608 def analyse_declarations(self, env):
1609 if 'locals' in env.directives:
1610 directive_locals = env.directives['locals']
1612 directive_locals = {}
1613 self.directive_locals = directive_locals
1614 for arg in self.args:
1615 if hasattr(arg, 'name'):
1617 name_declarator = None
1619 base_type = arg.base_type.analyse(env)
1620 name_declarator, type = \
1621 arg.declarator.analyse(base_type, env)
1622 arg.name = name_declarator.name
1623 if arg.name in directive_locals:
1624 type_node = directive_locals[arg.name]
1625 other_type = type_node.analyse_as_type(env)
1626 if other_type is None:
1627 error(type_node.pos, "Not a type")
1628 elif (type is not PyrexTypes.py_object_type
1629 and not type.same_as(other_type)):
1630 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1631 error(type_node.pos, "Previous declaration here")
1634 if name_declarator and name_declarator.cname:
1636 "Python function argument cannot have C name specification")
1637 arg.type = type.as_argument_type()
1639 arg.needs_conversion = 0
1640 arg.needs_type_test = 0
1642 if arg.not_none and not arg.type.is_extension_type:
1644 "Only extension type arguments can have 'not None'")
1645 self.declare_pyfunction(env)
1646 self.analyse_signature(env)
1647 self.return_type = self.entry.signature.return_type()
1649 def analyse_signature(self, env):
1650 any_type_tests_needed = 0
1651 # Use the simpler calling signature for zero- and one-argument functions.
1652 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1653 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1654 if len(self.args) == 0:
1655 self.entry.signature = TypeSlots.pyfunction_noargs
1656 elif len(self.args) == 1:
1657 if self.args[0].default is None and not self.args[0].kw_only:
1658 self.entry.signature = TypeSlots.pyfunction_onearg
1659 elif self.entry.signature is TypeSlots.pymethod_signature:
1660 if len(self.args) == 1:
1661 self.entry.signature = TypeSlots.unaryfunc
1662 elif len(self.args) == 2:
1663 if self.args[1].default is None and not self.args[1].kw_only:
1664 self.entry.signature = TypeSlots.ibinaryfunc
1665 elif self.entry.is_special:
1666 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1667 sig = self.entry.signature
1668 nfixed = sig.num_fixed_args()
1669 for i in range(nfixed):
1670 if i < len(self.args):
1673 if sig.is_self_arg(i):
1675 arg.hdr_type = arg.type = env.parent_type
1676 arg.needs_conversion = 0
1678 arg.hdr_type = sig.fixed_arg_type(i)
1679 if not arg.type.same_as(arg.hdr_type):
1680 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1681 arg.needs_type_test = 1
1682 any_type_tests_needed = 1
1684 arg.needs_conversion = 1
1685 if arg.needs_conversion:
1686 arg.hdr_cname = Naming.arg_prefix + arg.name
1688 arg.hdr_cname = Naming.var_prefix + arg.name
1690 self.bad_signature()
1692 if nfixed < len(self.args):
1693 if not sig.has_generic_args:
1694 self.bad_signature()
1695 for arg in self.args:
1696 if arg.is_generic and \
1697 (arg.type.is_extension_type or arg.type.is_builtin_type):
1698 arg.needs_type_test = 1
1699 any_type_tests_needed = 1
1700 if any_type_tests_needed:
1701 env.use_utility_code(arg_type_test_utility_code)
1703 def bad_signature(self):
1704 sig = self.entry.signature
1705 expected_str = "%d" % sig.num_fixed_args()
1706 if sig.has_generic_args:
1707 expected_str = expected_str + " or more"
1709 if name.startswith("__") and name.endswith("__"):
1710 desc = "Special method"
1714 "%s %s has wrong number of arguments "
1715 "(%d declared, %s expected)" % (
1716 desc, self.name, len(self.args), expected_str))
1718 def signature_has_nongeneric_args(self):
1719 argcount = len(self.args)
1720 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1724 def signature_has_generic_args(self):
1725 return self.entry.signature.has_generic_args
1727 def declare_pyfunction(self, env):
1728 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1730 entry = env.lookup_here(self.name)
1731 if entry and entry.type.is_cfunction and not self.is_wrapper:
1732 warning(self.pos, "Overriding cdef method with def method.", 5)
1733 entry = env.declare_pyfunction(self.name, self.pos)
1735 prefix = env.scope_prefix
1736 entry.func_cname = \
1737 Naming.pyfunc_prefix + prefix + name
1738 entry.pymethdef_cname = \
1739 Naming.pymethdef_prefix + prefix + name
1740 if Options.docstrings:
1741 entry.doc = embed_position(self.pos, self.doc)
1743 Naming.funcdoc_prefix + prefix + name
1747 def declare_arguments(self, env):
1748 for arg in self.args:
1750 error(arg.pos, "Missing argument name")
1751 if arg.needs_conversion:
1752 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1753 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1754 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1755 if arg.type.is_pyobject:
1756 arg.entry.init = "0"
1757 arg.entry.init_to_none = 0
1759 arg.entry = self.declare_argument(env, arg)
1761 arg.entry.is_self_arg = arg.is_self_arg
1763 if arg.is_self_arg or \
1764 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1765 arg.entry.is_declared_generic = 1
1766 self.declare_python_arg(env, self.star_arg)
1767 self.declare_python_arg(env, self.starstar_arg)
1769 def declare_python_arg(self, env, arg):
1771 entry = env.declare_var(arg.name,
1772 PyrexTypes.py_object_type, arg.pos)
1775 entry.init_to_none = 0
1776 entry.xdecref_cleanup = 1
1778 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1780 def analyse_expressions(self, env):
1781 self.analyse_default_values(env)
1782 if env.is_py_class_scope:
1783 self.synthesize_assignment_node(env)
1785 def synthesize_assignment_node(self, env):
1787 self.assmt = SingleAssignmentNode(self.pos,
1788 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1789 rhs = ExprNodes.UnboundMethodNode(self.pos,
1790 class_cname = env.class_obj_cname,
1791 function = ExprNodes.PyCFunctionNode(self.pos,
1792 pymethdef_cname = self.entry.pymethdef_cname)))
1793 self.assmt.analyse_declarations(env)
1794 self.assmt.analyse_expressions(env)
1796 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1798 sig = self.entry.signature
1799 if sig.has_dummy_arg:
1800 arg_code_list.append(
1801 "PyObject *%s" % Naming.self_cname)
1802 for arg in self.args:
1803 if not arg.is_generic:
1805 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1807 arg_code_list.append(
1808 arg.hdr_type.declaration_code(arg.hdr_cname))
1809 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1810 arg_code_list.append("PyObject *unused")
1811 if sig.has_generic_args:
1812 arg_code_list.append(
1813 "PyObject *%s, PyObject *%s"
1814 % (Naming.args_cname, Naming.kwds_cname))
1815 arg_code = ", ".join(arg_code_list)
1816 dc = self.return_type.declaration_code(self.entry.func_cname)
1817 header = "static %s(%s)" % (dc, arg_code)
1818 code.putln("%s; /*proto*/" % header)
1821 if self.entry.doc and Options.docstrings:
1822 docstr = self.entry.doc
1823 if not isinstance(docstr, str):
1824 docstr = docstr.utf8encode()
1826 'static char %s[] = "%s";' % (
1827 self.entry.doc_cname,
1828 split_docstring(escape_byte_string(docstr))))
1831 "static PyMethodDef %s = " %
1832 self.entry.pymethdef_cname)
1833 code.put_pymethoddef(self.entry, ";")
1834 code.putln("%s {" % header)
1836 def generate_argument_declarations(self, env, code):
1837 for arg in self.args:
1838 if arg.is_generic: # or arg.needs_conversion:
1839 if arg.needs_conversion:
1840 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1842 code.put_var_declaration(arg.entry)
1844 def generate_keyword_list(self, code):
1845 if self.signature_has_generic_args() and \
1846 self.signature_has_nongeneric_args():
1848 "static PyObject **%s[] = {" %
1849 Naming.pykwdlist_cname)
1850 for arg in self.args:
1852 pystring_cname = code.intern_identifier(arg.name)
1853 code.put('&%s,' % pystring_cname)
1856 def generate_argument_parsing_code(self, env, code):
1857 # Generate PyArg_ParseTuple call for generic
1858 # arguments, if any.
1859 if self.entry.signature.has_dummy_arg:
1860 # get rid of unused argument warning
1861 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1863 old_error_label = code.new_error_label()
1864 our_error_label = code.error_label
1865 end_label = code.new_label("argument_unpacking_done")
1867 has_kwonly_args = self.num_kwonly_args > 0
1868 has_star_or_kw_args = self.star_arg is not None \
1869 or self.starstar_arg is not None or has_kwonly_args
1871 if not self.signature_has_generic_args():
1872 if has_star_or_kw_args:
1873 error(self.pos, "This method cannot have * or keyword arguments")
1874 self.generate_argument_conversion_code(code)
1876 elif not self.signature_has_nongeneric_args():
1877 # func(*args) or func(**kw) or func(*args, **kw)
1878 self.generate_stararg_copy_code(code)
1881 positional_args = []
1884 for arg in self.args:
1885 arg_entry = arg.entry
1889 if not arg.is_self_arg:
1891 kw_only_args.append(arg)
1893 positional_args.append(arg)
1895 kw_only_args.append(arg)
1898 error(arg.pos, "Non-default argument following default argument")
1899 elif not arg.is_self_arg:
1900 positional_args.append(arg)
1902 self.generate_tuple_and_keyword_parsing_code(
1903 positional_args, kw_only_args, end_label, code)
1905 code.error_label = old_error_label
1906 if code.label_used(our_error_label):
1907 if not code.label_used(end_label):
1908 code.put_goto(end_label)
1909 code.put_label(our_error_label)
1910 if has_star_or_kw_args:
1911 self.generate_arg_decref(self.star_arg, code)
1912 if self.starstar_arg:
1913 if self.starstar_arg.entry.xdecref_cleanup:
1914 code.put_var_xdecref(self.starstar_arg.entry)
1916 code.put_var_decref(self.starstar_arg.entry)
1917 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1918 code.putln("return %s;" % self.error_value())
1919 if code.label_used(end_label):
1920 code.put_label(end_label)
1922 def generate_arg_assignment(self, arg, item, code):
1923 if arg.type.is_pyobject:
1925 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1926 code.putln("%s = %s;" % (arg.entry.cname, item))
1928 func = arg.type.from_py_function
1930 code.putln("%s = %s(%s); %s" % (
1934 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1936 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1938 def generate_arg_xdecref(self, arg, code):
1940 code.put_var_xdecref(arg.entry)
1942 def generate_arg_decref(self, arg, code):
1944 code.put_var_decref(arg.entry)
1946 def generate_stararg_copy_code(self, code):
1947 if not self.star_arg:
1948 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1949 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1951 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1952 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1955 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1957 if self.starstar_arg:
1959 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1961 kwarg_check = "%s" % Naming.kwds_cname
1963 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1964 Naming.kwds_cname, Naming.kwds_cname)
1966 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1967 kwarg_check, Naming.kwds_cname, self.name,
1968 bool(self.starstar_arg), self.error_value()))
1970 if self.starstar_arg:
1971 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1972 self.starstar_arg.entry.cname,
1975 code.putln("if (unlikely(!%s)) return %s;" % (
1976 self.starstar_arg.entry.cname, self.error_value()))
1977 self.starstar_arg.entry.xdecref_cleanup = 0
1978 code.put_gotref(self.starstar_arg.entry.cname)
1982 code.put_incref(Naming.args_cname, py_object_type)
1983 code.putln("%s = %s;" % (
1984 self.star_arg.entry.cname,
1986 self.star_arg.entry.xdecref_cleanup = 0
1988 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1989 kw_only_args, success_label, code):
1990 argtuple_error_label = code.new_label("argtuple_error")
1992 min_positional_args = self.num_required_args - self.num_required_kw_args
1993 if len(self.args) > 0 and self.args[0].is_self_arg:
1994 min_positional_args -= 1
1995 max_positional_args = len(positional_args)
1996 has_fixed_positional_count = not self.star_arg and \
1997 min_positional_args == max_positional_args
1999 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2000 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2001 if self.num_required_kw_args:
2002 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2004 if self.starstar_arg or self.star_arg:
2005 self.generate_stararg_init_code(max_positional_args, code)
2007 # --- optimised code when we receive keyword arguments
2008 if self.num_required_kw_args:
2009 likely_hint = "likely"
2011 likely_hint = "unlikely"
2012 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2013 self.generate_keyword_unpacking_code(
2014 min_positional_args, max_positional_args,
2015 has_fixed_positional_count,
2016 positional_args, kw_only_args, argtuple_error_label, code)
2018 # --- optimised code when we do not receive any keyword arguments
2019 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2020 # Python raises arg tuple related errors first, so we must
2021 # check the length here
2022 if min_positional_args == max_positional_args and not self.star_arg:
2026 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2027 Naming.args_cname, compare, min_positional_args))
2028 code.put_goto(argtuple_error_label)
2030 if self.num_required_kw_args:
2031 # pure error case: keywords required but not passed
2032 if max_positional_args > min_positional_args and not self.star_arg:
2033 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2034 Naming.args_cname, max_positional_args))
2035 code.put_goto(argtuple_error_label)
2036 code.putln('} else {')
2037 for i, arg in enumerate(kw_only_args):
2039 pystring_cname = code.intern_identifier(arg.name)
2040 # required keyword-only argument missing
2041 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2042 self.name.utf8encode(),
2044 code.putln(code.error_goto(self.pos))
2047 elif min_positional_args == max_positional_args:
2048 # parse the exact number of positional arguments from the
2050 code.putln('} else {')
2051 for i, arg in enumerate(positional_args):
2052 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2053 self.generate_arg_assignment(arg, item, code)
2054 self.generate_arg_default_assignments(code)
2057 # parse the positional arguments from the variable length
2059 code.putln('} else {')
2060 self.generate_arg_default_assignments(code)
2061 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2063 code.putln('default:')
2064 reversed_args = list(enumerate(positional_args))[::-1]
2065 for i, arg in reversed_args:
2066 if i >= min_positional_args-1:
2067 if min_positional_args > 1:
2068 code.putln('case %2d:' % (i+1)) # pure code beautification
2070 code.put('case %2d: ' % (i+1))
2071 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2072 self.generate_arg_assignment(arg, item, code)
2073 if min_positional_args == 0:
2074 code.put('case 0: ')
2075 code.putln('break;')
2077 if min_positional_args:
2078 for i in range(min_positional_args-1, -1, -1):
2079 code.putln('case %2d:' % i)
2080 code.put_goto(argtuple_error_label)
2082 code.put('default: ')
2083 code.put_goto(argtuple_error_label)
2088 if code.label_used(argtuple_error_label):
2089 code.put_goto(success_label)
2090 code.put_label(argtuple_error_label)
2091 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2092 self.name.utf8encode(), has_fixed_positional_count,
2093 min_positional_args, max_positional_args,
2095 code.putln(code.error_goto(self.pos))
2097 def generate_arg_default_assignments(self, code):
2098 for arg in self.args:
2099 if arg.is_generic and arg.default:
2103 arg.calculate_default_value_code(code)))
2105 def generate_stararg_init_code(self, max_positional_args, code):
2106 if self.starstar_arg:
2107 self.starstar_arg.entry.xdecref_cleanup = 0
2108 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2109 self.starstar_arg.entry.cname,
2110 self.starstar_arg.entry.cname,
2111 self.error_value()))
2112 code.put_gotref(self.starstar_arg.entry.cname)
2114 self.star_arg.entry.xdecref_cleanup = 0
2115 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2117 max_positional_args))
2118 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2119 self.star_arg.entry.cname, Naming.args_cname,
2120 max_positional_args, Naming.args_cname))
2121 code.put_gotref(self.star_arg.entry.cname)
2122 if self.starstar_arg:
2124 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2125 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2126 code.putln('return %s;' % self.error_value())
2129 code.putln("if (unlikely(!%s)) return %s;" % (
2130 self.star_arg.entry.cname, self.error_value()))
2131 code.putln('} else {')
2132 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2133 code.put_incref(Naming.empty_tuple, py_object_type)
2136 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2137 has_fixed_positional_count, positional_args,
2138 kw_only_args, argtuple_error_label, code):
2139 all_args = tuple(positional_args) + tuple(kw_only_args)
2140 max_args = len(all_args)
2143 for i, arg in enumerate(all_args):
2144 if arg.default and arg.type.is_pyobject:
2145 default_value = arg.calculate_default_value_code(code)
2146 if arg.type is not PyrexTypes.py_object_type:
2147 default_value = "(PyObject*)"+default_value
2148 default_args.append((i, default_value))
2150 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2152 # it looks funny to separate the init-to-0 from setting the
2153 # default value, but C89 needs this
2154 code.putln("PyObject* values[%d] = {%s};" % (
2155 max_args, ','.join(['0']*max_args)))
2156 for i, default_value in default_args:
2157 code.putln('values[%d] = %s;' % (i, default_value))
2159 # parse the tuple and check that it's not too long
2160 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2162 code.putln('default:')
2163 for i in range(max_positional_args-1, -1, -1):
2164 code.put('case %2d: ' % (i+1))
2165 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2166 i, Naming.args_cname, i))
2167 code.putln('case 0: break;')
2168 if not self.star_arg:
2169 code.put('default: ') # more arguments than allowed
2170 code.put_goto(argtuple_error_label)
2173 # now fill up the positional/required arguments with values
2175 if self.num_required_args or max_positional_args > 0:
2176 last_required_arg = -1
2177 for i, arg in enumerate(all_args):
2179 last_required_arg = i
2180 if last_required_arg < max_positional_args:
2181 last_required_arg = max_positional_args-1
2182 num_required_args = self.num_required_args
2183 if max_positional_args > 0:
2184 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2185 for i, arg in enumerate(all_args[:last_required_arg+1]):
2186 if max_positional_args > 0 and i <= max_positional_args:
2187 if self.star_arg and i == max_positional_args:
2188 code.putln('default:')
2190 code.putln('case %2d:' % i)
2191 pystring_cname = code.intern_identifier(arg.name)
2194 # handled separately below
2196 code.putln('if (kw_args > %d) {' % num_required_args)
2197 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2198 Naming.kwds_cname, pystring_cname))
2199 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2202 num_required_args -= 1
2203 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2204 i, Naming.kwds_cname, pystring_cname))
2205 code.putln('if (likely(values[%d])) kw_args--;' % i);
2206 if i < min_positional_args:
2208 # special case: we know arg 0 is missing
2210 code.put_goto(argtuple_error_label)
2212 # print the correct number of values (args or
2213 # kwargs) that were passed into positional
2214 # arguments up to this point
2215 code.putln('else {')
2216 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2217 self.name.utf8encode(), has_fixed_positional_count,
2218 min_positional_args, max_positional_args, i))
2219 code.putln(code.error_goto(self.pos))
2222 code.putln('else {')
2223 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2224 self.name.utf8encode(), pystring_cname))
2225 code.putln(code.error_goto(self.pos))
2227 if max_positional_args > 0:
2230 if kw_only_args and not self.starstar_arg:
2231 # unpack optional keyword-only arguments
2232 # checking for interned strings in a dict is faster than iterating
2233 # but it's too likely that we must iterate if we expect **kwargs
2235 for i, arg in enumerate(all_args[max_positional_args:]):
2236 if not arg.kw_only or not arg.default:
2238 optional_args.append((i+max_positional_args, arg))
2240 # this mimics an unrolled loop so that we can "break" out of it
2241 code.putln('while (kw_args > 0) {')
2242 code.putln('PyObject* value;')
2243 for i, arg in optional_args:
2244 pystring_cname = code.intern_identifier(arg.name)
2246 'value = PyDict_GetItem(%s, %s);' % (
2247 Naming.kwds_cname, pystring_cname))
2249 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2250 code.putln('break;')
2253 code.putln('if (unlikely(kw_args > 0)) {')
2254 # non-positional/-required kw args left in dict: default args,
2255 # kw-only args, **kwargs or error
2257 # This is sort of a catch-all: except for checking required
2258 # arguments, this will always do the right thing for unpacking
2259 # keyword arguments, so that we can concentrate on optimising
2260 # common cases above.
2261 if max_positional_args == 0:
2264 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2265 Naming.args_cname, max_positional_args,
2266 Naming.args_cname, max_positional_args))
2267 pos_arg_count = "used_pos_args"
2269 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2270 code.globalstate.use_utility_code(parse_keywords_utility_code)
2272 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2274 Naming.pykwdlist_cname,
2275 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2277 self.name.utf8encode()))
2278 code.putln(code.error_goto(self.pos))
2281 # convert arg values to their final type and assign them
2282 for i, arg in enumerate(all_args):
2283 if arg.default and not arg.type.is_pyobject:
2284 code.putln("if (values[%d]) {" % i)
2285 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2286 if arg.default and not arg.type.is_pyobject:
2287 code.putln('} else {')
2291 arg.calculate_default_value_code(code)))
2294 def generate_argument_conversion_code(self, code):
2295 # Generate code to convert arguments from
2296 # signature type to declared type, if needed.
2297 for arg in self.args:
2298 if arg.needs_conversion:
2299 self.generate_arg_conversion(arg, code)
2301 def generate_arg_conversion(self, arg, code):
2302 # Generate conversion code for one argument.
2303 old_type = arg.hdr_type
2305 if old_type.is_pyobject:
2307 code.putln("if (%s) {" % arg.hdr_cname)
2309 code.putln("assert(%s); {" % arg.hdr_cname)
2310 self.generate_arg_conversion_from_pyobject(arg, code)
2312 elif new_type.is_pyobject:
2313 self.generate_arg_conversion_to_pyobject(arg, code)
2315 if new_type.assignable_from(old_type):
2317 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2320 "Cannot convert 1 argument from '%s' to '%s'" %
2321 (old_type, new_type))
2323 def generate_arg_conversion_from_pyobject(self, arg, code):
2325 func = new_type.from_py_function
2326 # copied from CoerceFromPyTypeNode
2328 code.putln("%s = %s(%s); %s" % (
2332 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2335 "Cannot convert Python object argument to type '%s'"
2338 def generate_arg_conversion_to_pyobject(self, arg, code):
2339 old_type = arg.hdr_type
2340 func = old_type.to_py_function
2342 code.putln("%s = %s(%s); %s" % (
2346 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2347 code.put_var_gotref(arg.entry)
2350 "Cannot convert argument of type '%s' to Python object"
2353 def generate_argument_type_tests(self, code):
2354 # Generate type tests for args whose signature
2355 # type is PyObject * and whose declared type is
2356 # a subtype thereof.
2357 for arg in self.args:
2358 if arg.needs_type_test:
2359 self.generate_arg_type_test(arg, code)
2361 def generate_arg_type_test(self, arg, code):
2362 # Generate type test for one argument.
2363 if arg.type.typeobj_is_available():
2364 typeptr_cname = arg.type.typeptr_cname
2365 arg_code = "((PyObject *)%s)" % arg.entry.cname
2367 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2372 arg.type.is_builtin_type,
2373 code.error_goto(arg.pos)))
2375 error(arg.pos, "Cannot test type of extern C class "
2376 "without type object name specification")
2378 def error_value(self):
2379 return self.entry.signature.error_value
2381 def caller_will_check_exceptions(self):
2384 class OverrideCheckNode(StatNode):
2385 # A Node for dispatching to the def method if it
2394 child_attrs = ['body']
2398 def analyse_expressions(self, env):
2399 self.args = env.arg_entries
2400 if self.py_func.is_module_scope:
2405 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2406 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2407 call_node = ExprNodes.SimpleCallNode(self.pos,
2408 function=self.func_node,
2409 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2410 self.body = ReturnStatNode(self.pos, value=call_node)
2411 self.body.analyse_expressions(env)
2413 def generate_execution_code(self, code):
2414 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2415 # Check to see if we are an extension type
2416 if self.py_func.is_module_scope:
2417 self_arg = "((PyObject *)%s)" % Naming.module_cname
2419 self_arg = "((PyObject *)%s)" % self.args[0].cname
2420 code.putln("/* Check if called by wrapper */")
2421 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2422 code.putln("/* Check if overriden in Python */")
2423 if self.py_func.is_module_scope:
2424 code.putln("else {")
2426 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2427 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2428 # need to get attribute manually--scope would return cdef method
2429 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2430 self.func_node.result(), self_arg, interned_attr_cname, err))
2431 code.put_gotref(self.func_node.py_result())
2432 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2433 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2434 self.func_node.result(), self.py_func.entry.func_cname)
2435 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2436 self.body.generate_execution_code(code)
2438 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2441 class ClassDefNode(StatNode, BlockNode):
2444 class PyClassDefNode(ClassDefNode):
2445 # A Python class definition.
2447 # name EncodedString Name of the class
2448 # doc string or None
2449 # body StatNode Attribute definition code
2450 # entry Symtab.Entry
2451 # scope PyClassScope
2453 # The following subnodes are constructed internally:
2455 # dict DictNode Class dictionary
2456 # classobj ClassNode Class object
2457 # target NameNode Variable to assign class object to
2459 child_attrs = ["body", "dict", "classobj", "target"]
2461 def __init__(self, pos, name, bases, doc, body):
2462 StatNode.__init__(self, pos)
2467 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2468 if self.doc and Options.docstrings:
2469 doc = embed_position(self.pos, self.doc)
2470 doc_node = ExprNodes.StringNode(pos, value = doc)
2473 self.classobj = ExprNodes.ClassNode(pos, name = name,
2474 bases = bases, dict = self.dict, doc = doc_node)
2475 self.target = ExprNodes.NameNode(pos, name = name)
2477 def as_cclass(self):
2479 Return this node as if it were declared as an extension class
2481 bases = self.classobj.bases.args
2483 base_class_name = None
2484 base_class_module = None
2485 elif len(bases) == 1:
2488 from ExprNodes import AttributeNode, NameNode
2489 while isinstance(base, AttributeNode):
2490 path.insert(0, base.attribute)
2492 if isinstance(base, NameNode):
2493 path.insert(0, base.name)
2494 base_class_name = path[-1]
2496 base_class_module = u'.'.join(path[:-1])
2498 base_class_module = None
2500 error(self.classobj.bases.args.pos, "Invalid base class")
2502 error(self.classobj.bases.args.pos, "C class may only have one base class")
2505 return CClassDefNode(self.pos,
2506 visibility = 'private',
2508 class_name = self.name,
2509 base_class_module = base_class_module,
2510 base_class_name = base_class_name,
2515 def create_scope(self, env):
2517 while env.is_py_class_scope or env.is_c_class_scope:
2518 env = env.outer_scope
2519 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2522 def analyse_declarations(self, env):
2523 self.target.analyse_target_declaration(env)
2524 cenv = self.create_scope(env)
2525 cenv.class_obj_cname = self.target.entry.cname
2526 self.body.analyse_declarations(cenv)
2528 def analyse_expressions(self, env):
2529 self.dict.analyse_expressions(env)
2530 self.classobj.analyse_expressions(env)
2531 genv = env.global_scope()
2533 cenv.class_dict_cname = self.dict.result()
2534 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2535 self.body.analyse_expressions(cenv)
2536 self.target.analyse_target_expression(env, self.classobj)
2537 self.dict.release_temp(env)
2538 #self.classobj.release_temp(env)
2539 #self.target.release_target_temp(env)
2541 def generate_function_definitions(self, env, code):
2542 self.body.generate_function_definitions(self.scope, code)
2544 def generate_execution_code(self, code):
2545 self.dict.generate_evaluation_code(code)
2546 self.classobj.generate_evaluation_code(code)
2547 self.body.generate_execution_code(code)
2548 self.target.generate_assignment_code(self.classobj, code)
2549 self.dict.generate_disposal_code(code)
2550 self.dict.free_temps(code)
2553 class CClassDefNode(ClassDefNode):
2554 # An extension type definition.
2556 # visibility 'private' or 'public' or 'extern'
2557 # typedef_flag boolean
2559 # module_name string or None For import of extern type objects
2560 # class_name string Unqualified name of class
2561 # as_name string or None Name to declare as in this scope
2562 # base_class_module string or None Module containing the base class
2563 # base_class_name string or None Name of the base class
2564 # objstruct_name string or None Specified C name of object struct
2565 # typeobj_name string or None Specified C name of type object
2566 # in_pxd boolean Is in a .pxd file
2567 # doc string or None
2568 # body StatNode or None
2569 # entry Symtab.Entry
2570 # base_type PyExtensionType or None
2571 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2572 # buffer_defaults_pos
2574 child_attrs = ["body"]
2575 buffer_defaults_node = None
2576 buffer_defaults_pos = None
2577 typedef_flag = False
2579 objstruct_name = None
2582 def analyse_declarations(self, env):
2583 #print "CClassDefNode.analyse_declarations:", self.class_name
2584 #print "...visibility =", self.visibility
2585 #print "...module_name =", self.module_name
2588 if self.buffer_defaults_node:
2589 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2590 env, [], self.buffer_defaults_node,
2591 need_complete=False)
2593 buffer_defaults = None
2595 if env.in_cinclude and not self.objstruct_name:
2596 error(self.pos, "Object struct name specification required for "
2597 "C class defined in 'extern from' block")
2598 self.base_type = None
2599 # Now that module imports are cached, we need to
2600 # import the modules for extern classes.
2601 if self.module_name:
2603 for module in env.cimported_modules:
2604 if module.name == self.module_name:
2605 self.module = module
2606 if self.module is None:
2607 self.module = ModuleScope(self.module_name, None, env.context)
2608 self.module.has_extern_class = 1
2609 env.add_imported_module(self.module)
2611 if self.base_class_name:
2612 if self.base_class_module:
2613 base_class_scope = env.find_module(self.base_class_module, self.pos)
2615 base_class_scope = env
2616 if self.base_class_name == 'object':
2617 # extension classes are special and don't need to inherit from object
2618 if base_class_scope is None or base_class_scope.lookup('object') is None:
2619 self.base_class_name = None
2620 self.base_class_module = None
2621 base_class_scope = None
2622 if base_class_scope:
2623 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2624 if base_class_entry:
2625 if not base_class_entry.is_type:
2626 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2627 elif not base_class_entry.type.is_extension_type:
2628 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2629 elif not base_class_entry.type.is_complete():
2630 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2632 self.base_type = base_class_entry.type
2633 has_body = self.body is not None
2634 if self.module_name and self.visibility != 'extern':
2635 module_path = self.module_name.split(".")
2636 home_scope = env.find_imported_module(module_path, self.pos)
2642 if self.visibility == 'extern':
2643 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2644 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2646 self.entry = home_scope.declare_c_class(
2647 name = self.class_name,
2649 defining = has_body and self.in_pxd,
2650 implementing = has_body and not self.in_pxd,
2651 module_name = self.module_name,
2652 base_type = self.base_type,
2653 objstruct_cname = self.objstruct_name,
2654 typeobj_cname = self.typeobj_name,
2655 visibility = self.visibility,
2656 typedef_flag = self.typedef_flag,
2658 buffer_defaults = buffer_defaults)
2659 if home_scope is not env and self.visibility == 'extern':
2660 env.add_imported_entry(self.class_name, self.entry, pos)
2661 scope = self.entry.type.scope
2663 if self.doc and Options.docstrings:
2664 scope.doc = embed_position(self.pos, self.doc)
2667 self.body.analyse_declarations(scope)
2671 scope.implemented = 1
2672 env.allocate_vtable_names(self.entry)
2674 def analyse_expressions(self, env):
2676 scope = self.entry.type.scope
2677 self.body.analyse_expressions(scope)
2679 def generate_function_definitions(self, env, code):
2681 self.body.generate_function_definitions(
2682 self.entry.type.scope, code)
2684 def generate_execution_code(self, code):
2685 # This is needed to generate evaluation code for
2686 # default values of method arguments.
2688 self.body.generate_execution_code(code)
2690 def annotate(self, code):
2692 self.body.annotate(code)
2695 class PropertyNode(StatNode):
2696 # Definition of a property in an extension type.
2699 # doc EncodedString or None Doc string
2702 child_attrs = ["body"]
2704 def analyse_declarations(self, env):
2705 entry = env.declare_property(self.name, self.doc, self.pos)
2707 self.body.analyse_declarations(entry.scope)
2709 def analyse_expressions(self, env):
2710 self.body.analyse_expressions(env)
2712 def generate_function_definitions(self, env, code):
2713 self.body.generate_function_definitions(env, code)
2715 def generate_execution_code(self, code):
2718 def annotate(self, code):
2719 self.body.annotate(code)
2722 class GlobalNode(StatNode):
2723 # Global variable declaration.
2729 def analyse_declarations(self, env):
2730 for name in self.names:
2731 env.declare_global(name, self.pos)
2733 def analyse_expressions(self, env):
2736 def generate_execution_code(self, code):
2740 class ExprStatNode(StatNode):
2741 # Expression used as a statement.
2745 child_attrs = ["expr"]
2747 def analyse_declarations(self, env):
2749 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2750 func = self.expr.function.as_cython_attribute()
2751 if func == u'declare':
2752 args, kwds = self.expr.explicit_args_kwds()
2754 error(self.expr.pos, "Variable names must be specified.")
2755 for var, type_node in kwds.key_value_pairs:
2756 type = type_node.analyse_as_type(env)
2758 error(type_node.pos, "Unknown type")
2760 env.declare_var(var.value, type, var.pos, is_cdef = True)
2761 self.__class__ = PassStatNode
2763 def analyse_expressions(self, env):
2764 self.expr.analyse_expressions(env)
2765 self.expr.release_temp(env)
2767 def generate_execution_code(self, code):
2768 self.expr.generate_evaluation_code(code)
2769 if not self.expr.is_temp and self.expr.result():
2770 code.putln("%s;" % self.expr.result())
2771 self.expr.generate_disposal_code(code)
2772 self.expr.free_temps(code)
2774 def annotate(self, code):
2775 self.expr.annotate(code)
2778 class AssignmentNode(StatNode):
2779 # Abstract base class for assignment nodes.
2781 # The analyse_expressions and generate_execution_code
2782 # phases of assignments are split into two sub-phases
2783 # each, to enable all the right hand sides of a
2784 # parallel assignment to be evaluated before assigning
2785 # to any of the left hand sides.
2787 def analyse_expressions(self, env):
2788 self.analyse_types(env)
2789 self.allocate_rhs_temps(env)
2790 self.allocate_lhs_temps(env)
2792 # def analyse_expressions(self, env):
2793 # self.analyse_expressions_1(env)
2794 # self.analyse_expressions_2(env)
2796 def generate_execution_code(self, code):
2797 self.generate_rhs_evaluation_code(code)
2798 self.generate_assignment_code(code)
2801 class SingleAssignmentNode(AssignmentNode):
2802 # The simplest case:
2806 # lhs ExprNode Left hand side
2807 # rhs ExprNode Right hand side
2808 # first bool Is this guaranteed the first assignment to lhs?
2810 child_attrs = ["lhs", "rhs"]
2812 declaration_only = False
2814 def analyse_declarations(self, env):
2817 # handle declarations of the form x = cython.foo()
2818 if isinstance(self.rhs, ExprNodes.CallNode):
2819 func_name = self.rhs.function.as_cython_attribute()
2821 args, kwds = self.rhs.explicit_args_kwds()
2823 if func_name in ['declare', 'typedef']:
2824 if len(args) > 2 or kwds is not None:
2825 error(rhs.pos, "Can only declare one type at a time.")
2827 type = args[0].analyse_as_type(env)
2829 error(args[0].pos, "Unknown type")
2832 if func_name == 'declare':
2833 if isinstance(lhs, ExprNodes.NameNode):
2834 vars = [(lhs.name, lhs.pos)]
2835 elif isinstance(lhs, ExprNodes.TupleNode):
2836 vars = [(var.name, var.pos) for var in lhs.args]
2838 error(lhs.pos, "Invalid declaration")
2840 for var, pos in vars:
2841 env.declare_var(var, type, pos, is_cdef = True)
2846 self.declaration_only = True
2848 self.declaration_only = True
2849 if not isinstance(lhs, ExprNodes.NameNode):
2850 error(lhs.pos, "Invalid declaration.")
2851 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2853 elif func_name in ['struct', 'union']:
2854 self.declaration_only = True
2855 if len(args) > 0 or kwds is None:
2856 error(rhs.pos, "Struct or union members must be given by name.")
2859 for member, type_node in kwds.key_value_pairs:
2860 type = type_node.analyse_as_type(env)
2862 error(type_node.pos, "Unknown type")
2864 members.append((member.value, type, member.pos))
2865 if len(members) < len(kwds.key_value_pairs):
2867 if not isinstance(self.lhs, ExprNodes.NameNode):
2868 error(self.lhs.pos, "Invalid declaration.")
2869 name = self.lhs.name
2870 scope = StructOrUnionScope(name)
2871 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2872 for member, type, pos in members:
2873 scope.declare_var(member, type, pos)
2875 if self.declaration_only:
2878 self.lhs.analyse_target_declaration(env)
2880 def analyse_types(self, env, use_temp = 0):
2881 self.rhs.analyse_types(env)
2882 self.lhs.analyse_target_types(env)
2883 self.lhs.gil_assignment_check(env)
2884 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2886 self.rhs = self.rhs.coerce_to_temp(env)
2888 def allocate_rhs_temps(self, env):
2889 self.rhs.allocate_temps(env)
2891 def allocate_lhs_temps(self, env):
2892 self.lhs.allocate_target_temps(env, self.rhs)
2893 #self.lhs.release_target_temp(env)
2894 #self.rhs.release_temp(env)
2896 def generate_rhs_evaluation_code(self, code):
2897 self.rhs.generate_evaluation_code(code)
2899 def generate_assignment_code(self, code):
2900 self.lhs.generate_assignment_code(self.rhs, code)
2902 def annotate(self, code):
2903 self.lhs.annotate(code)
2904 self.rhs.annotate(code)
2907 class CascadedAssignmentNode(AssignmentNode):
2908 # An assignment with multiple left hand sides:
2912 # lhs_list [ExprNode] Left hand sides
2913 # rhs ExprNode Right hand sides
2917 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2919 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2920 coerced_rhs_list = None
2922 def analyse_declarations(self, env):
2923 for lhs in self.lhs_list:
2924 lhs.analyse_target_declaration(env)
2926 def analyse_types(self, env, use_temp = 0):
2927 self.rhs.analyse_types(env)
2929 self.rhs = self.rhs.coerce_to_temp(env)
2931 self.rhs = self.rhs.coerce_to_simple(env)
2932 from ExprNodes import CloneNode
2933 self.coerced_rhs_list = []
2934 for lhs in self.lhs_list:
2935 lhs.analyse_target_types(env)
2936 lhs.gil_assignment_check(env)
2937 rhs = CloneNode(self.rhs)
2938 rhs = rhs.coerce_to(lhs.type, env)
2939 self.coerced_rhs_list.append(rhs)
2941 def allocate_rhs_temps(self, env):
2942 self.rhs.allocate_temps(env)
2944 def allocate_lhs_temps(self, env):
2945 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2946 rhs.allocate_temps(env)
2947 lhs.allocate_target_temps(env, rhs)
2948 #lhs.release_target_temp(env)
2949 #rhs.release_temp(env)
2950 self.rhs.release_temp(env)
2952 def generate_rhs_evaluation_code(self, code):
2953 self.rhs.generate_evaluation_code(code)
2955 def generate_assignment_code(self, code):
2956 for i in range(len(self.lhs_list)):
2957 lhs = self.lhs_list[i]
2958 rhs = self.coerced_rhs_list[i]
2959 rhs.generate_evaluation_code(code)
2960 lhs.generate_assignment_code(rhs, code)
2961 # Assignment has disposed of the cloned RHS
2962 self.rhs.generate_disposal_code(code)
2963 self.rhs.free_temps(code)
2965 def annotate(self, code):
2966 for i in range(len(self.lhs_list)):
2967 lhs = self.lhs_list[i].annotate(code)
2968 rhs = self.coerced_rhs_list[i].annotate(code)
2969 self.rhs.annotate(code)
2972 class ParallelAssignmentNode(AssignmentNode):
2973 # A combined packing/unpacking assignment:
2977 # This has been rearranged by the parser into
2979 # a = d ; b = e ; c = f
2981 # but we must evaluate all the right hand sides
2982 # before assigning to any of the left hand sides.
2984 # stats [AssignmentNode] The constituent assignments
2986 child_attrs = ["stats"]
2988 def analyse_declarations(self, env):
2989 for stat in self.stats:
2990 stat.analyse_declarations(env)
2992 def analyse_expressions(self, env):
2993 for stat in self.stats:
2994 stat.analyse_types(env, use_temp = 1)
2995 stat.allocate_rhs_temps(env)
2996 for stat in self.stats:
2997 stat.allocate_lhs_temps(env)
2999 # def analyse_expressions(self, env):
3000 # for stat in self.stats:
3001 # stat.analyse_expressions_1(env, use_temp = 1)
3002 # for stat in self.stats:
3003 # stat.analyse_expressions_2(env)
3005 def generate_execution_code(self, code):
3006 for stat in self.stats:
3007 stat.generate_rhs_evaluation_code(code)
3008 for stat in self.stats:
3009 stat.generate_assignment_code(code)
3011 def annotate(self, code):
3012 for stat in self.stats:
3016 class InPlaceAssignmentNode(AssignmentNode):
3017 # An in place arithmatic operand:
3023 # lhs ExprNode Left hand side
3024 # rhs ExprNode Right hand side
3025 # op char one of "+-*/%^&|"
3026 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3028 # This code is a bit tricky because in order to obey Python
3029 # semantics the sub-expressions (e.g. indices) of the lhs must
3030 # not be evaluated twice. So we must re-use the values calculated
3031 # in evaluation phase for the assignment phase as well.
3032 # Fortunately, the type of the lhs node is fairly constrained
3033 # (it must be a NameNode, AttributeNode, or IndexNode).
3035 child_attrs = ["lhs", "rhs"]
3038 def analyse_declarations(self, env):
3039 self.lhs.analyse_target_declaration(env)
3041 def analyse_types(self, env):
3042 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3043 self.rhs.analyse_types(env)
3044 self.lhs.analyse_target_types(env)
3045 if Options.incref_local_binop and self.dup.type.is_pyobject:
3046 self.dup = self.dup.coerce_to_temp(env)
3048 def allocate_rhs_temps(self, env):
3050 if self.lhs.type.is_pyobject:
3051 self.rhs = self.rhs.coerce_to_pyobject(env)
3052 elif self.rhs.type.is_pyobject:
3053 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3054 if self.lhs.type.is_pyobject:
3055 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3056 self.result_value.allocate_temps(env)
3058 # self.rhs = self.rhs.coerce_to_temp(env)
3059 self.rhs.allocate_temps(env)
3060 self.dup.allocate_subexpr_temps(env)
3061 self.dup.allocate_temp(env)
3063 def allocate_lhs_temps(self, env):
3064 self.lhs.allocate_target_temps(env, self.rhs)
3065 # self.lhs.release_target_temp(env)
3066 self.dup.release_temp(env)
3067 if self.dup.is_temp:
3068 self.dup.release_subexpr_temps(env)
3069 # self.rhs.release_temp(env)
3070 if self.lhs.type.is_pyobject:
3071 self.result_value.release_temp(env)
3073 def generate_execution_code(self, code):
3075 self.rhs.generate_evaluation_code(code)
3076 self.dup.generate_subexpr_evaluation_code(code)
3077 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3078 # This is because we're manually messing with subexpr nodes
3079 if self.dup.is_temp:
3080 self.dup.allocate_temp_result(code)
3081 # self.dup.generate_result_code is run only if it is not buffer access
3082 if self.operator == "**":
3086 if self.lhs.type.is_pyobject:
3087 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3088 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3089 self.dup.generate_result_code(code)
3091 "%s = %s(%s, %s%s); %s" % (
3092 self.result_value.result(),
3093 self.py_operation_function(),
3094 self.dup.py_result(),
3095 self.rhs.py_result(),
3097 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3098 code.put_gotref(self.result_value.py_result())
3099 self.result_value.generate_evaluation_code(code) # May be a type check...
3100 self.rhs.generate_disposal_code(code)
3101 self.rhs.free_temps(code)
3102 self.dup.generate_disposal_code(code)
3103 self.dup.free_temps(code)
3104 self.lhs.generate_assignment_code(self.result_value, code)
3106 c_op = self.operator
3110 if self.lhs.type.is_int and self.rhs.type.is_int:
3111 error(self.pos, "** with two C int types is ambiguous")
3113 error(self.pos, "No C inplace power operator")
3114 # have to do assignment directly to avoid side-effects
3115 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3116 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3118 self.dup.generate_result_code(code)
3119 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3120 self.rhs.generate_disposal_code(code)
3121 self.rhs.free_temps(code)
3122 if self.dup.is_temp:
3123 self.dup.generate_subexpr_disposal_code(code)
3124 self.dup.free_subexpr_temps(code)
3126 def create_dup_node(self, env):
3129 self.dup.analyse_types(env)
3130 if isinstance(self.lhs, ExprNodes.NameNode):
3131 target_lhs = ExprNodes.NameNode(self.dup.pos,
3132 name = self.dup.name,
3133 is_temp = self.dup.is_temp,
3134 entry = self.dup.entry)
3135 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3136 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3137 obj = ExprNodes.CloneNode(self.lhs.obj),
3138 attribute = self.dup.attribute,
3139 is_temp = self.dup.is_temp)
3140 elif isinstance(self.lhs, ExprNodes.IndexNode):
3142 index = ExprNodes.CloneNode(self.lhs.index)
3145 if self.lhs.indices:
3146 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3149 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3150 base = ExprNodes.CloneNode(self.dup.base),
3153 is_temp = self.dup.is_temp)
3156 self.lhs = target_lhs
3159 def py_operation_function(self):
3160 return self.py_functions[self.operator]
3163 "|": "PyNumber_InPlaceOr",
3164 "^": "PyNumber_InPlaceXor",
3165 "&": "PyNumber_InPlaceAnd",
3166 "+": "PyNumber_InPlaceAdd",
3167 "-": "PyNumber_InPlaceSubtract",
3168 "*": "PyNumber_InPlaceMultiply",
3169 "/": "PyNumber_InPlaceDivide",
3170 "%": "PyNumber_InPlaceRemainder",
3171 "<<": "PyNumber_InPlaceLshift",
3172 ">>": "PyNumber_InPlaceRshift",
3173 "**": "PyNumber_InPlacePower",
3174 "//": "PyNumber_InPlaceFloorDivide",
3177 def annotate(self, code):
3178 self.lhs.annotate(code)
3179 self.rhs.annotate(code)
3180 self.dup.annotate(code)
3183 class PrintStatNode(StatNode):
3186 # arg_tuple TupleNode
3187 # append_newline boolean
3189 child_attrs = ["arg_tuple"]
3191 def analyse_expressions(self, env):
3192 self.arg_tuple.analyse_expressions(env)
3193 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3194 self.arg_tuple.release_temp(env)
3195 env.use_utility_code(printing_utility_code)
3196 if len(self.arg_tuple.args) == 1 and self.append_newline:
3197 env.use_utility_code(printing_one_utility_code)
3199 gil_check = StatNode._gil_check
3200 gil_message = "Python print statement"
3202 def generate_execution_code(self, code):
3203 if len(self.arg_tuple.args) == 1 and self.append_newline:
3204 arg = self.arg_tuple.args[0]
3205 arg.generate_evaluation_code(code)
3208 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3210 code.error_goto(self.pos)))
3211 arg.generate_disposal_code(code)
3212 arg.free_temps(code)
3214 self.arg_tuple.generate_evaluation_code(code)
3216 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3217 self.arg_tuple.py_result(),
3218 self.append_newline,
3219 code.error_goto(self.pos)))
3220 self.arg_tuple.generate_disposal_code(code)
3221 self.arg_tuple.free_temps(code)
3223 def annotate(self, code):
3224 self.arg_tuple.annotate(code)
3227 class ExecStatNode(StatNode):
3232 child_attrs = ["args"]
3234 def analyse_expressions(self, env):
3235 for i, arg in enumerate(self.args):
3236 arg.analyse_expressions(env)
3237 arg = arg.coerce_to_pyobject(env)
3238 arg.release_temp(env)
3240 self.temp_result = env.allocate_temp_pyobject()
3241 env.release_temp(self.temp_result)
3242 env.use_utility_code(Builtin.pyexec_utility_code)
3244 gil_check = StatNode._gil_check
3245 gil_message = "Python exec statement"
3247 def generate_execution_code(self, code):
3249 for arg in self.args:
3250 arg.generate_evaluation_code(code)
3251 args.append( arg.py_result() )
3252 args = tuple(args + ['0', '0'][:3-len(args)])
3253 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3254 (self.temp_result,) + args))
3255 for arg in self.args:
3256 arg.generate_disposal_code(code)
3257 arg.free_temps(code)
3259 code.error_goto_if_null(self.temp_result, self.pos))
3260 code.put_gotref(self.temp_result)
3261 code.put_decref_clear(self.temp_result, py_object_type)
3263 def annotate(self, code):
3264 for arg in self.args:
3268 class DelStatNode(StatNode):
3273 child_attrs = ["args"]
3275 def analyse_declarations(self, env):
3276 for arg in self.args:
3277 arg.analyse_target_declaration(env)
3279 def analyse_expressions(self, env):
3280 for arg in self.args:
3281 arg.analyse_target_expression(env, None)
3282 if not arg.type.is_pyobject:
3283 error(arg.pos, "Deletion of non-Python object")
3284 #arg.release_target_temp(env)
3286 def gil_check(self, env):
3287 for arg in self.args:
3288 if arg.type.is_pyobject:
3289 self._gil_check(env)
3291 gil_message = "Deleting Python object"
3293 def generate_execution_code(self, code):
3294 for arg in self.args:
3295 if arg.type.is_pyobject:
3296 arg.generate_deletion_code(code)
3297 # else error reported earlier
3299 def annotate(self, code):
3300 for arg in self.args:
3304 class PassStatNode(StatNode):
3309 def analyse_expressions(self, env):
3312 def generate_execution_code(self, code):
3316 class BreakStatNode(StatNode):
3320 def analyse_expressions(self, env):
3323 def generate_execution_code(self, code):
3324 if not code.break_label:
3325 error(self.pos, "break statement not inside loop")
3327 code.put_goto(code.break_label)
3330 class ContinueStatNode(StatNode):
3334 def analyse_expressions(self, env):
3337 def generate_execution_code(self, code):
3338 if code.funcstate.in_try_finally:
3339 error(self.pos, "continue statement inside try of try...finally")
3340 elif not code.continue_label:
3341 error(self.pos, "continue statement not inside loop")
3343 code.put_goto(code.continue_label)
3346 class ReturnStatNode(StatNode):
3349 # value ExprNode or None
3350 # return_type PyrexType
3351 # temps_in_use [Entry] Temps in use at time of return
3353 child_attrs = ["value"]
3355 def analyse_expressions(self, env):
3356 return_type = env.return_type
3357 self.return_type = return_type
3358 self.temps_in_use = env.temps_in_use()
3360 error(self.pos, "Return not inside a function body")
3363 self.value.analyse_types(env)
3364 if return_type.is_void or return_type.is_returncode:
3365 error(self.value.pos,
3366 "Return with value in void function")
3368 self.value = self.value.coerce_to(env.return_type, env)
3369 self.value.allocate_temps(env)
3370 self.value.release_temp(env)
3372 if (not return_type.is_void
3373 and not return_type.is_pyobject
3374 and not return_type.is_returncode):
3375 error(self.pos, "Return value required")
3377 def gil_check(self, env):
3378 if self.return_type.is_pyobject:
3379 self._gil_check(env)
3381 gil_message = "Returning Python object"
3383 def generate_execution_code(self, code):
3384 code.mark_pos(self.pos)
3385 if not self.return_type:
3386 # error reported earlier
3388 if self.return_type.is_pyobject:
3389 code.put_xdecref(Naming.retval_cname,
3392 self.value.generate_evaluation_code(code)
3393 self.value.make_owned_reference(code)
3396 Naming.retval_cname,
3397 self.value.result_as(self.return_type)))
3398 self.value.generate_post_assignment_code(code)
3399 self.value.free_temps(code)
3401 if self.return_type.is_pyobject:
3402 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3403 elif self.return_type.is_returncode:
3406 Naming.retval_cname,
3407 self.return_type.default_value))
3408 # free temps the old way
3409 for entry in self.temps_in_use:
3410 code.put_var_decref_clear(entry)
3411 # free temps the new way
3412 for cname, type in code.funcstate.temps_holding_reference():
3413 code.put_decref_clear(cname, type)
3416 # code.return_label)
3417 code.put_goto(code.return_label)
3419 def annotate(self, code):
3421 self.value.annotate(code)
3424 class RaiseStatNode(StatNode):
3427 # exc_type ExprNode or None
3428 # exc_value ExprNode or None
3429 # exc_tb ExprNode or None
3431 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3433 def analyse_expressions(self, env):
3435 self.exc_type.analyse_types(env)
3436 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3437 self.exc_type.allocate_temps(env)
3439 self.exc_value.analyse_types(env)
3440 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3441 self.exc_value.allocate_temps(env)
3443 self.exc_tb.analyse_types(env)
3444 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3445 self.exc_tb.allocate_temps(env)
3447 self.exc_type.release_temp(env)
3449 self.exc_value.release_temp(env)
3451 self.exc_tb.release_temp(env)
3452 env.use_utility_code(raise_utility_code)
3453 env.use_utility_code(restore_exception_utility_code)
3455 gil_check = StatNode._gil_check
3456 gil_message = "Raising exception"
3458 def generate_execution_code(self, code):
3460 self.exc_type.generate_evaluation_code(code)
3461 type_code = self.exc_type.py_result()
3465 self.exc_value.generate_evaluation_code(code)
3466 value_code = self.exc_value.py_result()
3470 self.exc_tb.generate_evaluation_code(code)
3471 tb_code = self.exc_tb.py_result()
3474 if self.exc_type or self.exc_value or self.exc_tb:
3476 "__Pyx_Raise(%s, %s, %s);" % (
3483 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3485 obj.generate_disposal_code(code)
3486 obj.free_temps(code)
3488 code.error_goto(self.pos))
3490 def annotate(self, code):
3492 self.exc_type.annotate(code)
3494 self.exc_value.annotate(code)
3496 self.exc_tb.annotate(code)
3499 class ReraiseStatNode(StatNode):
3503 def analyse_expressions(self, env):
3504 env.use_utility_code(raise_utility_code)
3505 env.use_utility_code(restore_exception_utility_code)
3507 gil_check = StatNode._gil_check
3508 gil_message = "Raising exception"
3510 def generate_execution_code(self, code):
3511 vars = code.funcstate.exc_vars
3513 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3514 code.putln(code.error_goto(self.pos))
3516 error(self.pos, "Reraise not inside except clause")
3519 class AssertStatNode(StatNode):
3523 # value ExprNode or None
3525 child_attrs = ["cond", "value"]
3527 def analyse_expressions(self, env):
3528 self.cond = self.cond.analyse_boolean_expression(env)
3530 self.value.analyse_types(env)
3531 self.value = self.value.coerce_to_pyobject(env)
3532 self.value.allocate_temps(env)
3533 self.cond.release_temp(env)
3535 self.value.release_temp(env)
3536 #env.recycle_pending_temps() # TEMPORARY
3538 gil_check = StatNode._gil_check
3539 gil_message = "Raising exception"
3541 def generate_execution_code(self, code):
3542 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3543 self.cond.generate_evaluation_code(code)
3545 "if (unlikely(!%s)) {" %
3548 self.value.generate_evaluation_code(code)
3550 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3551 self.value.py_result())
3552 self.value.generate_disposal_code(code)
3553 self.value.free_temps(code)
3556 "PyErr_SetNone(PyExc_AssertionError);")
3558 code.error_goto(self.pos))
3561 self.cond.generate_disposal_code(code)
3562 self.cond.free_temps(code)
3563 code.putln("#endif")
3565 def annotate(self, code):
3566 self.cond.annotate(code)
3568 self.value.annotate(code)
3571 class IfStatNode(StatNode):
3574 # if_clauses [IfClauseNode]
3575 # else_clause StatNode or None
3577 child_attrs = ["if_clauses", "else_clause"]
3579 def analyse_control_flow(self, env):
3580 env.start_branching(self.pos)
3581 for if_clause in self.if_clauses:
3582 if_clause.analyse_control_flow(env)
3583 env.next_branch(if_clause.end_pos())
3584 if self.else_clause:
3585 self.else_clause.analyse_control_flow(env)
3586 env.finish_branching(self.end_pos())
3588 def analyse_declarations(self, env):
3589 for if_clause in self.if_clauses:
3590 if_clause.analyse_declarations(env)
3591 if self.else_clause:
3592 self.else_clause.analyse_declarations(env)
3594 def analyse_expressions(self, env):
3595 for if_clause in self.if_clauses:
3596 if_clause.analyse_expressions(env)
3597 if self.else_clause:
3598 self.else_clause.analyse_expressions(env)
3600 def generate_execution_code(self, code):
3601 code.mark_pos(self.pos)
3602 end_label = code.new_label()
3603 for if_clause in self.if_clauses:
3604 if_clause.generate_execution_code(code, end_label)
3605 if self.else_clause:
3606 code.putln("/*else*/ {")
3607 self.else_clause.generate_execution_code(code)
3609 code.put_label(end_label)
3611 def annotate(self, code):
3612 for if_clause in self.if_clauses:
3613 if_clause.annotate(code)
3614 if self.else_clause:
3615 self.else_clause.annotate(code)
3618 class IfClauseNode(Node):
3619 # if or elif clause in an if statement
3621 # condition ExprNode
3624 child_attrs = ["condition", "body"]
3626 def analyse_control_flow(self, env):
3627 self.body.analyse_control_flow(env)
3629 def analyse_declarations(self, env):
3630 self.condition.analyse_declarations(env)
3631 self.body.analyse_declarations(env)
3633 def analyse_expressions(self, env):
3635 self.condition.analyse_temp_boolean_expression(env)
3636 self.condition.release_temp(env)
3637 self.body.analyse_expressions(env)
3639 def generate_execution_code(self, code, end_label):
3640 self.condition.generate_evaluation_code(code)
3643 self.condition.result())
3644 self.condition.generate_disposal_code(code)
3645 self.condition.free_temps(code)
3646 self.body.generate_execution_code(code)
3650 code.put_goto(end_label)
3653 def annotate(self, code):
3654 self.condition.annotate(code)
3655 self.body.annotate(code)
3658 class SwitchCaseNode(StatNode):
3659 # Generated in the optimization of an if-elif-else node
3661 # conditions [ExprNode]
3664 child_attrs = ['conditions', 'body']
3666 def generate_execution_code(self, code):
3667 for cond in self.conditions:
3668 code.mark_pos(cond.pos)
3669 cond.generate_evaluation_code(code)
3670 code.putln("case %s:" % cond.result())
3671 self.body.generate_execution_code(code)
3672 code.putln("break;")
3674 def annotate(self, code):
3675 for cond in self.conditions:
3677 self.body.annotate(code)
3679 class SwitchStatNode(StatNode):
3680 # Generated in the optimization of an if-elif-else node
3683 # cases [SwitchCaseNode]
3684 # else_clause StatNode or None
3686 child_attrs = ['test', 'cases', 'else_clause']
3688 def generate_execution_code(self, code):
3689 code.putln("switch (%s) {" % self.test.result())
3690 for case in self.cases:
3691 case.generate_execution_code(code)
3692 if self.else_clause is not None:
3693 code.putln("default:")
3694 self.else_clause.generate_execution_code(code)
3695 code.putln("break;")
3698 def annotate(self, code):
3699 self.test.annotate(code)
3700 for case in self.cases:
3702 if self.else_clause is not None:
3703 self.else_clause.annotate(code)
3705 class LoopNode(object):
3707 def analyse_control_flow(self, env):
3708 env.start_branching(self.pos)
3709 self.body.analyse_control_flow(env)
3710 env.next_branch(self.body.end_pos())
3711 if self.else_clause:
3712 self.else_clause.analyse_control_flow(env)
3713 env.finish_branching(self.end_pos())
3716 class WhileStatNode(LoopNode, StatNode):
3719 # condition ExprNode
3721 # else_clause StatNode
3723 child_attrs = ["condition", "body", "else_clause"]
3725 def analyse_declarations(self, env):
3726 self.body.analyse_declarations(env)
3727 if self.else_clause:
3728 self.else_clause.analyse_declarations(env)
3730 def analyse_expressions(self, env):
3732 self.condition.analyse_temp_boolean_expression(env)
3733 self.condition.release_temp(env)
3734 #env.recycle_pending_temps() # TEMPORARY
3735 self.body.analyse_expressions(env)
3736 if self.else_clause:
3737 self.else_clause.analyse_expressions(env)
3739 def generate_execution_code(self, code):
3740 old_loop_labels = code.new_loop_labels()
3743 self.condition.generate_evaluation_code(code)
3744 self.condition.generate_disposal_code(code)
3747 self.condition.result())
3748 self.condition.free_temps(code)
3749 self.body.generate_execution_code(code)
3750 code.put_label(code.continue_label)
3752 break_label = code.break_label
3753 code.set_loop_labels(old_loop_labels)
3754 if self.else_clause:
3755 code.putln("/*else*/ {")
3756 self.else_clause.generate_execution_code(code)
3758 code.put_label(break_label)
3760 def annotate(self, code):
3761 self.condition.annotate(code)
3762 self.body.annotate(code)
3763 if self.else_clause:
3764 self.else_clause.annotate(code)
3767 def ForStatNode(pos, **kw):
3768 if 'iterator' in kw:
3769 return ForInStatNode(pos, **kw)
3771 return ForFromStatNode(pos, **kw)
3773 class ForInStatNode(LoopNode, StatNode):
3777 # iterator IteratorNode
3779 # else_clause StatNode
3780 # item NextNode used internally
3782 child_attrs = ["target", "iterator", "body", "else_clause"]
3785 def analyse_declarations(self, env):
3786 self.target.analyse_target_declaration(env)
3787 self.body.analyse_declarations(env)
3788 if self.else_clause:
3789 self.else_clause.analyse_declarations(env)
3791 def analyse_expressions(self, env):
3793 self.target.analyse_target_types(env)
3794 self.iterator.analyse_expressions(env)
3795 self.item = ExprNodes.NextNode(self.iterator, env)
3796 self.item = self.item.coerce_to(self.target.type, env)
3797 self.item.allocate_temps(env)
3798 self.target.allocate_target_temps(env, self.item)
3799 #self.item.release_temp(env)
3800 #self.target.release_target_temp(env)
3801 self.body.analyse_expressions(env)
3802 if self.else_clause:
3803 self.else_clause.analyse_expressions(env)
3804 self.iterator.release_temp(env)
3806 def generate_execution_code(self, code):
3807 old_loop_labels = code.new_loop_labels()
3808 self.iterator.allocate_counter_temp(code)
3809 self.iterator.generate_evaluation_code(code)
3812 self.item.generate_evaluation_code(code)
3813 self.target.generate_assignment_code(self.item, code)
3814 self.body.generate_execution_code(code)
3815 code.put_label(code.continue_label)
3818 break_label = code.break_label
3819 code.set_loop_labels(old_loop_labels)
3820 if self.else_clause:
3821 code.putln("/*else*/ {")
3822 self.else_clause.generate_execution_code(code)
3824 code.put_label(break_label)
3825 self.iterator.release_counter_temp(code)
3826 self.iterator.generate_disposal_code(code)
3827 self.iterator.free_temps(code)
3829 def annotate(self, code):
3830 self.target.annotate(code)
3831 self.iterator.annotate(code)
3832 self.body.annotate(code)
3833 if self.else_clause:
3834 self.else_clause.annotate(code)
3835 self.item.annotate(code)
3838 class ForFromStatNode(LoopNode, StatNode):
3839 # for name from expr rel name rel expr
3846 # step ExprNode or None
3848 # else_clause StatNode or None
3854 # loopvar_node ExprNode (usually a NameNode or temp node)
3855 # py_loopvar_node PyTempNode or None
3856 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3858 is_py_target = False
3860 py_loopvar_node = None
3863 def analyse_declarations(self, env):
3864 self.target.analyse_target_declaration(env)
3865 self.body.analyse_declarations(env)
3866 if self.else_clause:
3867 self.else_clause.analyse_declarations(env)
3869 def analyse_expressions(self, env):
3871 self.target.analyse_target_types(env)
3872 self.bound1.analyse_types(env)
3873 self.bound2.analyse_types(env)
3874 if self.step is not None:
3875 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3876 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3877 self.step.analyse_types(env)
3879 target_type = self.target.type
3880 if self.target.type.is_numeric:
3881 loop_type = self.target.type
3883 loop_type = PyrexTypes.c_int_type
3884 if not self.bound1.type.is_pyobject:
3885 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3886 if not self.bound2.type.is_pyobject:
3887 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3888 if self.step is not None and not self.step.type.is_pyobject:
3889 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3890 self.bound1 = self.bound1.coerce_to(loop_type, env)
3891 self.bound2 = self.bound2.coerce_to(loop_type, env)
3892 if not self.bound2.is_literal:
3893 self.bound2 = self.bound2.coerce_to_temp(env)
3894 if self.step is not None:
3895 self.step = self.step.coerce_to(loop_type, env)
3896 if not self.step.is_literal:
3897 self.step = self.step.coerce_to_temp(env)
3899 target_type = self.target.type
3900 if not (target_type.is_pyobject or target_type.is_numeric):
3901 error(self.target.pos,
3902 "for-from loop variable must be c numeric type or Python object")
3903 if target_type.is_numeric:
3904 self.is_py_target = False
3905 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3906 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3907 self.loopvar_node = self.target
3908 self.py_loopvar_node = None
3910 self.is_py_target = True
3911 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3912 c_loopvar_node.allocate_temps(env)
3913 self.loopvar_node = c_loopvar_node
3914 self.py_loopvar_node = \
3915 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3916 self.bound1.allocate_temps(env)
3917 self.bound2.allocate_temps(env)
3918 if self.step is not None:
3919 self.step.allocate_temps(env)
3920 if self.is_py_target:
3921 self.py_loopvar_node.allocate_temps(env)
3922 self.target.allocate_target_temps(env, self.py_loopvar_node)
3923 #self.target.release_target_temp(env)
3924 #self.py_loopvar_node.release_temp(env)
3925 self.body.analyse_expressions(env)
3926 if self.is_py_target:
3927 c_loopvar_node.release_temp(env)
3928 if self.else_clause:
3929 self.else_clause.analyse_expressions(env)
3930 self.bound1.release_temp(env)
3931 self.bound2.release_temp(env)
3932 if self.step is not None:
3933 self.step.release_temp(env)
3935 def generate_execution_code(self, code):
3936 old_loop_labels = code.new_loop_labels()
3937 from_range = self.from_range
3938 self.bound1.generate_evaluation_code(code)
3939 self.bound2.generate_evaluation_code(code)
3940 offset, incop = self.relation_table[self.relation1]
3941 if self.step is not None:
3942 self.step.generate_evaluation_code(code)
3943 step = self.step.result()
3944 incop = "%s=%s" % (incop[0], step)
3946 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3948 loopvar_name = self.loopvar_node.result()
3950 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3952 self.bound1.result(), offset,
3953 loopvar_name, self.relation2, self.bound2.result(),
3954 loopvar_name, incop))
3955 if self.py_loopvar_node:
3956 self.py_loopvar_node.generate_evaluation_code(code)
3957 self.target.generate_assignment_code(self.py_loopvar_node, code)
3959 code.putln("%s = %s;" % (
3960 self.target.result(), loopvar_name))
3961 self.body.generate_execution_code(code)
3962 code.put_label(code.continue_label)
3963 if self.py_loopvar_node:
3964 # Reassign py variable to loop var here.
3965 # (For consistancy, should rarely come up in practice.)
3967 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, self.target, None)
3968 from_py_node.temp_code = loopvar_name
3969 from_py_node.generate_result_code(code)
3971 if self.py_loopvar_node:
3972 # This is potentially wasteful, but we don't want the semantics to
3973 # depend on whether or not the loop is a python type.
3974 self.py_loopvar_node.generate_evaluation_code(code)
3975 self.target.generate_assignment_code(self.py_loopvar_node, code)
3976 break_label = code.break_label
3977 code.set_loop_labels(old_loop_labels)
3978 if self.else_clause:
3979 code.putln("/*else*/ {")
3980 self.else_clause.generate_execution_code(code)
3982 code.put_label(break_label)
3983 self.bound1.generate_disposal_code(code)
3984 self.bound1.free_temps(code)
3985 self.bound2.generate_disposal_code(code)
3986 self.bound2.free_temps(code)
3987 if self.step is not None:
3988 self.step.generate_disposal_code(code)
3989 self.step.free_temps(code)
3991 code.funcstate.release_temp(loopvar_name)
3994 # {relop : (initial offset, increment op)}
4001 def annotate(self, code):
4002 self.target.annotate(code)
4003 self.bound1.annotate(code)
4004 self.bound2.annotate(code)
4006 self.bound2.annotate(code)
4007 self.body.annotate(code)
4008 if self.else_clause:
4009 self.else_clause.annotate(code)
4012 class WithStatNode(StatNode):
4014 Represents a Python with statement.
4016 This is only used at parse tree level; and is not present in
4017 analysis or generation phases.
4019 # manager The with statement manager object
4020 # target Node (lhs expression)
4022 child_attrs = ["manager", "target", "body"]
4024 class TryExceptStatNode(StatNode):
4025 # try .. except statement
4028 # except_clauses [ExceptClauseNode]
4029 # else_clause StatNode or None
4030 # cleanup_list [Entry] old style temps to clean up on error
4032 child_attrs = ["body", "except_clauses", "else_clause"]
4034 def analyse_control_flow(self, env):
4035 env.start_branching(self.pos)
4036 self.body.analyse_control_flow(env)
4037 successful_try = env.control_flow # grab this for later
4038 env.next_branch(self.body.end_pos())
4039 env.finish_branching(self.body.end_pos())
4041 env.start_branching(self.except_clauses[0].pos)
4042 for except_clause in self.except_clauses:
4043 except_clause.analyse_control_flow(env)
4044 env.next_branch(except_clause.end_pos())
4046 # the else cause it executed only when the try clause finishes
4047 env.control_flow.incoming = successful_try
4048 if self.else_clause:
4049 self.else_clause.analyse_control_flow(env)
4050 env.finish_branching(self.end_pos())
4052 def analyse_declarations(self, env):
4053 self.body.analyse_declarations(env)
4054 for except_clause in self.except_clauses:
4055 except_clause.analyse_declarations(env)
4056 if self.else_clause:
4057 self.else_clause.analyse_declarations(env)
4058 env.use_utility_code(reset_exception_utility_code)
4060 def analyse_expressions(self, env):
4061 self.body.analyse_expressions(env)
4062 self.cleanup_list = env.free_temp_entries[:]
4063 default_clause_seen = 0
4064 for except_clause in self.except_clauses:
4065 except_clause.analyse_expressions(env)
4066 if default_clause_seen:
4067 error(except_clause.pos, "default 'except:' must be last")
4068 if not except_clause.pattern:
4069 default_clause_seen = 1
4070 self.has_default_clause = default_clause_seen
4071 if self.else_clause:
4072 self.else_clause.analyse_expressions(env)
4074 gil_check = StatNode._gil_check
4075 gil_message = "Try-except statement"
4077 def generate_execution_code(self, code):
4078 old_return_label = code.return_label
4079 old_break_label = code.break_label
4080 old_continue_label = code.continue_label
4081 old_error_label = code.new_error_label()
4082 our_error_label = code.error_label
4083 except_end_label = code.new_label('exception_handled')
4084 except_error_label = code.new_label('except_error')
4085 except_return_label = code.new_label('except_return')
4086 try_return_label = code.new_label('try_return')
4087 try_break_label = code.new_label('try_break')
4088 try_continue_label = code.new_label('try_continue')
4089 try_end_label = code.new_label('try_end')
4092 code.putln("PyObject %s;" %
4093 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4094 code.putln("__Pyx_ExceptionSave(%s);" %
4095 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4096 for var in Naming.exc_save_vars:
4097 code.put_xgotref(var)
4100 code.return_label = try_return_label
4101 code.break_label = try_break_label
4102 code.continue_label = try_continue_label
4103 self.body.generate_execution_code(code)
4106 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4107 code.error_label = except_error_label
4108 code.return_label = except_return_label
4109 if self.else_clause:
4112 self.else_clause.generate_execution_code(code)
4115 for var in Naming.exc_save_vars:
4116 code.put_xdecref_clear(var, py_object_type)
4117 code.put_goto(try_end_label)
4118 if code.label_used(try_return_label):
4119 code.put_label(try_return_label)
4120 for var in Naming.exc_save_vars:
4121 code.put_xdecref_clear(var, py_object_type)
4122 code.put_goto(old_return_label)
4123 code.put_label(our_error_label)
4124 code.put_var_xdecrefs_clear(self.cleanup_list)
4125 for temp_name, type in temps_to_clean_up:
4126 code.put_xdecref_clear(temp_name, type)
4127 for except_clause in self.except_clauses:
4128 except_clause.generate_handling_code(code, except_end_label)
4130 error_label_used = code.label_used(except_error_label)
4131 if error_label_used or not self.has_default_clause:
4132 if error_label_used:
4133 code.put_label(except_error_label)
4134 for var in Naming.exc_save_vars:
4135 code.put_xdecref(var, py_object_type)
4136 code.put_goto(old_error_label)
4138 if code.label_used(try_break_label):
4139 code.put_label(try_break_label)
4140 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4141 code.putln("__Pyx_ExceptionReset(%s);" %
4142 ', '.join(Naming.exc_save_vars))
4143 code.put_goto(old_break_label)
4145 if code.label_used(try_continue_label):
4146 code.put_label(try_continue_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_continue_label)
4152 if code.label_used(except_return_label):
4153 code.put_label(except_return_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_return_label)
4159 if code.label_used(except_end_label):
4160 code.put_label(except_end_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_label(try_end_label)
4167 code.return_label = old_return_label
4168 code.break_label = old_break_label
4169 code.continue_label = old_continue_label
4170 code.error_label = old_error_label
4172 def annotate(self, code):
4173 self.body.annotate(code)
4174 for except_node in self.except_clauses:
4175 except_node.annotate(code)
4176 if self.else_clause:
4177 self.else_clause.annotate(code)
4180 class ExceptClauseNode(Node):
4181 # Part of try ... except statement.
4184 # target ExprNode or None
4186 # excinfo_target NameNode or None optional target for exception info
4187 # match_flag string result of exception match
4188 # exc_value ExcValueNode used internally
4189 # function_name string qualified name of enclosing function
4190 # exc_vars (string * 3) local exception variables
4192 # excinfo_target is never set by the parser, but can be set by a transform
4193 # in order to extract more extensive information about the exception as a
4194 # sys.exc_info()-style tuple into a target variable
4196 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4199 excinfo_target = None
4201 def analyse_declarations(self, env):
4203 self.target.analyse_target_declaration(env)
4204 if self.excinfo_target is not None:
4205 self.excinfo_target.analyse_target_declaration(env)
4206 self.body.analyse_declarations(env)
4208 def analyse_expressions(self, env):
4210 genv = env.global_scope()
4211 self.function_name = env.qualified_name
4213 self.pattern.analyse_expressions(env)
4214 self.pattern = self.pattern.coerce_to_pyobject(env)
4215 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4216 self.pattern.release_temp(env)
4217 env.release_temp(self.match_flag)
4219 if self.target or self.excinfo_target:
4220 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4222 self.exc_vars = None
4225 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4226 self.exc_value.allocate_temps(env)
4227 self.target.analyse_target_expression(env, self.exc_value)
4228 if self.excinfo_target is not None:
4230 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4231 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4232 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4233 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4235 self.excinfo_tuple.analyse_expressions(env)
4236 self.excinfo_tuple.allocate_temps(env)
4237 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4239 self.body.analyse_expressions(env)
4242 for var in self.exc_vars:
4243 env.release_temp(var)
4245 def generate_handling_code(self, code, end_label):
4246 code.mark_pos(self.pos)
4248 self.pattern.generate_evaluation_code(code)
4250 "%s = PyErr_ExceptionMatches(%s);" % (
4252 self.pattern.py_result()))
4253 self.pattern.generate_disposal_code(code)
4254 self.pattern.free_temps(code)
4259 code.putln("/*except:*/ {")
4262 exc_vars = self.exc_vars
4263 elif not getattr(self.body, 'stats', True):
4264 # most simple case: no exception variable, empty body (pass)
4265 # => reset the exception state, done
4266 code.putln("PyErr_Restore(0,0,0);")
4267 code.put_goto(end_label)
4271 # during type analysis, we didn't know if we need the
4272 # exception value, but apparently, we do
4273 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4277 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4278 # We always have to fetch the exception value even if
4279 # there is no target, because this also normalises the
4280 # exception and stores it in the thread state.
4281 code.globalstate.use_utility_code(get_exception_utility_code)
4282 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4283 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4284 code.error_goto(self.pos)))
4288 self.exc_value.generate_evaluation_code(code)
4289 self.target.generate_assignment_code(self.exc_value, code)
4290 if self.excinfo_target is not None:
4291 self.excinfo_tuple.generate_evaluation_code(code)
4292 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4295 old_break_label, old_continue_label = code.break_label, code.continue_label
4296 code.break_label = code.new_label('except_break')
4297 code.continue_label = code.new_label('except_continue')
4299 old_exc_vars = code.funcstate.exc_vars
4300 code.funcstate.exc_vars = exc_vars
4301 self.body.generate_execution_code(code)
4302 code.funcstate.exc_vars = old_exc_vars
4303 for var in exc_vars:
4304 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4305 code.put_goto(end_label)
4307 if code.label_used(code.break_label):
4308 code.put_label(code.break_label)
4309 for var in exc_vars:
4310 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4311 code.put_goto(old_break_label)
4312 code.break_label = old_break_label
4314 if code.label_used(code.continue_label):
4315 code.put_label(code.continue_label)
4316 for var in exc_vars:
4317 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4318 code.put_goto(old_continue_label)
4319 code.continue_label = old_continue_label
4321 if not self.exc_vars:
4322 # clean up locally allocated temps
4323 for temp in exc_vars:
4324 code.funcstate.release_temp(temp)
4329 def annotate(self, code):
4331 self.pattern.annotate(code)
4333 self.target.annotate(code)
4334 self.body.annotate(code)
4337 class TryFinallyStatNode(StatNode):
4338 # try ... finally statement
4341 # finally_clause StatNode
4343 # cleanup_list [Entry] old_style temps to clean up on error
4345 # The plan is that we funnel all continue, break
4346 # return and error gotos into the beginning of the
4347 # finally block, setting a variable to remember which
4348 # one we're doing. At the end of the finally block, we
4349 # switch on the variable to figure out where to go.
4350 # In addition, if we're doing an error, we save the
4351 # exception on entry to the finally block and restore
4354 child_attrs = ["body", "finally_clause"]
4356 preserve_exception = 1
4358 disallow_continue_in_try_finally = 0
4359 # There doesn't seem to be any point in disallowing
4360 # continue in the try block, since we have no problem
4363 def create_analysed(pos, env, body, finally_clause):
4364 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4365 node.cleanup_list = []
4367 create_analysed = staticmethod(create_analysed)
4369 def analyse_control_flow(self, env):
4370 env.start_branching(self.pos)
4371 self.body.analyse_control_flow(env)
4372 env.next_branch(self.body.end_pos())
4373 env.finish_branching(self.body.end_pos())
4374 self.finally_clause.analyse_control_flow(env)
4376 def analyse_declarations(self, env):
4377 self.body.analyse_declarations(env)
4378 self.finally_clause.analyse_declarations(env)
4380 def analyse_expressions(self, env):
4381 self.body.analyse_expressions(env)
4382 self.cleanup_list = env.free_temp_entries[:]
4383 self.finally_clause.analyse_expressions(env)
4385 gil_check = StatNode._gil_check
4386 gil_message = "Try-finally statement"
4388 def generate_execution_code(self, code):
4389 old_error_label = code.error_label
4390 old_labels = code.all_new_labels()
4391 new_labels = code.get_all_labels()
4392 new_error_label = code.error_label
4393 catch_label = code.new_label()
4396 if self.disallow_continue_in_try_finally:
4397 was_in_try_finally = code.funcstate.in_try_finally
4398 code.funcstate.in_try_finally = 1
4399 self.body.generate_execution_code(code)
4400 if self.disallow_continue_in_try_finally:
4401 code.funcstate.in_try_finally = was_in_try_finally
4404 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4408 error_label_used = 0
4409 for i, new_label in enumerate(new_labels):
4410 if new_label in code.labels_used:
4411 cases_used.append(i)
4412 if new_label == new_error_label:
4413 error_label_used = 1
4414 error_label_case = i
4418 if error_label_used and self.preserve_exception:
4420 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4422 "int %s;" % Naming.exc_lineno_name)
4423 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4424 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4425 code.putln(exc_var_init_zero)
4427 exc_var_init_zero = None
4428 code.use_label(catch_label)
4430 "__pyx_why = 0; goto %s;" % catch_label)
4431 for i in cases_used:
4432 new_label = new_labels[i]
4433 #if new_label and new_label != "<try>":
4434 if new_label == new_error_label and self.preserve_exception:
4435 self.put_error_catcher(code,
4436 new_error_label, i+1, catch_label, temps_to_clean_up)
4438 code.put('%s: ' % new_label)
4439 if exc_var_init_zero:
4440 code.putln(exc_var_init_zero)
4441 code.putln("__pyx_why = %s; goto %s;" % (
4444 code.put_label(catch_label)
4445 code.set_all_labels(old_labels)
4446 if error_label_used:
4447 code.new_error_label()
4448 finally_error_label = code.error_label
4449 self.finally_clause.generate_execution_code(code)
4450 if error_label_used:
4451 if finally_error_label in code.labels_used and self.preserve_exception:
4452 over_label = code.new_label()
4453 code.put_goto(over_label);
4454 code.put_label(finally_error_label)
4455 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4456 for var in Naming.exc_vars:
4457 code.putln("Py_XDECREF(%s);" % var)
4459 code.put_goto(old_error_label)
4460 code.put_label(over_label)
4461 code.error_label = old_error_label
4464 "switch (__pyx_why) {")
4465 for i in cases_used:
4466 old_label = old_labels[i]
4467 if old_label == old_error_label and self.preserve_exception:
4468 self.put_error_uncatcher(code, i+1, old_error_label)
4470 code.use_label(old_label)
4472 "case %s: goto %s;" % (
4480 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4481 code.globalstate.use_utility_code(restore_exception_utility_code)
4488 code.put_var_xdecrefs_clear(self.cleanup_list)
4489 for temp_name, type in temps_to_clean_up:
4490 code.put_xdecref_clear(temp_name, type)
4492 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4496 Naming.exc_lineno_name, Naming.lineno_cname))
4500 code.put_goto(catch_label)
4504 def put_error_uncatcher(self, code, i, error_label):
4505 code.globalstate.use_utility_code(restore_exception_utility_code)
4510 "__Pyx_ErrRestore(%s, %s, %s);" %
4514 Naming.lineno_cname, Naming.exc_lineno_name))
4515 for var in Naming.exc_vars:
4519 code.put_goto(error_label)
4523 def annotate(self, code):
4524 self.body.annotate(code)
4525 self.finally_clause.annotate(code)
4528 class GILStatNode(TryFinallyStatNode):
4529 # 'with gil' or 'with nogil' statement
4531 # state string 'gil' or 'nogil'
4535 preserve_exception = 0
4537 def __init__(self, pos, state, body):
4539 TryFinallyStatNode.__init__(self, pos,
4541 finally_clause = GILExitNode(pos, state = state))
4543 def analyse_expressions(self, env):
4544 env.use_utility_code(force_init_threads_utility_code)
4545 was_nogil = env.nogil
4547 TryFinallyStatNode.analyse_expressions(self, env)
4548 env.nogil = was_nogil
4550 def gil_check(self, env):
4553 def generate_execution_code(self, code):
4554 code.mark_pos(self.pos)
4555 if self.state == 'gil':
4556 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4558 code.putln("{ PyThreadState *_save;")
4559 code.putln("Py_UNBLOCK_THREADS")
4560 TryFinallyStatNode.generate_execution_code(self, code)
4564 class GILExitNode(StatNode):
4565 # Used as the 'finally' block in a GILStatNode
4567 # state string 'gil' or 'nogil'
4571 def analyse_expressions(self, env):
4574 def generate_execution_code(self, code):
4575 if self.state == 'gil':
4576 code.putln("PyGILState_Release();")
4578 code.putln("Py_BLOCK_THREADS")
4581 class CImportStatNode(StatNode):
4584 # module_name string Qualified name of module being imported
4585 # as_name string or None Name specified in "as" clause, if any
4589 def analyse_declarations(self, env):
4590 if not env.is_module_scope:
4591 error(self.pos, "cimport only allowed at module level")
4593 module_scope = env.find_module(self.module_name, self.pos)
4594 if "." in self.module_name:
4595 names = [EncodedString(name) for name in self.module_name.split(".")]
4597 top_module_scope = env.context.find_submodule(top_name)
4598 module_scope = top_module_scope
4599 for name in names[1:]:
4600 submodule_scope = module_scope.find_submodule(name)
4601 module_scope.declare_module(name, submodule_scope, self.pos)
4602 module_scope = submodule_scope
4604 env.declare_module(self.as_name, module_scope, self.pos)
4606 env.declare_module(top_name, top_module_scope, self.pos)
4608 name = self.as_name or self.module_name
4609 env.declare_module(name, module_scope, self.pos)
4611 def analyse_expressions(self, env):
4614 def generate_execution_code(self, code):
4618 class FromCImportStatNode(StatNode):
4619 # from ... cimport statement
4621 # module_name string Qualified name of module
4622 # imported_names [(pos, name, as_name, kind)] Names to be imported
4626 def analyse_declarations(self, env):
4627 if not env.is_module_scope:
4628 error(self.pos, "cimport only allowed at module level")
4630 module_scope = env.find_module(self.module_name, self.pos)
4631 env.add_imported_module(module_scope)
4632 for pos, name, as_name, kind in self.imported_names:
4634 for local_name, entry in module_scope.entries.items():
4635 env.add_imported_entry(local_name, entry, pos)
4637 entry = module_scope.lookup(name)
4639 if kind and not self.declaration_matches(entry, kind):
4640 entry.redeclared(pos)
4642 if kind == 'struct' or kind == 'union':
4643 entry = module_scope.declare_struct_or_union(name,
4644 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4645 elif kind == 'class':
4646 entry = module_scope.declare_c_class(name, pos = pos,
4647 module_name = self.module_name)
4649 error(pos, "Name '%s' not declared in module '%s'"
4650 % (name, self.module_name))
4653 local_name = as_name or name
4654 env.add_imported_entry(local_name, entry, pos)
4656 def declaration_matches(self, entry, kind):
4657 if not entry.is_type:
4661 if not type.is_extension_type:
4664 if not type.is_struct_or_union:
4666 if kind != type.kind:
4670 def analyse_expressions(self, env):
4673 def generate_execution_code(self, code):
4677 class FromImportStatNode(StatNode):
4678 # from ... import statement
4681 # items [(string, NameNode)]
4682 # interned_items [(string, NameNode, ExprNode)]
4683 # item PyTempNode used internally
4684 # import_star boolean used internally
4686 child_attrs = ["module"]
4689 def analyse_declarations(self, env):
4690 for name, target in self.items:
4692 if not env.is_module_scope:
4693 error(self.pos, "import * only allowed at module level")
4695 env.has_import_star = 1
4696 self.import_star = 1
4698 target.analyse_target_declaration(env)
4700 def analyse_expressions(self, env):
4702 self.module.analyse_expressions(env)
4703 self.item = ExprNodes.PyTempNode(self.pos, env)
4704 self.item.allocate_temp(env)
4705 self.interned_items = []
4706 for name, target in self.items:
4708 for _, entry in env.entries.items():
4709 if not entry.is_type and entry.type.is_extension_type:
4710 env.use_utility_code(ExprNodes.type_test_utility_code)
4713 entry = env.lookup(target.name)
4714 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4715 continue # already cimported
4716 target.analyse_target_expression(env, None)
4717 if target.type is py_object_type:
4720 coerced_item = self.item.coerce_to(target.type, env)
4721 self.interned_items.append(
4722 (name, target, coerced_item))
4723 #target.release_target_temp(env) # was release_temp ?!?
4724 self.module.release_temp(env)
4725 self.item.release_temp(env)
4727 def generate_execution_code(self, code):
4728 self.module.generate_evaluation_code(code)
4729 if self.import_star:
4731 'if (%s(%s) < 0) %s;' % (
4733 self.module.py_result(),
4734 code.error_goto(self.pos)))
4735 for name, target, coerced_item in self.interned_items:
4736 cname = code.intern_identifier(name)
4738 '%s = PyObject_GetAttr(%s, %s); %s' % (
4740 self.module.py_result(),
4742 code.error_goto_if_null(self.item.result(), self.pos)))
4743 code.put_gotref(self.item.py_result())
4744 if coerced_item is None:
4745 target.generate_assignment_code(self.item, code)
4747 coerced_item.allocate_temp_result(code)
4748 coerced_item.generate_result_code(code)
4749 target.generate_assignment_code(coerced_item, code)
4750 if self.item.result() != coerced_item.result():
4751 code.put_decref_clear(self.item.result(), self.item.type)
4752 self.module.generate_disposal_code(code)
4753 self.module.free_temps(code)
4757 #------------------------------------------------------------------------------------
4759 # Runtime support code
4761 #------------------------------------------------------------------------------------
4763 utility_function_predeclarations = \
4766 #define INLINE __inline__
4768 #define INLINE __inline
4773 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4777 static int %(skip_dispatch_cname)s = 0;
4779 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4781 if Options.gcc_branch_hints:
4782 branch_prediction_macros = \
4785 /* Test for GCC > 2.95 */
4786 #if __GNUC__ > 2 || \
4787 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4788 #define likely(x) __builtin_expect(!!(x), 1)
4789 #define unlikely(x) __builtin_expect(!!(x), 0)
4790 #else /* __GNUC__ > 2 ... */
4791 #define likely(x) (x)
4792 #define unlikely(x) (x)
4793 #endif /* __GNUC__ > 2 ... */
4794 #else /* __GNUC__ */
4795 #define likely(x) (x)
4796 #define unlikely(x) (x)
4797 #endif /* __GNUC__ */
4800 branch_prediction_macros = \
4802 #define likely(x) (x)
4803 #define unlikely(x) (x)
4806 #get_name_predeclaration = \
4807 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4809 #get_name_interned_predeclaration = \
4810 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4812 #------------------------------------------------------------------------------------
4814 printing_utility_code = UtilityCode(
4816 static int __Pyx_Print(PyObject *, int); /*proto*/
4817 #if PY_MAJOR_VERSION >= 3
4818 static PyObject* %s = 0;
4819 static PyObject* %s = 0;
4821 """ % (Naming.print_function, Naming.print_function_kwargs),
4823 #if PY_MAJOR_VERSION < 3
4824 static PyObject *__Pyx_GetStdout(void) {
4825 PyObject *f = PySys_GetObject((char *)"stdout");
4827 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4832 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4837 if (!(f = __Pyx_GetStdout()))
4839 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4840 if (PyFile_SoftSpace(f, 1)) {
4841 if (PyFile_WriteString(" ", f) < 0)
4844 v = PyTuple_GET_ITEM(arg_tuple, i);
4845 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4847 if (PyString_Check(v)) {
4848 char *s = PyString_AsString(v);
4849 Py_ssize_t len = PyString_Size(v);
4851 isspace(Py_CHARMASK(s[len-1])) &&
4853 PyFile_SoftSpace(f, 0);
4857 if (PyFile_WriteString("\n", f) < 0)
4859 PyFile_SoftSpace(f, 0);
4864 #else /* Python 3 has a print function */
4866 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4867 PyObject* kwargs = 0;
4868 PyObject* result = 0;
4869 PyObject* end_string;
4870 if (!%(PRINT_FUNCTION)s) {
4871 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4872 if (!%(PRINT_FUNCTION)s)
4876 if (!%(PRINT_KWARGS)s) {
4877 %(PRINT_KWARGS)s = PyDict_New();
4878 if (!%(PRINT_KWARGS)s)
4880 end_string = PyUnicode_FromStringAndSize(" ", 1);
4883 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4884 Py_DECREF(end_string);
4887 Py_DECREF(end_string);
4889 kwargs = %(PRINT_KWARGS)s;
4891 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4899 """ % {'BUILTINS' : Naming.builtins_cname,
4900 'PRINT_FUNCTION' : Naming.print_function,
4901 'PRINT_KWARGS' : Naming.print_function_kwargs}
4905 printing_one_utility_code = UtilityCode(
4907 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4910 #if PY_MAJOR_VERSION < 3
4912 static int __Pyx_PrintOne(PyObject *o) {
4914 if (!(f = __Pyx_GetStdout()))
4916 if (PyFile_SoftSpace(f, 0)) {
4917 if (PyFile_WriteString(" ", f) < 0)
4920 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4922 if (PyFile_WriteString("\n", f) < 0)
4925 /* the line below is just to avoid compiler
4926 * compiler warnings about unused functions */
4927 return __Pyx_Print(NULL, 0);
4930 #else /* Python 3 has a print function */
4932 static int __Pyx_PrintOne(PyObject *o) {
4934 PyObject* arg_tuple = PyTuple_New(1);
4935 if (unlikely(!arg_tuple))
4938 PyTuple_SET_ITEM(arg_tuple, 0, o);
4939 res = __Pyx_Print(arg_tuple, 1);
4940 Py_DECREF(arg_tuple);
4949 #------------------------------------------------------------------------------------
4951 # The following function is based on do_raise() from ceval.c.
4953 raise_utility_code = UtilityCode(
4955 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4958 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4962 /* First, check the traceback argument, replacing None with NULL. */
4963 if (tb == Py_None) {
4967 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4968 PyErr_SetString(PyExc_TypeError,
4969 "raise: arg 3 must be a traceback or None");
4972 /* Next, replace a missing value with None */
4973 if (value == NULL) {
4977 #if PY_VERSION_HEX < 0x02050000
4978 if (!PyClass_Check(type))
4980 if (!PyType_Check(type))
4983 /* Raising an instance. The value should be a dummy. */
4984 if (value != Py_None) {
4985 PyErr_SetString(PyExc_TypeError,
4986 "instance exception may not have a separate value");
4989 /* Normalize to raise <class>, <instance> */
4992 #if PY_VERSION_HEX < 0x02050000
4993 if (PyInstance_Check(type)) {
4994 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4999 PyErr_SetString(PyExc_TypeError,
5000 "raise: exception must be an old-style class or instance");
5004 type = (PyObject*) Py_TYPE(type);
5006 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5007 PyErr_SetString(PyExc_TypeError,
5008 "raise: exception class must be a subclass of BaseException");
5013 __Pyx_ErrRestore(type, value, tb);
5023 #------------------------------------------------------------------------------------
5025 reraise_utility_code = UtilityCode(
5027 static void __Pyx_ReRaise(void); /*proto*/
5030 static void __Pyx_ReRaise(void) {
5031 PyThreadState *tstate = PyThreadState_GET();
5032 PyObject* tmp_type = tstate->curexc_type;
5033 PyObject* tmp_value = tstate->curexc_value;
5034 PyObject* tmp_tb = tstate->curexc_traceback;
5035 tstate->curexc_type = tstate->exc_type;
5036 tstate->curexc_value = tstate->exc_value;
5037 tstate->curexc_traceback = tstate->exc_traceback;
5038 tstate->exc_type = 0;
5039 tstate->exc_value = 0;
5040 tstate->exc_traceback = 0;
5041 Py_XDECREF(tmp_type);
5042 Py_XDECREF(tmp_value);
5047 #------------------------------------------------------------------------------------
5049 arg_type_test_utility_code = UtilityCode(
5051 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5052 const char *name, int exact); /*proto*/
5055 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5056 const char *name, int exact)
5059 PyErr_Format(PyExc_SystemError, "Missing type object");
5062 if (none_allowed && obj == Py_None) return 1;
5064 if (Py_TYPE(obj) == type) return 1;
5067 if (PyObject_TypeCheck(obj, type)) return 1;
5069 PyErr_Format(PyExc_TypeError,
5070 "Argument '%s' has incorrect type (expected %s, got %s)",
5071 name, type->tp_name, Py_TYPE(obj)->tp_name);
5076 #------------------------------------------------------------------------------------
5078 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5079 # many or too few positional arguments were found. This handles
5080 # Py_ssize_t formatting correctly.
5082 raise_argtuple_invalid_utility_code = UtilityCode(
5084 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5085 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5088 static void __Pyx_RaiseArgtupleInvalid(
5089 const char* func_name,
5093 Py_ssize_t num_found)
5095 Py_ssize_t num_expected;
5096 const char *number, *more_or_less;
5098 if (num_found < num_min) {
5099 num_expected = num_min;
5100 more_or_less = "at least";
5102 num_expected = num_max;
5103 more_or_less = "at most";
5106 more_or_less = "exactly";
5108 number = (num_expected == 1) ? "" : "s";
5109 PyErr_Format(PyExc_TypeError,
5110 #if PY_VERSION_HEX < 0x02050000
5111 "%s() takes %s %d positional argument%s (%d given)",
5113 "%s() takes %s %zd positional argument%s (%zd given)",
5115 func_name, more_or_less, num_expected, number, num_found);
5119 raise_keyword_required_utility_code = UtilityCode(
5121 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5124 static INLINE void __Pyx_RaiseKeywordRequired(
5125 const char* func_name,
5128 PyErr_Format(PyExc_TypeError,
5129 #if PY_MAJOR_VERSION >= 3
5130 "%s() needs keyword-only argument %U", func_name, kw_name);
5132 "%s() needs keyword-only argument %s", func_name,
5133 PyString_AS_STRING(kw_name));
5138 raise_double_keywords_utility_code = UtilityCode(
5140 static void __Pyx_RaiseDoubleKeywordsError(
5141 const char* func_name, PyObject* kw_name); /*proto*/
5144 static void __Pyx_RaiseDoubleKeywordsError(
5145 const char* func_name,
5148 PyErr_Format(PyExc_TypeError,
5149 #if PY_MAJOR_VERSION >= 3
5150 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5152 "%s() got multiple values for keyword argument '%s'", func_name,
5153 PyString_AS_STRING(kw_name));
5158 #------------------------------------------------------------------------------------
5160 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5161 # were passed to a function, or if any keywords were passed to a
5162 # function that does not accept them.
5164 keyword_string_check_utility_code = UtilityCode(
5166 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5167 const char* function_name, int kw_allowed); /*proto*/
5170 static INLINE int __Pyx_CheckKeywordStrings(
5172 const char* function_name,
5177 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5178 #if PY_MAJOR_VERSION < 3
5179 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5181 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5183 goto invalid_keyword_type;
5185 if ((!kw_allowed) && unlikely(key))
5186 goto invalid_keyword;
5188 invalid_keyword_type:
5189 PyErr_Format(PyExc_TypeError,
5190 "%s() keywords must be strings", function_name);
5193 PyErr_Format(PyExc_TypeError,
5194 #if PY_MAJOR_VERSION < 3
5195 "%s() got an unexpected keyword argument '%s'",
5196 function_name, PyString_AsString(key));
5198 "%s() got an unexpected keyword argument '%U'",
5199 function_name, key);
5205 #------------------------------------------------------------------------------------
5207 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5208 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5209 # keywords will raise an invalid keyword error.
5211 # Three kinds of errors are checked: 1) non-string keywords, 2)
5212 # unexpected keywords and 3) overlap with positional arguments.
5214 # If num_posargs is greater 0, it denotes the number of positional
5215 # arguments that were passed and that must therefore not appear
5216 # amongst the keywords as well.
5218 # This method does not check for required keyword arguments.
5221 parse_keywords_utility_code = UtilityCode(
5223 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5224 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5225 const char* function_name); /*proto*/
5228 static int __Pyx_ParseOptionalKeywords(
5230 PyObject **argnames[],
5233 Py_ssize_t num_pos_args,
5234 const char* function_name)
5236 PyObject *key = 0, *value = 0;
5239 PyObject*** first_kw_arg = argnames + num_pos_args;
5241 while (PyDict_Next(kwds, &pos, &key, &value)) {
5242 name = first_kw_arg;
5243 while (*name && (**name != key)) name++;
5245 values[name-argnames] = value;
5247 #if PY_MAJOR_VERSION < 3
5248 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5250 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5252 goto invalid_keyword_type;
5254 for (name = first_kw_arg; *name; name++) {
5255 #if PY_MAJOR_VERSION >= 3
5256 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5257 PyUnicode_Compare(**name, key) == 0) break;
5259 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5260 _PyString_Eq(**name, key)) break;
5264 values[name-argnames] = value;
5266 /* unexpected keyword found */
5267 for (name=argnames; name != first_kw_arg; name++) {
5268 if (**name == key) goto arg_passed_twice;
5269 #if PY_MAJOR_VERSION >= 3
5270 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5271 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5273 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5274 _PyString_Eq(**name, key)) goto arg_passed_twice;
5278 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5280 goto invalid_keyword;
5288 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5290 invalid_keyword_type:
5291 PyErr_Format(PyExc_TypeError,
5292 "%s() keywords must be strings", function_name);
5295 PyErr_Format(PyExc_TypeError,
5296 #if PY_MAJOR_VERSION < 3
5297 "%s() got an unexpected keyword argument '%s'",
5298 function_name, PyString_AsString(key));
5300 "%s() got an unexpected keyword argument '%U'",
5301 function_name, key);
5308 #------------------------------------------------------------------------------------
5310 unraisable_exception_utility_code = UtilityCode(
5312 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5315 static void __Pyx_WriteUnraisable(const char *name) {
5316 PyObject *old_exc, *old_val, *old_tb;
5318 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5319 #if PY_MAJOR_VERSION < 3
5320 ctx = PyString_FromString(name);
5322 ctx = PyUnicode_FromString(name);
5324 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5326 PyErr_WriteUnraisable(Py_None);
5328 PyErr_WriteUnraisable(ctx);
5334 #------------------------------------------------------------------------------------
5336 traceback_utility_code = UtilityCode(
5338 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5341 #include "compile.h"
5342 #include "frameobject.h"
5343 #include "traceback.h"
5345 static void __Pyx_AddTraceback(const char *funcname) {
5346 PyObject *py_srcfile = 0;
5347 PyObject *py_funcname = 0;
5348 PyObject *py_globals = 0;
5349 PyObject *empty_string = 0;
5350 PyCodeObject *py_code = 0;
5351 PyFrameObject *py_frame = 0;
5353 #if PY_MAJOR_VERSION < 3
5354 py_srcfile = PyString_FromString(%(FILENAME)s);
5356 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5358 if (!py_srcfile) goto bad;
5360 #if PY_MAJOR_VERSION < 3
5361 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5363 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5367 #if PY_MAJOR_VERSION < 3
5368 py_funcname = PyString_FromString(funcname);
5370 py_funcname = PyUnicode_FromString(funcname);
5373 if (!py_funcname) goto bad;
5374 py_globals = PyModule_GetDict(%(GLOBALS)s);
5375 if (!py_globals) goto bad;
5376 #if PY_MAJOR_VERSION < 3
5377 empty_string = PyString_FromStringAndSize("", 0);
5379 empty_string = PyBytes_FromStringAndSize("", 0);
5381 if (!empty_string) goto bad;
5382 py_code = PyCode_New(
5383 0, /*int argcount,*/
5384 #if PY_MAJOR_VERSION >= 3
5385 0, /*int kwonlyargcount,*/
5388 0, /*int stacksize,*/
5390 empty_string, /*PyObject *code,*/
5391 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5392 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5393 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5394 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5395 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5396 py_srcfile, /*PyObject *filename,*/
5397 py_funcname, /*PyObject *name,*/
5398 %(LINENO)s, /*int firstlineno,*/
5399 empty_string /*PyObject *lnotab*/
5401 if (!py_code) goto bad;
5402 py_frame = PyFrame_New(
5403 PyThreadState_GET(), /*PyThreadState *tstate,*/
5404 py_code, /*PyCodeObject *code,*/
5405 py_globals, /*PyObject *globals,*/
5406 0 /*PyObject *locals*/
5408 if (!py_frame) goto bad;
5409 py_frame->f_lineno = %(LINENO)s;
5410 PyTraceBack_Here(py_frame);
5412 Py_XDECREF(py_srcfile);
5413 Py_XDECREF(py_funcname);
5414 Py_XDECREF(empty_string);
5415 Py_XDECREF(py_code);
5416 Py_XDECREF(py_frame);
5419 'FILENAME': Naming.filename_cname,
5420 'LINENO': Naming.lineno_cname,
5421 'CFILENAME': Naming.cfilenm_cname,
5422 'CLINENO': Naming.clineno_cname,
5423 'GLOBALS': Naming.module_cname,
5424 'EMPTY_TUPLE' : Naming.empty_tuple,
5427 restore_exception_utility_code = UtilityCode(
5429 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5430 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5433 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5434 PyObject *tmp_type, *tmp_value, *tmp_tb;
5435 PyThreadState *tstate = PyThreadState_GET();
5437 #if PY_MAJOR_VERSION >= 3
5438 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5439 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5440 tmp_type = tstate->exc_type;
5441 tmp_value = tstate->exc_value;
5442 tmp_tb = tstate->exc_traceback;
5443 PyErr_NormalizeException(&type, &value, &tb);
5444 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5445 tstate->exc_type = 0;
5446 tstate->exc_value = 0;
5447 tstate->exc_traceback = 0;
5448 PyException_SetContext(value, tmp_value);
5449 Py_DECREF(tmp_type);
5454 tmp_type = tstate->curexc_type;
5455 tmp_value = tstate->curexc_value;
5456 tmp_tb = tstate->curexc_traceback;
5457 tstate->curexc_type = type;
5458 tstate->curexc_value = value;
5459 tstate->curexc_traceback = tb;
5460 Py_XDECREF(tmp_type);
5461 Py_XDECREF(tmp_value);
5465 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5466 PyThreadState *tstate = PyThreadState_GET();
5467 *type = tstate->curexc_type;
5468 *value = tstate->curexc_value;
5469 *tb = tstate->curexc_traceback;
5471 tstate->curexc_type = 0;
5472 tstate->curexc_value = 0;
5473 tstate->curexc_traceback = 0;
5478 #------------------------------------------------------------------------------------
5480 set_vtable_utility_code = UtilityCode(
5482 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5485 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5486 PyObject *pycobj = 0;
5489 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5492 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5505 #------------------------------------------------------------------------------------
5507 get_vtable_utility_code = UtilityCode(
5509 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5512 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5516 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5519 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5520 if (!*(void **)vtabptr)
5533 #------------------------------------------------------------------------------------
5535 init_string_tab_utility_code = UtilityCode(
5537 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5540 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5542 #if PY_MAJOR_VERSION < 3
5543 if (t->is_unicode && (!t->is_identifier)) {
5544 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5545 } else if (t->intern) {
5546 *t->p = PyString_InternFromString(t->s);
5548 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5550 #else /* Python 3+ has unicode identifiers */
5551 if (t->is_identifier || (t->is_unicode && t->intern)) {
5552 *t->p = PyUnicode_InternFromString(t->s);
5553 } else if (t->is_unicode) {
5554 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5556 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5567 #------------------------------------------------------------------------------------
5569 get_exception_utility_code = UtilityCode(
5571 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5574 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5575 PyObject *tmp_type, *tmp_value, *tmp_tb;
5576 PyThreadState *tstate = PyThreadState_GET();
5577 *type = tstate->curexc_type;
5578 *value = tstate->curexc_value;
5579 *tb = tstate->curexc_traceback;
5580 tstate->curexc_type = 0;
5581 tstate->curexc_value = 0;
5582 tstate->curexc_traceback = 0;
5583 PyErr_NormalizeException(type, value, tb);
5584 if (PyErr_Occurred())
5589 tmp_type = tstate->exc_type;
5590 tmp_value = tstate->exc_value;
5591 tmp_tb = tstate->exc_traceback;
5592 tstate->exc_type = *type;
5593 tstate->exc_value = *value;
5594 tstate->exc_traceback = *tb;
5595 /* Make sure tstate is in a consistent state when we XDECREF
5596 these objects (XDECREF may run arbitrary code). */
5597 Py_XDECREF(tmp_type);
5598 Py_XDECREF(tmp_value);
5610 #------------------------------------------------------------------------------------
5612 reset_exception_utility_code = UtilityCode(
5614 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5615 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5618 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5619 PyThreadState *tstate = PyThreadState_GET();
5620 *type = tstate->exc_type;
5621 *value = tstate->exc_value;
5622 *tb = tstate->exc_traceback;
5628 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5629 PyObject *tmp_type, *tmp_value, *tmp_tb;
5630 PyThreadState *tstate = PyThreadState_GET();
5631 tmp_type = tstate->exc_type;
5632 tmp_value = tstate->exc_value;
5633 tmp_tb = tstate->exc_traceback;
5634 tstate->exc_type = type;
5635 tstate->exc_value = value;
5636 tstate->exc_traceback = tb;
5637 Py_XDECREF(tmp_type);
5638 Py_XDECREF(tmp_value);
5643 #------------------------------------------------------------------------------------
5645 force_init_threads_utility_code = UtilityCode(
5647 #ifndef __PYX_FORCE_INIT_THREADS
5648 #if PY_VERSION_HEX < 0x02040200
5649 #define __PYX_FORCE_INIT_THREADS 1
5651 #define __PYX_FORCE_INIT_THREADS 0
5656 #------------------------------------------------------------------------------------