2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
136 def _gil_check(self, env):
141 error(self.pos, "%s not allowed without gil" % self.gil_message)
143 def clone_node(self):
144 """Clone the node. This is defined as a shallow copy, except for member lists
145 amongst the child attributes (from get_child_accessors) which are also
146 copied. Lists containing child nodes are thus seen as a way for the node
147 to hold multiple children directly; the list is not treated as a seperate
148 level in the tree."""
149 result = copy.copy(self)
150 for attrname in result.child_attrs:
151 value = getattr(result, attrname)
152 if isinstance(value, list):
153 setattr(result, attrname, [x for x in value])
158 # There are 4 phases of parse tree processing, applied in order to
159 # all the statements in a given scope-block:
161 # (0) analyse_control_flow
162 # Create the control flow tree into which state can be asserted and
165 # (1) analyse_declarations
166 # Make symbol table entries for all declarations at the current
167 # level, both explicit (def, cdef, etc.) and implicit (assignment
168 # to an otherwise undeclared name).
170 # (2) analyse_expressions
171 # Determine the result types of expressions and fill in the
172 # 'type' attribute of each ExprNode. Insert coercion nodes into the
173 # tree where needed to convert to and from Python objects.
174 # Allocate temporary locals for intermediate results. Fill
175 # in the 'result_code' attribute of each ExprNode with a C code
179 # Emit C code for all declarations, statements and expressions.
180 # Recursively applies the 3 processing phases to the bodies of
184 def analyse_control_flow(self, env):
187 def analyse_declarations(self, env):
190 def analyse_expressions(self, env):
191 raise InternalError("analyse_expressions not implemented for %s" % \
192 self.__class__.__name__)
194 def generate_code(self, code):
195 raise InternalError("generate_code not implemented for %s" % \
196 self.__class__.__name__)
198 def annotate(self, code):
199 # mro does the wrong thing
200 if isinstance(self, BlockNode):
201 self.body.annotate(code)
206 except AttributeError:
208 if not self.child_attrs:
211 for attr in self.child_attrs:
212 child = getattr(self, attr)
213 # Sometimes lists, sometimes nodes
216 elif isinstance(child, list):
218 pos = max(pos, c.end_pos())
220 pos = max(pos, child.end_pos())
224 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
226 return "<...nesting level cutoff...>"
227 if encountered is None:
229 if id(self) in encountered:
230 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
231 encountered.add(id(self))
233 def dump_child(x, level):
234 if isinstance(x, Node):
235 return x.dump(level, filter_out, cutoff-1, encountered)
236 elif isinstance(x, list):
237 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
242 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
244 return "<%s (%d)>" % (self.__class__.__name__, id(self))
247 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
248 for key, value in attrs:
249 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
250 res += "%s>" % indent
253 class CompilerDirectivesNode(Node):
255 Sets compiler directives for the children nodes
257 # directives {string:value} A dictionary holding the right value for
258 # *all* possible directives.
260 child_attrs = ["body"]
262 def analyse_control_flow(self, env):
264 env.directives = self.directives
265 self.body.analyse_control_flow(env)
268 def analyse_declarations(self, env):
270 env.directives = self.directives
271 self.body.analyse_declarations(env)
274 def analyse_expressions(self, env):
276 env.directives = self.directives
277 self.body.analyse_expressions(env)
280 def generate_function_definitions(self, env, code):
281 env_old = env.directives
282 code_old = code.globalstate.directives
283 code.globalstate.directives = self.directives
284 self.body.generate_function_definitions(env, code)
285 env.directives = env_old
286 code.globalstate.directives = code_old
288 def generate_execution_code(self, code):
289 old = code.globalstate.directives
290 code.globalstate.directives = self.directives
291 self.body.generate_execution_code(code)
292 code.globalstate.directives = old
294 def annotate(self, code):
295 old = code.globalstate.directives
296 code.globalstate.directives = self.directives
297 self.body.annotate(code)
298 code.globalstate.directives = old
300 class BlockNode(object):
301 # Mixin class for nodes representing a declaration block.
303 def generate_cached_builtins_decls(self, env, code):
304 entries = env.global_scope().undeclared_cached_builtins
305 for entry in entries:
306 code.globalstate.add_cached_builtin_decl(entry)
310 class StatListNode(Node):
311 # stats a list of StatNode
313 child_attrs = ["stats"]
315 def create_analysed(pos, env, *args, **kw):
316 node = StatListNode(pos, *args, **kw)
317 return node # No node-specific analysis necesarry
318 create_analysed = staticmethod(create_analysed)
320 def analyse_control_flow(self, env):
321 for stat in self.stats:
322 stat.analyse_control_flow(env)
324 def analyse_declarations(self, env):
325 #print "StatListNode.analyse_declarations" ###
326 for stat in self.stats:
327 stat.analyse_declarations(env)
329 def analyse_expressions(self, env):
330 #print "StatListNode.analyse_expressions" ###
331 for stat in self.stats:
332 stat.analyse_expressions(env)
334 def generate_function_definitions(self, env, code):
335 #print "StatListNode.generate_function_definitions" ###
336 for stat in self.stats:
337 stat.generate_function_definitions(env, code)
339 def generate_execution_code(self, code):
340 #print "StatListNode.generate_execution_code" ###
341 for stat in self.stats:
342 code.mark_pos(stat.pos)
343 stat.generate_execution_code(code)
345 def annotate(self, code):
346 for stat in self.stats:
350 class StatNode(Node):
352 # Code generation for statements is split into the following subphases:
354 # (1) generate_function_definitions
355 # Emit C code for the definitions of any structs,
356 # unions, enums and functions defined in the current
359 # (2) generate_execution_code
360 # Emit C code for executable statements.
363 def generate_function_definitions(self, env, code):
366 def generate_execution_code(self, code):
367 raise InternalError("generate_execution_code not implemented for %s" % \
368 self.__class__.__name__)
371 class CDefExternNode(StatNode):
372 # include_file string or None
375 child_attrs = ["body"]
377 def analyse_declarations(self, env):
378 if self.include_file:
379 env.add_include_file(self.include_file)
380 old_cinclude_flag = env.in_cinclude
382 self.body.analyse_declarations(env)
383 env.in_cinclude = old_cinclude_flag
385 def analyse_expressions(self, env):
388 def generate_execution_code(self, code):
391 def annotate(self, code):
392 self.body.annotate(code)
395 class CDeclaratorNode(Node):
396 # Part of a C declaration.
398 # Processing during analyse_declarations phase:
401 # Returns (name, type) pair where name is the
402 # CNameDeclaratorNode of the name being declared
403 # and type is the type it is being declared as.
405 # calling_convention string Calling convention of CFuncDeclaratorNode
406 # for which this is a base
410 calling_convention = ""
413 class CNameDeclaratorNode(CDeclaratorNode):
414 # name string The Pyrex name being declared
415 # cname string or None C name, if specified
416 # default ExprNode or None the value assigned on declaration
418 child_attrs = ['default']
422 def analyse(self, base_type, env, nonempty = 0):
423 if nonempty and self.name == '':
424 # May have mistaken the name for the type.
425 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
426 error(self.pos, "Missing argument name")
427 elif base_type.is_void:
428 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
430 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
431 base_type = py_object_type
432 self.type = base_type
433 return self, base_type
435 class CPtrDeclaratorNode(CDeclaratorNode):
436 # base CDeclaratorNode
438 child_attrs = ["base"]
440 def analyse(self, base_type, env, nonempty = 0):
441 if base_type.is_pyobject:
443 "Pointer base type cannot be a Python object")
444 ptr_type = PyrexTypes.c_ptr_type(base_type)
445 return self.base.analyse(ptr_type, env, nonempty = nonempty)
447 class CArrayDeclaratorNode(CDeclaratorNode):
448 # base CDeclaratorNode
451 child_attrs = ["base", "dimension"]
453 def analyse(self, base_type, env, nonempty = 0):
455 self.dimension.analyse_const_expression(env)
456 if not self.dimension.type.is_int:
457 error(self.dimension.pos, "Array dimension not integer")
458 size = self.dimension.get_constant_result_code()
466 if not base_type.is_complete():
468 "Array element type '%s' is incomplete" % base_type)
469 if base_type.is_pyobject:
471 "Array element cannot be a Python object")
472 if base_type.is_cfunction:
474 "Array element cannot be a function")
475 array_type = PyrexTypes.c_array_type(base_type, size)
476 return self.base.analyse(array_type, env, nonempty = nonempty)
479 class CFuncDeclaratorNode(CDeclaratorNode):
480 # base CDeclaratorNode
481 # args [CArgDeclNode]
482 # has_varargs boolean
483 # exception_value ConstNode
484 # exception_check boolean True if PyErr_Occurred check needed
485 # nogil boolean Can be called without gil
486 # with_gil boolean Acquire gil around function body
488 child_attrs = ["base", "args", "exception_value"]
491 optional_arg_count = 0
493 def analyse(self, return_type, env, nonempty = 0):
497 for arg_node in self.args:
498 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
499 name = name_declarator.name
500 if name_declarator.cname:
502 "Function argument cannot have C name specification")
503 # Turn *[] argument into **
505 type = PyrexTypes.c_ptr_type(type.base_type)
506 # Catch attempted C-style func(void) decl
508 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
509 func_type_args.append(
510 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
512 self.optional_arg_count += 1
513 elif self.optional_arg_count:
514 error(self.pos, "Non-default argument follows default argument")
516 if self.optional_arg_count:
517 scope = StructOrUnionScope()
518 arg_count_member = '%sn' % Naming.pyrex_prefix
519 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
520 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
521 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
522 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
523 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
528 cname = struct_cname)
529 self.op_args_struct.defined_in_pxd = 1
530 self.op_args_struct.used = 1
534 if return_type.is_pyobject \
535 and (self.exception_value or self.exception_check) \
536 and self.exception_check != '+':
538 "Exception clause not allowed for function returning Python object")
540 if self.exception_value:
541 self.exception_value.analyse_const_expression(env)
542 exc_val = self.exception_value.get_constant_result_code()
543 if self.exception_check == '+':
544 exc_val_type = self.exception_value.type
545 env.add_include_file('stdexcept')
546 if not exc_val_type.is_error and \
547 not exc_val_type.is_pyobject and \
548 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
549 error(self.exception_value.pos,
550 "Exception value must be a Python exception or cdef function with no arguments.")
552 if not return_type.assignable_from(self.exception_value.type):
553 error(self.exception_value.pos,
554 "Exception value incompatible with function return type")
555 exc_check = self.exception_check
556 if return_type.is_array:
558 "Function cannot return an array")
559 if return_type.is_cfunction:
561 "Function cannot return a function")
562 func_type = PyrexTypes.CFuncType(
563 return_type, func_type_args, self.has_varargs,
564 optional_arg_count = self.optional_arg_count,
565 exception_value = exc_val, exception_check = exc_check,
566 calling_convention = self.base.calling_convention,
567 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
568 if self.optional_arg_count:
569 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
570 return self.base.analyse(func_type, env)
573 class CArgDeclNode(Node):
574 # Item in a function declaration argument list.
576 # base_type CBaseTypeNode
577 # declarator CDeclaratorNode
578 # not_none boolean Tagged with 'not None'
579 # default ExprNode or None
580 # default_value PyObjectConst constant for default value
581 # is_self_arg boolean Is the "self" arg of an extension type method
582 # is_kw_only boolean Is a keyword-only argument
584 child_attrs = ["base_type", "declarator", "default"]
589 name_declarator = None
592 def analyse(self, env, nonempty = 0):
593 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
594 if self.type is None:
595 # The parser may missinterpret names as types...
597 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
599 self.declarator.name = self.base_type.name
600 self.base_type.name = None
601 self.base_type.is_basic_c_type = False
604 could_be_name = False
605 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
606 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
607 self.declarator.name = self.base_type.arg_name
608 return self.declarator.analyse(base_type, env, nonempty = nonempty)
610 return self.name_declarator, self.type
612 def calculate_default_value_code(self, code):
613 if self.default_value is None:
615 if self.default.is_literal:
616 # will not output any code, just assign the result_code
617 self.default.generate_evaluation_code(code)
618 return self.type.cast_code(self.default.result())
619 self.default_value = code.get_argument_default_const(self.type)
620 return self.default_value
622 def annotate(self, code):
624 self.default.annotate(code)
627 class CBaseTypeNode(Node):
628 # Abstract base class for C base type nodes.
630 # Processing during analyse_declarations phase:
637 class CAnalysedBaseTypeNode(Node):
642 def analyse(self, env, could_be_name = False):
645 class CSimpleBaseTypeNode(CBaseTypeNode):
647 # module_path [string] Qualifying name components
648 # is_basic_c_type boolean
651 # is_self_arg boolean Is self argument of C method
654 arg_name = None # in case the argument name was interpreted as a type
656 def analyse(self, env, could_be_name = False):
657 # Return type descriptor.
658 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
660 if self.is_basic_c_type:
661 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
663 error(self.pos, "Unrecognised type modifier combination")
664 elif self.name == "object" and not self.module_path:
665 type = py_object_type
666 elif self.name is None:
667 if self.is_self_arg and env.is_c_class_scope:
668 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
669 type = env.parent_type
671 type = py_object_type
674 scope = env.find_imported_module(self.module_path, self.pos)
678 if scope.is_c_class_scope:
679 scope = scope.global_scope()
680 entry = scope.lookup(self.name)
681 if entry and entry.is_type:
684 if self.is_self_arg and env.is_c_class_scope:
685 type = env.parent_type
687 type = py_object_type
688 self.arg_name = self.name
690 error(self.pos, "'%s' is not a type identifier" % self.name)
694 return PyrexTypes.error_type
696 class CBufferAccessTypeNode(CBaseTypeNode):
698 # positional_args [ExprNode] List of positional arguments
699 # keyword_args DictNode Keyword arguments
700 # base_type_node CBaseTypeNode
703 # type PyrexType.BufferType ...containing the right options
706 child_attrs = ["base_type_node", "positional_args",
707 "keyword_args", "dtype_node"]
713 def analyse(self, env, could_be_name = False):
714 base_type = self.base_type_node.analyse(env)
715 if base_type.is_error: return base_type
718 options = Buffer.analyse_buffer_options(
721 self.positional_args,
723 base_type.buffer_defaults)
725 self.type = PyrexTypes.BufferType(base_type, **options)
728 class CComplexBaseTypeNode(CBaseTypeNode):
729 # base_type CBaseTypeNode
730 # declarator CDeclaratorNode
732 child_attrs = ["base_type", "declarator"]
734 def analyse(self, env, could_be_name = False):
735 base = self.base_type.analyse(env, could_be_name)
736 _, type = self.declarator.analyse(base, env)
740 class CVarDefNode(StatNode):
741 # C variable definition or forward/extern function declaration.
743 # visibility 'private' or 'public' or 'extern'
744 # base_type CBaseTypeNode
745 # declarators [CDeclaratorNode]
748 # need_properties [entry]
750 # decorators [cython.locals(...)] or None
751 # directive_locals { string : NameNode } locals defined by cython.locals(...)
753 child_attrs = ["base_type", "declarators"]
757 directive_locals = {}
759 def analyse_declarations(self, env, dest_scope = None):
762 self.dest_scope = dest_scope
763 base_type = self.base_type.analyse(env)
764 if (dest_scope.is_c_class_scope
765 and self.visibility == 'public'
766 and base_type.is_pyobject
767 and (base_type.is_builtin_type or base_type.is_extension_type)):
768 self.need_properties = []
770 visibility = 'private'
772 need_property = False
773 visibility = self.visibility
775 for declarator in self.declarators:
776 name_declarator, type = declarator.analyse(base_type, env)
777 if not type.is_complete():
778 if not (self.visibility == 'extern' and type.is_array):
779 error(declarator.pos,
780 "Variable type '%s' is incomplete" % type)
781 if self.visibility == 'extern' and type.is_pyobject:
782 error(declarator.pos,
783 "Python object cannot be declared extern")
784 name = name_declarator.name
785 cname = name_declarator.cname
787 error(declarator.pos, "Missing name in declaration.")
789 if type.is_cfunction:
790 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
791 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
793 if entry is not None:
794 entry.directive_locals = self.directive_locals
796 if self.directive_locals:
797 s.error("Decorators can only be followed by functions")
798 if self.in_pxd and self.visibility != 'extern':
800 "Only 'extern' C variable declaration allowed in .pxd file")
801 entry = dest_scope.declare_var(name, type, declarator.pos,
802 cname = cname, visibility = visibility, is_cdef = 1)
804 self.need_properties.append(entry)
805 entry.needs_property = 1
808 class CStructOrUnionDefNode(StatNode):
810 # cname string or None
811 # kind "struct" or "union"
812 # typedef_flag boolean
813 # visibility "public" or "private"
815 # attributes [CVarDefNode] or None
818 child_attrs = ["attributes"]
820 def analyse_declarations(self, env):
822 if self.attributes is not None:
823 scope = StructOrUnionScope(self.name)
824 self.entry = env.declare_struct_or_union(
825 self.name, self.kind, scope, self.typedef_flag, self.pos,
826 self.cname, visibility = self.visibility)
827 if self.attributes is not None:
828 if self.in_pxd and not env.in_cinclude:
829 self.entry.defined_in_pxd = 1
830 for attr in self.attributes:
831 attr.analyse_declarations(env, scope)
832 if self.visibility != 'extern':
833 need_typedef_indirection = False
834 for attr in scope.var_entries:
837 type = type.base_type
838 if type == self.entry.type:
839 error(attr.pos, "Struct cannot contain itself as a member.")
840 if self.typedef_flag:
842 type = type.base_type
843 if type == self.entry.type:
844 need_typedef_indirection = True
845 if need_typedef_indirection:
846 # C can't handle typedef structs that refer to themselves.
847 struct_entry = self.entry
848 self.entry = env.declare_typedef(
849 self.name, struct_entry.type, self.pos,
850 cname = self.cname, visibility='ignore')
851 struct_entry.type.typedef_flag = False
852 # FIXME: this might be considered a hack ;-)
853 struct_entry.cname = struct_entry.type.cname = '_' + self.cname
855 def analyse_expressions(self, env):
858 def generate_execution_code(self, code):
862 class CEnumDefNode(StatNode):
863 # name string or None
864 # cname string or None
865 # items [CEnumDefItemNode]
866 # typedef_flag boolean
867 # visibility "public" or "private"
871 child_attrs = ["items"]
873 def analyse_declarations(self, env):
874 self.entry = env.declare_enum(self.name, self.pos,
875 cname = self.cname, typedef_flag = self.typedef_flag,
876 visibility = self.visibility)
877 if self.items is not None:
878 if self.in_pxd and not env.in_cinclude:
879 self.entry.defined_in_pxd = 1
880 for item in self.items:
881 item.analyse_declarations(env, self.entry)
883 def analyse_expressions(self, env):
884 if self.visibility == 'public':
885 self.temp = env.allocate_temp_pyobject()
886 env.release_temp(self.temp)
888 def generate_execution_code(self, code):
889 if self.visibility == 'public':
890 for item in self.entry.enum_values:
891 code.putln("%s = PyInt_FromLong(%s); %s" % (
894 code.error_goto_if_null(self.temp, item.pos)))
895 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
899 code.error_goto(item.pos)))
900 code.putln("%s = 0;" % self.temp)
903 class CEnumDefItemNode(StatNode):
905 # cname string or None
906 # value ExprNode or None
908 child_attrs = ["value"]
910 def analyse_declarations(self, env, enum_entry):
912 self.value.analyse_const_expression(env)
913 if not self.value.type.is_int:
914 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
915 self.value.analyse_const_expression(env)
916 entry = env.declare_const(self.name, enum_entry.type,
917 self.value, self.pos, cname = self.cname,
918 visibility = enum_entry.visibility)
919 enum_entry.enum_values.append(entry)
922 class CTypeDefNode(StatNode):
923 # base_type CBaseTypeNode
924 # declarator CDeclaratorNode
925 # visibility "public" or "private"
928 child_attrs = ["base_type", "declarator"]
930 def analyse_declarations(self, env):
931 base = self.base_type.analyse(env)
932 name_declarator, type = self.declarator.analyse(base, env)
933 name = name_declarator.name
934 cname = name_declarator.cname
935 entry = env.declare_typedef(name, type, self.pos,
936 cname = cname, visibility = self.visibility)
937 if self.in_pxd and not env.in_cinclude:
938 entry.defined_in_pxd = 1
940 def analyse_expressions(self, env):
942 def generate_execution_code(self, code):
946 class FuncDefNode(StatNode, BlockNode):
947 # Base class for function definition nodes.
949 # return_type PyrexType
950 # #filename string C name of filename string const
952 # needs_closure boolean Whether or not this function has inner functions/classes/yield
953 # directive_locals { string : NameNode } locals defined by cython.locals(...)
957 needs_closure = False
959 def analyse_default_values(self, env):
960 genv = env.global_scope()
961 for arg in self.args:
964 arg.default.analyse_types(env)
965 arg.default = arg.default.coerce_to(arg.type, genv)
966 arg.default.allocate_temps(genv)
969 "This argument cannot have a default value")
972 def need_gil_acquisition(self, lenv):
975 def create_local_scope(self, env):
977 while env.is_py_class_scope or env.is_c_class_scope:
978 env = env.outer_scope
979 if self.needs_closure:
980 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
982 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
983 lenv.return_type = self.return_type
984 type = self.entry.type
985 if type.is_cfunction:
986 lenv.nogil = type.nogil and not type.with_gil
987 self.local_scope = lenv
990 def generate_function_definitions(self, env, code):
993 lenv = self.local_scope
995 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
996 self.entry.scope.is_c_class_scope)
998 # Generate C code for header and body of function
999 code.enter_cfunc_scope()
1000 code.return_from_error_cleanup_label = code.new_label()
1002 # ----- Top-level constants used by this function
1003 code.mark_pos(self.pos)
1004 self.generate_cached_builtins_decls(lenv, code)
1005 # ----- Function header
1008 self.py_func.generate_function_header(code,
1009 with_pymethdef = env.is_py_class_scope,
1011 self.generate_function_header(code,
1012 with_pymethdef = env.is_py_class_scope)
1013 # ----- Local variable declarations
1014 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1015 self.generate_argument_declarations(lenv, code)
1016 if self.needs_closure:
1017 code.putln("/* TODO: declare and create scope object */")
1018 code.put_var_declarations(lenv.var_entries)
1020 if not self.return_type.is_void:
1021 if self.return_type.is_pyobject:
1025 (self.return_type.declaration_code(
1026 Naming.retval_cname),
1028 tempvardecl_code = code.insertion_point()
1029 self.generate_keyword_list(code)
1030 # ----- Extern library function declarations
1031 lenv.generate_library_function_declarations(code)
1032 # ----- GIL acquisition
1033 acquire_gil = self.need_gil_acquisition(lenv)
1035 env.use_utility_code(force_init_threads_utility_code)
1036 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1037 # ----- Automatic lead-ins for certain special functions
1039 code.put_setup_refcount_context(self.entry.name)
1040 if is_getbuffer_slot:
1041 self.getbuffer_init(code)
1042 # ----- Fetch arguments
1043 self.generate_argument_parsing_code(env, code)
1044 # If an argument is assigned to in the body, we must
1045 # incref it to properly keep track of refcounts.
1046 for entry in lenv.arg_entries:
1047 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1048 code.put_var_incref(entry)
1049 # ----- Initialise local variables
1050 for entry in lenv.var_entries:
1051 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1052 code.put_init_var_to_py_none(entry)
1053 # ----- Initialise local buffer auxiliary variables
1054 for entry in lenv.var_entries + lenv.arg_entries:
1055 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1056 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1057 # ----- Check and convert arguments
1058 self.generate_argument_type_tests(code)
1059 # ----- Acquire buffer arguments
1060 for entry in lenv.arg_entries:
1061 if entry.type.is_buffer:
1062 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1063 # ----- Function body
1064 self.body.generate_execution_code(code)
1065 # ----- Default return value
1067 if self.return_type.is_pyobject:
1068 #if self.return_type.is_extension_type:
1069 # lhs = "(PyObject *)%s" % Naming.retval_cname
1071 lhs = Naming.retval_cname
1072 code.put_init_to_py_none(lhs, self.return_type)
1074 val = self.return_type.default_value
1076 code.putln("%s = %s;" % (Naming.retval_cname, val))
1077 # ----- Error cleanup
1078 if code.error_label in code.labels_used:
1079 code.put_goto(code.return_label)
1080 code.put_label(code.error_label)
1081 # cleanup temps the old way
1082 code.put_var_xdecrefs(lenv.temp_entries)
1083 # cleanup temps the new way
1084 for cname, type in code.funcstate.all_managed_temps():
1085 code.put_xdecref(cname, type)
1087 # Clean up buffers -- this calls a Python function
1088 # so need to save and restore error state
1089 buffers_present = len(lenv.buffer_entries) > 0
1091 code.globalstate.use_utility_code(restore_exception_utility_code)
1092 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1093 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1094 for entry in lenv.buffer_entries:
1095 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1096 #code.putln("%s = 0;" % entry.cname)
1097 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1099 err_val = self.error_value()
1100 exc_check = self.caller_will_check_exceptions()
1101 if err_val is not None or exc_check:
1102 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1104 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1105 % self.entry.qualified_name, 0)
1107 '__Pyx_WriteUnraisable("%s");' %
1108 self.entry.qualified_name)
1109 env.use_utility_code(unraisable_exception_utility_code)
1110 env.use_utility_code(restore_exception_utility_code)
1111 default_retval = self.return_type.default_value
1112 if err_val is None and default_retval:
1113 err_val = default_retval
1114 if err_val is not None:
1117 Naming.retval_cname,
1120 if is_getbuffer_slot:
1121 self.getbuffer_error_cleanup(code)
1123 # If we are using the non-error cleanup section we should
1124 # jump past it if we have an error. The if-test below determine
1125 # whether this section is used.
1126 if buffers_present or is_getbuffer_slot:
1127 code.put_goto(code.return_from_error_cleanup_label)
1130 # ----- Non-error return cleanup
1131 # If you add anything here, remember to add a condition to the
1132 # if-test above in the error block (so that it can jump past this
1134 code.put_label(code.return_label)
1135 for entry in lenv.buffer_entries:
1137 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1138 if is_getbuffer_slot:
1139 self.getbuffer_normal_cleanup(code)
1140 # ----- Return cleanup for both error and no-error return
1141 code.put_label(code.return_from_error_cleanup_label)
1142 if not Options.init_local_none:
1143 for entry in lenv.var_entries:
1144 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1145 entry.xdecref_cleanup = 1
1146 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1147 # Decref any increfed args
1148 for entry in lenv.arg_entries:
1149 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1150 code.put_var_decref(entry)
1152 # code.putln("/* TODO: decref scope object */")
1154 # This code is duplicated in ModuleNode.generate_module_init_func
1156 default_retval = self.return_type.default_value
1157 err_val = self.error_value()
1158 if err_val is None and default_retval:
1159 err_val = default_retval
1160 if self.return_type.is_pyobject:
1161 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1163 code.put_finish_refcount_context()
1166 code.putln("PyGILState_Release(_save);")
1168 if not self.return_type.is_void:
1169 code.putln("return %s;" % Naming.retval_cname)
1172 # ----- Go back and insert temp variable declarations
1173 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1174 tempvardecl_code.put_temp_declarations(code.funcstate)
1175 # ----- Python version
1176 code.exit_cfunc_scope()
1178 self.py_func.generate_function_definitions(env, code)
1179 self.generate_wrapper_functions(code)
1181 def declare_argument(self, env, arg):
1182 if arg.type.is_void:
1183 error(arg.pos, "Invalid use of 'void'")
1184 elif not arg.type.is_complete() and not arg.type.is_array:
1186 "Argument type '%s' is incomplete" % arg.type)
1187 return env.declare_arg(arg.name, arg.type, arg.pos)
1189 def generate_wrapper_functions(self, code):
1192 def generate_execution_code(self, code):
1193 # Evaluate and store argument default values
1194 for arg in self.args:
1195 default = arg.default
1197 if not default.is_literal:
1198 default.generate_evaluation_code(code)
1199 default.make_owned_reference(code)
1200 result = default.result_as(arg.type)
1203 arg.calculate_default_value_code(code),
1205 if arg.type.is_pyobject:
1206 code.put_giveref(default.result())
1207 default.generate_post_assignment_code(code)
1208 default.free_temps(code)
1209 # For Python class methods, create and store function object
1211 self.assmt.generate_execution_code(code)
1214 # Special code for the __getbuffer__ function
1216 def getbuffer_init(self, code):
1217 info = self.local_scope.arg_entries[1].cname
1218 # Python 3.0 betas have a bug in memoryview which makes it call
1219 # getbuffer with a NULL parameter. For now we work around this;
1220 # the following line should be removed when this bug is fixed.
1221 code.putln("if (%s == NULL) return 0;" % info)
1222 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1223 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1225 def getbuffer_error_cleanup(self, code):
1226 info = self.local_scope.arg_entries[1].cname
1227 code.put_gotref("%s->obj" % info)
1228 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1231 def getbuffer_normal_cleanup(self, code):
1232 info = self.local_scope.arg_entries[1].cname
1233 code.putln("if (%s->obj == Py_None) {" % info)
1234 code.put_gotref("Py_None")
1235 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1238 class CFuncDefNode(FuncDefNode):
1239 # C function definition.
1241 # modifiers ['inline']
1242 # visibility 'private' or 'public' or 'extern'
1243 # base_type CBaseTypeNode
1244 # declarator CDeclaratorNode
1247 # decorators [DecoratorNode] list of decorators
1249 # with_gil boolean Acquire GIL around body
1251 # py_func wrapper for calling from Python
1252 # overridable whether or not this is a cpdef function
1253 # inline_in_pxd whether this is an inline function in a pxd file
1255 child_attrs = ["base_type", "declarator", "body", "py_func"]
1257 inline_in_pxd = False
1259 directive_locals = {}
1261 def unqualified_name(self):
1262 return self.entry.name
1264 def analyse_declarations(self, env):
1265 if 'locals' in env.directives and env.directives['locals']:
1266 self.directive_locals = env.directives['locals']
1267 directive_locals = self.directive_locals
1268 base_type = self.base_type.analyse(env)
1269 # The 2 here is because we need both function and argument names.
1270 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1271 if not type.is_cfunction:
1273 "Suite attached to non-function declaration")
1274 # Remember the actual type according to the function header
1275 # written here, because the type in the symbol table entry
1276 # may be different if we're overriding a C method inherited
1277 # from the base type of an extension type.
1279 type.is_overridable = self.overridable
1280 declarator = self.declarator
1281 while not hasattr(declarator, 'args'):
1282 declarator = declarator.base
1283 self.args = declarator.args
1284 for formal_arg, type_arg in zip(self.args, type.args):
1285 formal_arg.type = type_arg.type
1286 formal_arg.name = type_arg.name
1287 formal_arg.cname = type_arg.cname
1288 name = name_declarator.name
1289 cname = name_declarator.cname
1290 self.entry = env.declare_cfunction(
1291 name, type, self.pos,
1292 cname = cname, visibility = self.visibility,
1293 defining = self.body is not None,
1294 api = self.api, modifiers = self.modifiers)
1295 self.entry.inline_func_in_pxd = self.inline_in_pxd
1296 self.return_type = type.return_type
1298 if self.overridable and not env.is_module_scope:
1299 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1300 # An error will be produced in the cdef function
1301 self.overridable = False
1303 if self.overridable:
1305 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1306 self.py_func = DefNode(pos = self.pos,
1307 name = self.entry.name,
1310 starstar_arg = None,
1312 body = py_func_body,
1314 self.py_func.is_module_scope = env.is_module_scope
1315 self.py_func.analyse_declarations(env)
1316 self.entry.as_variable = self.py_func.entry
1317 # Reset scope entry the above cfunction
1318 env.entries[name] = self.entry
1319 if not env.is_module_scope or Options.lookup_module_cpdef:
1320 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1321 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1323 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1325 args = self.type.args
1326 if omit_optional_args:
1327 args = args[:len(args) - self.type.optional_arg_count]
1328 arg_names = [arg.name for arg in args]
1330 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1332 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1333 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1334 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1335 c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1336 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1338 def declare_arguments(self, env):
1339 for arg in self.type.args:
1341 error(arg.pos, "Missing argument name")
1342 self.declare_argument(env, arg)
1344 def need_gil_acquisition(self, lenv):
1345 return self.type.with_gil
1347 def gil_check(self, env):
1349 with_gil = type.with_gil
1350 if type.nogil and not with_gil:
1351 if type.return_type.is_pyobject:
1353 "Function with Python return type cannot be declared nogil")
1354 for entry in env.var_entries + env.temp_entries:
1355 if entry.type.is_pyobject:
1356 error(self.pos, "Function declared nogil has Python locals or temporaries")
1358 def analyse_expressions(self, env):
1359 self.local_scope.directives = env.directives
1360 if self.py_func is not None:
1361 # this will also analyse the default values
1362 self.py_func.analyse_expressions(env)
1364 self.analyse_default_values(env)
1366 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1369 visibility = self.entry.visibility
1370 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1371 arg_decls.append(arg.declaration_code())
1372 if with_dispatch and self.overridable:
1373 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1374 if type.optional_arg_count and with_opt_args:
1375 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1376 if type.has_varargs:
1377 arg_decls.append("...")
1379 arg_decls = ["void"]
1381 cname = self.entry.func_cname
1382 entity = type.function_header_code(cname, ', '.join(arg_decls))
1383 if visibility == 'public':
1384 dll_linkage = "DL_EXPORT"
1387 header = self.return_type.declaration_code(entity,
1388 dll_linkage = dll_linkage)
1389 if visibility == 'extern':
1390 storage_class = "%s " % Naming.extern_c_macro
1391 elif visibility == 'public':
1394 storage_class = "static "
1395 code.putln("%s%s %s {" % (
1397 ' '.join(self.modifiers).upper(), # macro forms
1400 def generate_argument_declarations(self, env, code):
1401 for arg in self.args:
1403 result = arg.calculate_default_value_code(code)
1404 code.putln('%s = %s;' % (
1405 arg.type.declaration_code(arg.cname), result))
1407 def generate_keyword_list(self, code):
1410 def generate_argument_parsing_code(self, env, code):
1412 if self.type.optional_arg_count:
1413 code.putln('if (%s) {' % Naming.optional_args_cname)
1414 for arg in self.args:
1416 # FIXME: simple name prefixing doesn't work when
1417 # argument name mangling is in place
1418 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1419 declarator = arg.declarator
1420 while not hasattr(declarator, 'name'):
1421 declarator = declarator.base
1422 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1424 for _ in range(self.type.optional_arg_count):
1428 def generate_argument_conversion_code(self, code):
1431 def generate_argument_type_tests(self, code):
1432 # Generate type tests for args whose type in a parent
1433 # class is a supertype of the declared type.
1434 for arg in self.type.args:
1435 if arg.needs_type_test:
1436 self.generate_arg_type_test(arg, code)
1438 def generate_arg_type_test(self, arg, code):
1439 # Generate type test for one argument.
1440 if arg.type.typeobj_is_available():
1441 typeptr_cname = arg.type.typeptr_cname
1442 arg_code = "((PyObject *)%s)" % arg.cname
1444 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1449 type.is_builtin_type,
1450 code.error_goto(arg.pos)))
1452 error(arg.pos, "Cannot test type of extern C class "
1453 "without type object name specification")
1455 def error_value(self):
1456 if self.return_type.is_pyobject:
1460 return self.entry.type.exception_value
1462 def caller_will_check_exceptions(self):
1463 return self.entry.type.exception_check
1465 def generate_wrapper_functions(self, code):
1466 # If the C signature of a function has changed, we need to generate
1467 # wrappers to put in the slots here.
1470 func_type = entry.type
1471 while entry.prev_entry is not None:
1473 entry = entry.prev_entry
1474 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1476 self.generate_function_header(code,
1478 with_dispatch = entry.type.is_overridable,
1479 with_opt_args = entry.type.optional_arg_count,
1480 cname = entry.func_cname)
1481 if not self.return_type.is_void:
1483 args = self.type.args
1484 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1485 if entry.type.is_overridable:
1486 arglist.append(Naming.skip_dispatch_cname)
1487 elif func_type.is_overridable:
1489 if entry.type.optional_arg_count:
1490 arglist.append(Naming.optional_args_cname)
1491 elif func_type.optional_arg_count:
1492 arglist.append('NULL')
1493 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1497 class PyArgDeclNode(Node):
1498 # Argument which must be a Python object (used
1499 # for * and ** arguments).
1502 # entry Symtab.Entry
1506 class DecoratorNode(Node):
1509 # decorator NameNode or CallNode
1510 child_attrs = ['decorator']
1513 class DefNode(FuncDefNode):
1514 # A Python function definition.
1516 # name string the Python name of the function
1517 # decorators [DecoratorNode] list of decorators
1518 # args [CArgDeclNode] formal arguments
1519 # star_arg PyArgDeclNode or None * argument
1520 # starstar_arg PyArgDeclNode or None ** argument
1521 # doc EncodedString or None
1524 # The following subnode is constructed internally
1525 # when the def statement is inside a Python class definition.
1527 # assmt AssignmentNode Function construction/assignment
1529 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1533 num_required_kw_args = 0
1534 reqd_kw_flags_cname = "0"
1540 def __init__(self, pos, **kwds):
1541 FuncDefNode.__init__(self, pos, **kwds)
1543 for arg in self.args:
1550 self.num_kwonly_args = k
1551 self.num_required_kw_args = rk
1552 self.num_required_args = r
1554 def as_cfunction(self, cfunc=None, scope=None):
1556 error(self.star_arg.pos, "cdef function cannot have star argument")
1557 if self.starstar_arg:
1558 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1561 for formal_arg in self.args:
1562 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1563 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1565 type = py_object_type,
1566 pos = formal_arg.pos))
1567 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1569 has_varargs = False,
1570 exception_value = None,
1571 exception_check = False,
1574 is_overridable = True)
1575 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1577 cfunc_type = cfunc.type
1578 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1579 error(self.pos, "wrong number of arguments")
1580 error(declarator.pos, "previous declaration here")
1581 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1582 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1583 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1584 formal_arg.type = type_arg.type
1585 formal_arg.name_declarator = name_declarator
1587 if cfunc_type.exception_value is None:
1588 exception_value = None
1590 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1591 declarator = CFuncDeclaratorNode(self.pos,
1592 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1594 has_varargs = False,
1595 exception_check = cfunc_type.exception_check,
1596 exception_value = exception_value,
1597 with_gil = cfunc_type.with_gil,
1598 nogil = cfunc_type.nogil)
1599 return CFuncDefNode(self.pos,
1601 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1602 declarator = declarator,
1605 overridable = cfunc_type.is_overridable,
1607 with_gil = cfunc_type.with_gil,
1608 nogil = cfunc_type.nogil,
1609 visibility = 'private',
1611 directive_locals = cfunc.directive_locals)
1613 def analyse_declarations(self, env):
1614 if 'locals' in env.directives:
1615 directive_locals = env.directives['locals']
1617 directive_locals = {}
1618 self.directive_locals = directive_locals
1619 for arg in self.args:
1620 if hasattr(arg, 'name'):
1622 name_declarator = None
1624 base_type = arg.base_type.analyse(env)
1625 name_declarator, type = \
1626 arg.declarator.analyse(base_type, env)
1627 arg.name = name_declarator.name
1628 if arg.name in directive_locals:
1629 type_node = directive_locals[arg.name]
1630 other_type = type_node.analyse_as_type(env)
1631 if other_type is None:
1632 error(type_node.pos, "Not a type")
1633 elif (type is not PyrexTypes.py_object_type
1634 and not type.same_as(other_type)):
1635 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1636 error(type_node.pos, "Previous declaration here")
1639 if name_declarator and name_declarator.cname:
1641 "Python function argument cannot have C name specification")
1642 arg.type = type.as_argument_type()
1644 arg.needs_conversion = 0
1645 arg.needs_type_test = 0
1647 if arg.not_none and not arg.type.is_extension_type:
1649 "Only extension type arguments can have 'not None'")
1650 self.declare_pyfunction(env)
1651 self.analyse_signature(env)
1652 self.return_type = self.entry.signature.return_type()
1654 def analyse_signature(self, env):
1655 any_type_tests_needed = 0
1656 # Use the simpler calling signature for zero- and one-argument functions.
1657 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1658 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1659 if len(self.args) == 0:
1660 self.entry.signature = TypeSlots.pyfunction_noargs
1661 elif len(self.args) == 1:
1662 if self.args[0].default is None and not self.args[0].kw_only:
1663 self.entry.signature = TypeSlots.pyfunction_onearg
1664 elif self.entry.signature is TypeSlots.pymethod_signature:
1665 if len(self.args) == 1:
1666 self.entry.signature = TypeSlots.unaryfunc
1667 elif len(self.args) == 2:
1668 if self.args[1].default is None and not self.args[1].kw_only:
1669 self.entry.signature = TypeSlots.ibinaryfunc
1670 elif self.entry.is_special:
1671 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1672 sig = self.entry.signature
1673 nfixed = sig.num_fixed_args()
1674 for i in range(nfixed):
1675 if i < len(self.args):
1678 if sig.is_self_arg(i):
1680 arg.hdr_type = arg.type = env.parent_type
1681 arg.needs_conversion = 0
1683 arg.hdr_type = sig.fixed_arg_type(i)
1684 if not arg.type.same_as(arg.hdr_type):
1685 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1686 arg.needs_type_test = 1
1687 any_type_tests_needed = 1
1689 arg.needs_conversion = 1
1690 if arg.needs_conversion:
1691 arg.hdr_cname = Naming.arg_prefix + arg.name
1693 arg.hdr_cname = Naming.var_prefix + arg.name
1695 self.bad_signature()
1697 if nfixed < len(self.args):
1698 if not sig.has_generic_args:
1699 self.bad_signature()
1700 for arg in self.args:
1701 if arg.is_generic and \
1702 (arg.type.is_extension_type or arg.type.is_builtin_type):
1703 arg.needs_type_test = 1
1704 any_type_tests_needed = 1
1705 if any_type_tests_needed:
1706 env.use_utility_code(arg_type_test_utility_code)
1708 def bad_signature(self):
1709 sig = self.entry.signature
1710 expected_str = "%d" % sig.num_fixed_args()
1711 if sig.has_generic_args:
1712 expected_str = expected_str + " or more"
1714 if name.startswith("__") and name.endswith("__"):
1715 desc = "Special method"
1719 "%s %s has wrong number of arguments "
1720 "(%d declared, %s expected)" % (
1721 desc, self.name, len(self.args), expected_str))
1723 def signature_has_nongeneric_args(self):
1724 argcount = len(self.args)
1725 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1729 def signature_has_generic_args(self):
1730 return self.entry.signature.has_generic_args
1732 def declare_pyfunction(self, env):
1733 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1735 entry = env.lookup_here(self.name)
1736 if entry and entry.type.is_cfunction and not self.is_wrapper:
1737 warning(self.pos, "Overriding cdef method with def method.", 5)
1738 entry = env.declare_pyfunction(self.name, self.pos)
1740 prefix = env.scope_prefix
1741 entry.func_cname = \
1742 Naming.pyfunc_prefix + prefix + name
1743 entry.pymethdef_cname = \
1744 Naming.pymethdef_prefix + prefix + name
1745 if Options.docstrings:
1746 entry.doc = embed_position(self.pos, self.doc)
1748 Naming.funcdoc_prefix + prefix + name
1752 def declare_arguments(self, env):
1753 for arg in self.args:
1755 error(arg.pos, "Missing argument name")
1756 if arg.needs_conversion:
1757 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1758 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1759 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1760 if arg.type.is_pyobject:
1761 arg.entry.init = "0"
1762 arg.entry.init_to_none = 0
1764 arg.entry = self.declare_argument(env, arg)
1766 arg.entry.is_self_arg = arg.is_self_arg
1768 if arg.is_self_arg or \
1769 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1770 arg.entry.is_declared_generic = 1
1771 self.declare_python_arg(env, self.star_arg)
1772 self.declare_python_arg(env, self.starstar_arg)
1774 def declare_python_arg(self, env, arg):
1776 entry = env.declare_var(arg.name,
1777 PyrexTypes.py_object_type, arg.pos)
1780 entry.init_to_none = 0
1781 entry.xdecref_cleanup = 1
1783 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1785 def analyse_expressions(self, env):
1786 self.local_scope.directives = env.directives
1787 self.analyse_default_values(env)
1788 if env.is_py_class_scope:
1789 self.synthesize_assignment_node(env)
1791 def synthesize_assignment_node(self, env):
1793 self.assmt = SingleAssignmentNode(self.pos,
1794 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1795 rhs = ExprNodes.UnboundMethodNode(self.pos,
1796 function = ExprNodes.PyCFunctionNode(self.pos,
1797 pymethdef_cname = self.entry.pymethdef_cname)))
1798 self.assmt.analyse_declarations(env)
1799 self.assmt.analyse_expressions(env)
1801 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1803 sig = self.entry.signature
1804 if sig.has_dummy_arg:
1805 arg_code_list.append(
1806 "PyObject *%s" % Naming.self_cname)
1807 for arg in self.args:
1808 if not arg.is_generic:
1810 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1812 arg_code_list.append(
1813 arg.hdr_type.declaration_code(arg.hdr_cname))
1814 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1815 arg_code_list.append("PyObject *unused")
1816 if sig.has_generic_args:
1817 arg_code_list.append(
1818 "PyObject *%s, PyObject *%s"
1819 % (Naming.args_cname, Naming.kwds_cname))
1820 arg_code = ", ".join(arg_code_list)
1821 dc = self.return_type.declaration_code(self.entry.func_cname)
1822 header = "static %s(%s)" % (dc, arg_code)
1823 code.putln("%s; /*proto*/" % header)
1826 if self.entry.doc and Options.docstrings:
1827 docstr = self.entry.doc
1828 if not isinstance(docstr, str):
1829 docstr = docstr.utf8encode()
1831 'static char %s[] = "%s";' % (
1832 self.entry.doc_cname,
1833 split_docstring(escape_byte_string(docstr))))
1836 "static PyMethodDef %s = " %
1837 self.entry.pymethdef_cname)
1838 code.put_pymethoddef(self.entry, ";")
1839 code.putln("%s {" % header)
1841 def generate_argument_declarations(self, env, code):
1842 for arg in self.args:
1843 if arg.is_generic: # or arg.needs_conversion:
1844 if arg.needs_conversion:
1845 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1847 code.put_var_declaration(arg.entry)
1849 def generate_keyword_list(self, code):
1850 if self.signature_has_generic_args() and \
1851 self.signature_has_nongeneric_args():
1853 "static PyObject **%s[] = {" %
1854 Naming.pykwdlist_cname)
1855 for arg in self.args:
1857 pystring_cname = code.intern_identifier(arg.name)
1858 code.put('&%s,' % pystring_cname)
1861 def generate_argument_parsing_code(self, env, code):
1862 # Generate PyArg_ParseTuple call for generic
1863 # arguments, if any.
1864 if self.entry.signature.has_dummy_arg:
1865 # get rid of unused argument warning
1866 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1868 old_error_label = code.new_error_label()
1869 our_error_label = code.error_label
1870 end_label = code.new_label("argument_unpacking_done")
1872 has_kwonly_args = self.num_kwonly_args > 0
1873 has_star_or_kw_args = self.star_arg is not None \
1874 or self.starstar_arg is not None or has_kwonly_args
1876 if not self.signature_has_generic_args():
1877 if has_star_or_kw_args:
1878 error(self.pos, "This method cannot have * or keyword arguments")
1879 self.generate_argument_conversion_code(code)
1881 elif not self.signature_has_nongeneric_args():
1882 # func(*args) or func(**kw) or func(*args, **kw)
1883 self.generate_stararg_copy_code(code)
1886 positional_args = []
1889 for arg in self.args:
1890 arg_entry = arg.entry
1894 if not arg.is_self_arg:
1896 kw_only_args.append(arg)
1898 positional_args.append(arg)
1900 kw_only_args.append(arg)
1903 error(arg.pos, "Non-default argument following default argument")
1904 elif not arg.is_self_arg:
1905 positional_args.append(arg)
1907 self.generate_tuple_and_keyword_parsing_code(
1908 positional_args, kw_only_args, end_label, code)
1910 code.error_label = old_error_label
1911 if code.label_used(our_error_label):
1912 if not code.label_used(end_label):
1913 code.put_goto(end_label)
1914 code.put_label(our_error_label)
1915 if has_star_or_kw_args:
1916 self.generate_arg_decref(self.star_arg, code)
1917 if self.starstar_arg:
1918 if self.starstar_arg.entry.xdecref_cleanup:
1919 code.put_var_xdecref(self.starstar_arg.entry)
1921 code.put_var_decref(self.starstar_arg.entry)
1922 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1923 code.putln("return %s;" % self.error_value())
1924 if code.label_used(end_label):
1925 code.put_label(end_label)
1927 def generate_arg_assignment(self, arg, item, code):
1928 if arg.type.is_pyobject:
1930 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1931 code.putln("%s = %s;" % (arg.entry.cname, item))
1933 func = arg.type.from_py_function
1935 code.putln("%s = %s(%s); %s" % (
1939 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1941 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1943 def generate_arg_xdecref(self, arg, code):
1945 code.put_var_xdecref(arg.entry)
1947 def generate_arg_decref(self, arg, code):
1949 code.put_var_decref(arg.entry)
1951 def generate_stararg_copy_code(self, code):
1952 if not self.star_arg:
1953 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1954 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1956 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1957 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1960 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1962 if self.starstar_arg:
1964 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1966 kwarg_check = "%s" % Naming.kwds_cname
1968 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1969 Naming.kwds_cname, Naming.kwds_cname)
1971 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1972 kwarg_check, Naming.kwds_cname, self.name,
1973 bool(self.starstar_arg), self.error_value()))
1975 if self.starstar_arg:
1976 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1977 self.starstar_arg.entry.cname,
1980 code.putln("if (unlikely(!%s)) return %s;" % (
1981 self.starstar_arg.entry.cname, self.error_value()))
1982 self.starstar_arg.entry.xdecref_cleanup = 0
1983 code.put_gotref(self.starstar_arg.entry.cname)
1987 code.put_incref(Naming.args_cname, py_object_type)
1988 code.putln("%s = %s;" % (
1989 self.star_arg.entry.cname,
1991 self.star_arg.entry.xdecref_cleanup = 0
1993 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1994 kw_only_args, success_label, code):
1995 argtuple_error_label = code.new_label("argtuple_error")
1997 min_positional_args = self.num_required_args - self.num_required_kw_args
1998 if len(self.args) > 0 and self.args[0].is_self_arg:
1999 min_positional_args -= 1
2000 max_positional_args = len(positional_args)
2001 has_fixed_positional_count = not self.star_arg and \
2002 min_positional_args == max_positional_args
2004 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2005 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2006 if self.num_required_kw_args:
2007 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2009 if self.starstar_arg or self.star_arg:
2010 self.generate_stararg_init_code(max_positional_args, code)
2012 # --- optimised code when we receive keyword arguments
2013 if self.num_required_kw_args:
2014 likely_hint = "likely"
2016 likely_hint = "unlikely"
2017 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2018 self.generate_keyword_unpacking_code(
2019 min_positional_args, max_positional_args,
2020 has_fixed_positional_count,
2021 positional_args, kw_only_args, argtuple_error_label, code)
2023 # --- optimised code when we do not receive any keyword arguments
2024 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2025 # Python raises arg tuple related errors first, so we must
2026 # check the length here
2027 if min_positional_args == max_positional_args and not self.star_arg:
2031 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2032 Naming.args_cname, compare, min_positional_args))
2033 code.put_goto(argtuple_error_label)
2035 if self.num_required_kw_args:
2036 # pure error case: keywords required but not passed
2037 if max_positional_args > min_positional_args and not self.star_arg:
2038 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2039 Naming.args_cname, max_positional_args))
2040 code.put_goto(argtuple_error_label)
2041 code.putln('} else {')
2042 for i, arg in enumerate(kw_only_args):
2044 pystring_cname = code.intern_identifier(arg.name)
2045 # required keyword-only argument missing
2046 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2047 self.name.utf8encode(),
2049 code.putln(code.error_goto(self.pos))
2052 elif min_positional_args == max_positional_args:
2053 # parse the exact number of positional arguments from the
2055 code.putln('} else {')
2056 for i, arg in enumerate(positional_args):
2057 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2058 self.generate_arg_assignment(arg, item, code)
2059 self.generate_arg_default_assignments(code)
2062 # parse the positional arguments from the variable length
2064 code.putln('} else {')
2065 self.generate_arg_default_assignments(code)
2066 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2068 code.putln('default:')
2069 reversed_args = list(enumerate(positional_args))[::-1]
2070 for i, arg in reversed_args:
2071 if i >= min_positional_args-1:
2072 if min_positional_args > 1:
2073 code.putln('case %2d:' % (i+1)) # pure code beautification
2075 code.put('case %2d: ' % (i+1))
2076 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2077 self.generate_arg_assignment(arg, item, code)
2078 if min_positional_args == 0:
2079 code.put('case 0: ')
2080 code.putln('break;')
2082 if min_positional_args:
2083 for i in range(min_positional_args-1, -1, -1):
2084 code.putln('case %2d:' % i)
2085 code.put_goto(argtuple_error_label)
2087 code.put('default: ')
2088 code.put_goto(argtuple_error_label)
2093 if code.label_used(argtuple_error_label):
2094 code.put_goto(success_label)
2095 code.put_label(argtuple_error_label)
2096 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2097 self.name.utf8encode(), has_fixed_positional_count,
2098 min_positional_args, max_positional_args,
2100 code.putln(code.error_goto(self.pos))
2102 def generate_arg_default_assignments(self, code):
2103 for arg in self.args:
2104 if arg.is_generic and arg.default:
2108 arg.calculate_default_value_code(code)))
2110 def generate_stararg_init_code(self, max_positional_args, code):
2111 if self.starstar_arg:
2112 self.starstar_arg.entry.xdecref_cleanup = 0
2113 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2114 self.starstar_arg.entry.cname,
2115 self.starstar_arg.entry.cname,
2116 self.error_value()))
2117 code.put_gotref(self.starstar_arg.entry.cname)
2119 self.star_arg.entry.xdecref_cleanup = 0
2120 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2122 max_positional_args))
2123 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2124 self.star_arg.entry.cname, Naming.args_cname,
2125 max_positional_args, Naming.args_cname))
2126 code.put_gotref(self.star_arg.entry.cname)
2127 if self.starstar_arg:
2129 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2130 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2131 code.putln('return %s;' % self.error_value())
2134 code.putln("if (unlikely(!%s)) return %s;" % (
2135 self.star_arg.entry.cname, self.error_value()))
2136 code.putln('} else {')
2137 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2138 code.put_incref(Naming.empty_tuple, py_object_type)
2141 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2142 has_fixed_positional_count, positional_args,
2143 kw_only_args, argtuple_error_label, code):
2144 all_args = tuple(positional_args) + tuple(kw_only_args)
2145 max_args = len(all_args)
2148 for i, arg in enumerate(all_args):
2149 if arg.default and arg.type.is_pyobject:
2150 default_value = arg.calculate_default_value_code(code)
2151 if arg.type is not PyrexTypes.py_object_type:
2152 default_value = "(PyObject*)"+default_value
2153 default_args.append((i, default_value))
2155 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2157 # it looks funny to separate the init-to-0 from setting the
2158 # default value, but C89 needs this
2159 code.putln("PyObject* values[%d] = {%s};" % (
2160 max_args, ','.join(['0']*max_args)))
2161 for i, default_value in default_args:
2162 code.putln('values[%d] = %s;' % (i, default_value))
2164 # parse the tuple and check that it's not too long
2165 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2167 code.putln('default:')
2168 for i in range(max_positional_args-1, -1, -1):
2169 code.put('case %2d: ' % (i+1))
2170 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2171 i, Naming.args_cname, i))
2172 code.putln('case 0: break;')
2173 if not self.star_arg:
2174 code.put('default: ') # more arguments than allowed
2175 code.put_goto(argtuple_error_label)
2178 # now fill up the positional/required arguments with values
2180 if self.num_required_args or max_positional_args > 0:
2181 last_required_arg = -1
2182 for i, arg in enumerate(all_args):
2184 last_required_arg = i
2185 if last_required_arg < max_positional_args:
2186 last_required_arg = max_positional_args-1
2187 num_required_args = self.num_required_args
2188 if max_positional_args > 0:
2189 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2190 for i, arg in enumerate(all_args[:last_required_arg+1]):
2191 if max_positional_args > 0 and i <= max_positional_args:
2192 if self.star_arg and i == max_positional_args:
2193 code.putln('default:')
2195 code.putln('case %2d:' % i)
2196 pystring_cname = code.intern_identifier(arg.name)
2199 # handled separately below
2201 code.putln('if (kw_args > %d) {' % num_required_args)
2202 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2203 Naming.kwds_cname, pystring_cname))
2204 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2207 num_required_args -= 1
2208 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2209 i, Naming.kwds_cname, pystring_cname))
2210 code.putln('if (likely(values[%d])) kw_args--;' % i);
2211 if i < min_positional_args:
2213 # special case: we know arg 0 is missing
2215 code.put_goto(argtuple_error_label)
2217 # print the correct number of values (args or
2218 # kwargs) that were passed into positional
2219 # arguments up to this point
2220 code.putln('else {')
2221 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2222 self.name.utf8encode(), has_fixed_positional_count,
2223 min_positional_args, max_positional_args, i))
2224 code.putln(code.error_goto(self.pos))
2227 code.putln('else {')
2228 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2229 self.name.utf8encode(), pystring_cname))
2230 code.putln(code.error_goto(self.pos))
2232 if max_positional_args > 0:
2235 if kw_only_args and not self.starstar_arg:
2236 # unpack optional keyword-only arguments
2237 # checking for interned strings in a dict is faster than iterating
2238 # but it's too likely that we must iterate if we expect **kwargs
2240 for i, arg in enumerate(all_args[max_positional_args:]):
2241 if not arg.kw_only or not arg.default:
2243 optional_args.append((i+max_positional_args, arg))
2245 # this mimics an unrolled loop so that we can "break" out of it
2246 code.putln('while (kw_args > 0) {')
2247 code.putln('PyObject* value;')
2248 for i, arg in optional_args:
2249 pystring_cname = code.intern_identifier(arg.name)
2251 'value = PyDict_GetItem(%s, %s);' % (
2252 Naming.kwds_cname, pystring_cname))
2254 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2255 code.putln('break;')
2258 code.putln('if (unlikely(kw_args > 0)) {')
2259 # non-positional/-required kw args left in dict: default args,
2260 # kw-only args, **kwargs or error
2262 # This is sort of a catch-all: except for checking required
2263 # arguments, this will always do the right thing for unpacking
2264 # keyword arguments, so that we can concentrate on optimising
2265 # common cases above.
2266 if max_positional_args == 0:
2269 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2270 Naming.args_cname, max_positional_args,
2271 Naming.args_cname, max_positional_args))
2272 pos_arg_count = "used_pos_args"
2274 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2275 code.globalstate.use_utility_code(parse_keywords_utility_code)
2277 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2279 Naming.pykwdlist_cname,
2280 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2282 self.name.utf8encode()))
2283 code.putln(code.error_goto(self.pos))
2286 # convert arg values to their final type and assign them
2287 for i, arg in enumerate(all_args):
2288 if arg.default and not arg.type.is_pyobject:
2289 code.putln("if (values[%d]) {" % i)
2290 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2291 if arg.default and not arg.type.is_pyobject:
2292 code.putln('} else {')
2296 arg.calculate_default_value_code(code)))
2299 def generate_argument_conversion_code(self, code):
2300 # Generate code to convert arguments from
2301 # signature type to declared type, if needed.
2302 for arg in self.args:
2303 if arg.needs_conversion:
2304 self.generate_arg_conversion(arg, code)
2306 def generate_arg_conversion(self, arg, code):
2307 # Generate conversion code for one argument.
2308 old_type = arg.hdr_type
2310 if old_type.is_pyobject:
2312 code.putln("if (%s) {" % arg.hdr_cname)
2314 code.putln("assert(%s); {" % arg.hdr_cname)
2315 self.generate_arg_conversion_from_pyobject(arg, code)
2317 elif new_type.is_pyobject:
2318 self.generate_arg_conversion_to_pyobject(arg, code)
2320 if new_type.assignable_from(old_type):
2322 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2325 "Cannot convert 1 argument from '%s' to '%s'" %
2326 (old_type, new_type))
2328 def generate_arg_conversion_from_pyobject(self, arg, code):
2330 func = new_type.from_py_function
2331 # copied from CoerceFromPyTypeNode
2333 code.putln("%s = %s(%s); %s" % (
2337 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2340 "Cannot convert Python object argument to type '%s'"
2343 def generate_arg_conversion_to_pyobject(self, arg, code):
2344 old_type = arg.hdr_type
2345 func = old_type.to_py_function
2347 code.putln("%s = %s(%s); %s" % (
2351 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2352 code.put_var_gotref(arg.entry)
2355 "Cannot convert argument of type '%s' to Python object"
2358 def generate_argument_type_tests(self, code):
2359 # Generate type tests for args whose signature
2360 # type is PyObject * and whose declared type is
2361 # a subtype thereof.
2362 for arg in self.args:
2363 if arg.needs_type_test:
2364 self.generate_arg_type_test(arg, code)
2366 def generate_arg_type_test(self, arg, code):
2367 # Generate type test for one argument.
2368 if arg.type.typeobj_is_available():
2369 typeptr_cname = arg.type.typeptr_cname
2370 arg_code = "((PyObject *)%s)" % arg.entry.cname
2372 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2377 arg.type.is_builtin_type,
2378 code.error_goto(arg.pos)))
2380 error(arg.pos, "Cannot test type of extern C class "
2381 "without type object name specification")
2383 def error_value(self):
2384 return self.entry.signature.error_value
2386 def caller_will_check_exceptions(self):
2389 class OverrideCheckNode(StatNode):
2390 # A Node for dispatching to the def method if it
2399 child_attrs = ['body']
2403 def analyse_expressions(self, env):
2404 self.args = env.arg_entries
2405 if self.py_func.is_module_scope:
2410 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2411 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2412 call_node = ExprNodes.SimpleCallNode(self.pos,
2413 function=self.func_node,
2414 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2415 self.body = ReturnStatNode(self.pos, value=call_node)
2416 self.body.analyse_expressions(env)
2418 def generate_execution_code(self, code):
2419 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2420 # Check to see if we are an extension type
2421 if self.py_func.is_module_scope:
2422 self_arg = "((PyObject *)%s)" % Naming.module_cname
2424 self_arg = "((PyObject *)%s)" % self.args[0].cname
2425 code.putln("/* Check if called by wrapper */")
2426 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2427 code.putln("/* Check if overriden in Python */")
2428 if self.py_func.is_module_scope:
2429 code.putln("else {")
2431 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2432 self.func_node.allocate(code)
2433 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2434 # need to get attribute manually--scope would return cdef method
2435 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2436 self.func_node.result(), self_arg, interned_attr_cname, err))
2437 code.put_gotref(self.func_node.py_result())
2438 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2439 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2440 self.func_node.result(), self.py_func.entry.func_cname)
2441 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2442 self.body.generate_execution_code(code)
2444 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2446 self.func_node.release(code)
2448 class ClassDefNode(StatNode, BlockNode):
2451 class PyClassDefNode(ClassDefNode):
2452 # A Python class definition.
2454 # name EncodedString Name of the class
2455 # doc string or None
2456 # body StatNode Attribute definition code
2457 # entry Symtab.Entry
2458 # scope PyClassScope
2460 # The following subnodes are constructed internally:
2462 # dict DictNode Class dictionary
2463 # classobj ClassNode Class object
2464 # target NameNode Variable to assign class object to
2466 child_attrs = ["body", "dict", "classobj", "target"]
2468 def __init__(self, pos, name, bases, doc, body):
2469 StatNode.__init__(self, pos)
2474 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2475 if self.doc and Options.docstrings:
2476 doc = embed_position(self.pos, self.doc)
2477 doc_node = ExprNodes.StringNode(pos, value = doc)
2480 self.classobj = ExprNodes.ClassNode(pos, name = name,
2481 bases = bases, dict = self.dict, doc = doc_node)
2482 self.target = ExprNodes.NameNode(pos, name = name)
2484 def as_cclass(self):
2486 Return this node as if it were declared as an extension class
2488 bases = self.classobj.bases.args
2490 base_class_name = None
2491 base_class_module = None
2492 elif len(bases) == 1:
2495 from ExprNodes import AttributeNode, NameNode
2496 while isinstance(base, AttributeNode):
2497 path.insert(0, base.attribute)
2499 if isinstance(base, NameNode):
2500 path.insert(0, base.name)
2501 base_class_name = path[-1]
2503 base_class_module = u'.'.join(path[:-1])
2505 base_class_module = None
2507 error(self.classobj.bases.args.pos, "Invalid base class")
2509 error(self.classobj.bases.args.pos, "C class may only have one base class")
2512 return CClassDefNode(self.pos,
2513 visibility = 'private',
2515 class_name = self.name,
2516 base_class_module = base_class_module,
2517 base_class_name = base_class_name,
2522 def create_scope(self, env):
2524 while env.is_py_class_scope or env.is_c_class_scope:
2525 env = env.outer_scope
2526 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2529 def analyse_declarations(self, env):
2530 self.target.analyse_target_declaration(env)
2531 cenv = self.create_scope(env)
2532 cenv.class_obj_cname = self.target.entry.cname
2533 self.body.analyse_declarations(cenv)
2535 def analyse_expressions(self, env):
2536 self.dict.analyse_expressions(env)
2537 self.classobj.analyse_expressions(env)
2538 genv = env.global_scope()
2540 self.body.analyse_expressions(cenv)
2541 self.target.analyse_target_expression(env, self.classobj)
2542 self.dict.release_temp(env)
2543 #self.classobj.release_temp(env)
2544 #self.target.release_target_temp(env)
2546 def generate_function_definitions(self, env, code):
2547 self.body.generate_function_definitions(self.scope, code)
2549 def generate_execution_code(self, code):
2550 code.pyclass_stack.append(self)
2552 self.dict.generate_evaluation_code(code)
2553 self.classobj.generate_evaluation_code(code)
2554 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2555 self.body.generate_execution_code(code)
2556 self.target.generate_assignment_code(self.classobj, code)
2557 self.dict.generate_disposal_code(code)
2558 self.dict.free_temps(code)
2559 code.pyclass_stack.pop()
2562 class CClassDefNode(ClassDefNode):
2563 # An extension type definition.
2565 # visibility 'private' or 'public' or 'extern'
2566 # typedef_flag boolean
2568 # module_name string or None For import of extern type objects
2569 # class_name string Unqualified name of class
2570 # as_name string or None Name to declare as in this scope
2571 # base_class_module string or None Module containing the base class
2572 # base_class_name string or None Name of the base class
2573 # objstruct_name string or None Specified C name of object struct
2574 # typeobj_name string or None Specified C name of type object
2575 # in_pxd boolean Is in a .pxd file
2576 # doc string or None
2577 # body StatNode or None
2578 # entry Symtab.Entry
2579 # base_type PyExtensionType or None
2580 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2581 # buffer_defaults_pos
2583 child_attrs = ["body"]
2584 buffer_defaults_node = None
2585 buffer_defaults_pos = None
2586 typedef_flag = False
2588 objstruct_name = None
2591 def analyse_declarations(self, env):
2592 #print "CClassDefNode.analyse_declarations:", self.class_name
2593 #print "...visibility =", self.visibility
2594 #print "...module_name =", self.module_name
2597 if self.buffer_defaults_node:
2598 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2599 env, [], self.buffer_defaults_node,
2600 need_complete=False)
2602 buffer_defaults = None
2604 if env.in_cinclude and not self.objstruct_name:
2605 error(self.pos, "Object struct name specification required for "
2606 "C class defined in 'extern from' block")
2607 self.base_type = None
2608 # Now that module imports are cached, we need to
2609 # import the modules for extern classes.
2610 if self.module_name:
2612 for module in env.cimported_modules:
2613 if module.name == self.module_name:
2614 self.module = module
2615 if self.module is None:
2616 self.module = ModuleScope(self.module_name, None, env.context)
2617 self.module.has_extern_class = 1
2618 env.add_imported_module(self.module)
2620 if self.base_class_name:
2621 if self.base_class_module:
2622 base_class_scope = env.find_module(self.base_class_module, self.pos)
2624 base_class_scope = env
2625 if self.base_class_name == 'object':
2626 # extension classes are special and don't need to inherit from object
2627 if base_class_scope is None or base_class_scope.lookup('object') is None:
2628 self.base_class_name = None
2629 self.base_class_module = None
2630 base_class_scope = None
2631 if base_class_scope:
2632 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2633 if base_class_entry:
2634 if not base_class_entry.is_type:
2635 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2636 elif not base_class_entry.type.is_extension_type:
2637 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2638 elif not base_class_entry.type.is_complete():
2639 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2641 self.base_type = base_class_entry.type
2642 has_body = self.body is not None
2643 if self.module_name and self.visibility != 'extern':
2644 module_path = self.module_name.split(".")
2645 home_scope = env.find_imported_module(module_path, self.pos)
2651 if self.visibility == 'extern':
2652 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2653 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2655 self.entry = home_scope.declare_c_class(
2656 name = self.class_name,
2658 defining = has_body and self.in_pxd,
2659 implementing = has_body and not self.in_pxd,
2660 module_name = self.module_name,
2661 base_type = self.base_type,
2662 objstruct_cname = self.objstruct_name,
2663 typeobj_cname = self.typeobj_name,
2664 visibility = self.visibility,
2665 typedef_flag = self.typedef_flag,
2667 buffer_defaults = buffer_defaults)
2668 if home_scope is not env and self.visibility == 'extern':
2669 env.add_imported_entry(self.class_name, self.entry, pos)
2670 scope = self.entry.type.scope
2672 if self.doc and Options.docstrings:
2673 scope.doc = embed_position(self.pos, self.doc)
2676 self.body.analyse_declarations(scope)
2680 scope.implemented = 1
2681 env.allocate_vtable_names(self.entry)
2683 def analyse_expressions(self, env):
2685 scope = self.entry.type.scope
2686 self.body.analyse_expressions(scope)
2688 def generate_function_definitions(self, env, code):
2690 self.body.generate_function_definitions(
2691 self.entry.type.scope, code)
2693 def generate_execution_code(self, code):
2694 # This is needed to generate evaluation code for
2695 # default values of method arguments.
2697 self.body.generate_execution_code(code)
2699 def annotate(self, code):
2701 self.body.annotate(code)
2704 class PropertyNode(StatNode):
2705 # Definition of a property in an extension type.
2708 # doc EncodedString or None Doc string
2711 child_attrs = ["body"]
2713 def analyse_declarations(self, env):
2714 entry = env.declare_property(self.name, self.doc, self.pos)
2716 self.body.analyse_declarations(entry.scope)
2718 def analyse_expressions(self, env):
2719 self.body.analyse_expressions(env)
2721 def generate_function_definitions(self, env, code):
2722 self.body.generate_function_definitions(env, code)
2724 def generate_execution_code(self, code):
2727 def annotate(self, code):
2728 self.body.annotate(code)
2731 class GlobalNode(StatNode):
2732 # Global variable declaration.
2738 def analyse_declarations(self, env):
2739 for name in self.names:
2740 env.declare_global(name, self.pos)
2742 def analyse_expressions(self, env):
2745 def generate_execution_code(self, code):
2749 class ExprStatNode(StatNode):
2750 # Expression used as a statement.
2754 child_attrs = ["expr"]
2756 def analyse_declarations(self, env):
2758 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2759 func = self.expr.function.as_cython_attribute()
2760 if func == u'declare':
2761 args, kwds = self.expr.explicit_args_kwds()
2763 error(self.expr.pos, "Variable names must be specified.")
2764 for var, type_node in kwds.key_value_pairs:
2765 type = type_node.analyse_as_type(env)
2767 error(type_node.pos, "Unknown type")
2769 env.declare_var(var.value, type, var.pos, is_cdef = True)
2770 self.__class__ = PassStatNode
2772 def analyse_expressions(self, env):
2773 self.expr.analyse_expressions(env)
2774 self.expr.release_temp(env)
2776 def generate_execution_code(self, code):
2777 self.expr.generate_evaluation_code(code)
2778 if not self.expr.is_temp and self.expr.result():
2779 code.putln("%s;" % self.expr.result())
2780 self.expr.generate_disposal_code(code)
2781 self.expr.free_temps(code)
2783 def annotate(self, code):
2784 self.expr.annotate(code)
2787 class AssignmentNode(StatNode):
2788 # Abstract base class for assignment nodes.
2790 # The analyse_expressions and generate_execution_code
2791 # phases of assignments are split into two sub-phases
2792 # each, to enable all the right hand sides of a
2793 # parallel assignment to be evaluated before assigning
2794 # to any of the left hand sides.
2796 def analyse_expressions(self, env):
2797 self.analyse_types(env)
2798 self.allocate_rhs_temps(env)
2799 self.allocate_lhs_temps(env)
2801 # def analyse_expressions(self, env):
2802 # self.analyse_expressions_1(env)
2803 # self.analyse_expressions_2(env)
2805 def generate_execution_code(self, code):
2806 self.generate_rhs_evaluation_code(code)
2807 self.generate_assignment_code(code)
2810 class SingleAssignmentNode(AssignmentNode):
2811 # The simplest case:
2815 # lhs ExprNode Left hand side
2816 # rhs ExprNode Right hand side
2817 # first bool Is this guaranteed the first assignment to lhs?
2819 child_attrs = ["lhs", "rhs"]
2821 declaration_only = False
2823 def analyse_declarations(self, env):
2826 # handle declarations of the form x = cython.foo()
2827 if isinstance(self.rhs, ExprNodes.CallNode):
2828 func_name = self.rhs.function.as_cython_attribute()
2830 args, kwds = self.rhs.explicit_args_kwds()
2832 if func_name in ['declare', 'typedef']:
2833 if len(args) > 2 or kwds is not None:
2834 error(rhs.pos, "Can only declare one type at a time.")
2836 type = args[0].analyse_as_type(env)
2838 error(args[0].pos, "Unknown type")
2841 if func_name == 'declare':
2842 if isinstance(lhs, ExprNodes.NameNode):
2843 vars = [(lhs.name, lhs.pos)]
2844 elif isinstance(lhs, ExprNodes.TupleNode):
2845 vars = [(var.name, var.pos) for var in lhs.args]
2847 error(lhs.pos, "Invalid declaration")
2849 for var, pos in vars:
2850 env.declare_var(var, type, pos, is_cdef = True)
2855 self.declaration_only = True
2857 self.declaration_only = True
2858 if not isinstance(lhs, ExprNodes.NameNode):
2859 error(lhs.pos, "Invalid declaration.")
2860 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2862 elif func_name in ['struct', 'union']:
2863 self.declaration_only = True
2864 if len(args) > 0 or kwds is None:
2865 error(rhs.pos, "Struct or union members must be given by name.")
2868 for member, type_node in kwds.key_value_pairs:
2869 type = type_node.analyse_as_type(env)
2871 error(type_node.pos, "Unknown type")
2873 members.append((member.value, type, member.pos))
2874 if len(members) < len(kwds.key_value_pairs):
2876 if not isinstance(self.lhs, ExprNodes.NameNode):
2877 error(self.lhs.pos, "Invalid declaration.")
2878 name = self.lhs.name
2879 scope = StructOrUnionScope(name)
2880 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2881 for member, type, pos in members:
2882 scope.declare_var(member, type, pos)
2884 if self.declaration_only:
2887 self.lhs.analyse_target_declaration(env)
2889 def analyse_types(self, env, use_temp = 0):
2890 self.rhs.analyse_types(env)
2891 self.lhs.analyse_target_types(env)
2892 self.lhs.gil_assignment_check(env)
2893 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2895 self.rhs = self.rhs.coerce_to_temp(env)
2897 def allocate_rhs_temps(self, env):
2898 self.rhs.allocate_temps(env)
2900 def allocate_lhs_temps(self, env):
2901 self.lhs.allocate_target_temps(env, self.rhs)
2902 #self.lhs.release_target_temp(env)
2903 #self.rhs.release_temp(env)
2905 def generate_rhs_evaluation_code(self, code):
2906 self.rhs.generate_evaluation_code(code)
2908 def generate_assignment_code(self, code):
2909 self.lhs.generate_assignment_code(self.rhs, code)
2911 def annotate(self, code):
2912 self.lhs.annotate(code)
2913 self.rhs.annotate(code)
2916 class CascadedAssignmentNode(AssignmentNode):
2917 # An assignment with multiple left hand sides:
2921 # lhs_list [ExprNode] Left hand sides
2922 # rhs ExprNode Right hand sides
2926 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2928 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2929 coerced_rhs_list = None
2931 def analyse_declarations(self, env):
2932 for lhs in self.lhs_list:
2933 lhs.analyse_target_declaration(env)
2935 def analyse_types(self, env, use_temp = 0):
2936 self.rhs.analyse_types(env)
2938 self.rhs = self.rhs.coerce_to_temp(env)
2940 self.rhs = self.rhs.coerce_to_simple(env)
2941 from ExprNodes import CloneNode
2942 self.coerced_rhs_list = []
2943 for lhs in self.lhs_list:
2944 lhs.analyse_target_types(env)
2945 lhs.gil_assignment_check(env)
2946 rhs = CloneNode(self.rhs)
2947 rhs = rhs.coerce_to(lhs.type, env)
2948 self.coerced_rhs_list.append(rhs)
2950 def allocate_rhs_temps(self, env):
2951 self.rhs.allocate_temps(env)
2953 def allocate_lhs_temps(self, env):
2954 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2955 rhs.allocate_temps(env)
2956 lhs.allocate_target_temps(env, rhs)
2957 #lhs.release_target_temp(env)
2958 #rhs.release_temp(env)
2959 self.rhs.release_temp(env)
2961 def generate_rhs_evaluation_code(self, code):
2962 self.rhs.generate_evaluation_code(code)
2964 def generate_assignment_code(self, code):
2965 for i in range(len(self.lhs_list)):
2966 lhs = self.lhs_list[i]
2967 rhs = self.coerced_rhs_list[i]
2968 rhs.generate_evaluation_code(code)
2969 lhs.generate_assignment_code(rhs, code)
2970 # Assignment has disposed of the cloned RHS
2971 self.rhs.generate_disposal_code(code)
2972 self.rhs.free_temps(code)
2974 def annotate(self, code):
2975 for i in range(len(self.lhs_list)):
2976 lhs = self.lhs_list[i].annotate(code)
2977 rhs = self.coerced_rhs_list[i].annotate(code)
2978 self.rhs.annotate(code)
2981 class ParallelAssignmentNode(AssignmentNode):
2982 # A combined packing/unpacking assignment:
2986 # This has been rearranged by the parser into
2988 # a = d ; b = e ; c = f
2990 # but we must evaluate all the right hand sides
2991 # before assigning to any of the left hand sides.
2993 # stats [AssignmentNode] The constituent assignments
2995 child_attrs = ["stats"]
2997 def analyse_declarations(self, env):
2998 for stat in self.stats:
2999 stat.analyse_declarations(env)
3001 def analyse_expressions(self, env):
3002 for stat in self.stats:
3003 stat.analyse_types(env, use_temp = 1)
3004 stat.allocate_rhs_temps(env)
3005 for stat in self.stats:
3006 stat.allocate_lhs_temps(env)
3008 # def analyse_expressions(self, env):
3009 # for stat in self.stats:
3010 # stat.analyse_expressions_1(env, use_temp = 1)
3011 # for stat in self.stats:
3012 # stat.analyse_expressions_2(env)
3014 def generate_execution_code(self, code):
3015 for stat in self.stats:
3016 stat.generate_rhs_evaluation_code(code)
3017 for stat in self.stats:
3018 stat.generate_assignment_code(code)
3020 def annotate(self, code):
3021 for stat in self.stats:
3025 class InPlaceAssignmentNode(AssignmentNode):
3026 # An in place arithmatic operand:
3032 # lhs ExprNode Left hand side
3033 # rhs ExprNode Right hand side
3034 # op char one of "+-*/%^&|"
3035 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3037 # This code is a bit tricky because in order to obey Python
3038 # semantics the sub-expressions (e.g. indices) of the lhs must
3039 # not be evaluated twice. So we must re-use the values calculated
3040 # in evaluation phase for the assignment phase as well.
3041 # Fortunately, the type of the lhs node is fairly constrained
3042 # (it must be a NameNode, AttributeNode, or IndexNode).
3044 child_attrs = ["lhs", "rhs"]
3047 def analyse_declarations(self, env):
3048 self.lhs.analyse_target_declaration(env)
3050 def analyse_types(self, env):
3051 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3052 self.rhs.analyse_types(env)
3053 self.lhs.analyse_target_types(env)
3054 if Options.incref_local_binop and self.dup.type.is_pyobject:
3055 self.dup = self.dup.coerce_to_temp(env)
3057 def allocate_rhs_temps(self, env):
3059 if self.lhs.type.is_pyobject:
3060 self.rhs = self.rhs.coerce_to_pyobject(env)
3061 elif self.rhs.type.is_pyobject:
3062 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3063 if self.lhs.type.is_pyobject:
3064 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3065 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3066 self.result_value.allocate_temps(env)
3068 # self.rhs = self.rhs.coerce_to_temp(env)
3069 self.rhs.allocate_temps(env)
3070 self.dup.allocate_subexpr_temps(env)
3071 self.dup.allocate_temp(env)
3073 def allocate_lhs_temps(self, env):
3074 self.lhs.allocate_target_temps(env, self.rhs)
3075 # self.lhs.release_target_temp(env)
3076 self.dup.release_temp(env)
3077 if self.dup.is_temp:
3078 self.dup.release_subexpr_temps(env)
3079 # self.rhs.release_temp(env)
3080 if self.lhs.type.is_pyobject:
3081 self.result_value.release_temp(env)
3083 def generate_execution_code(self, code):
3085 self.rhs.generate_evaluation_code(code)
3086 self.dup.generate_subexpr_evaluation_code(code)
3087 if self.dup.is_temp:
3088 self.dup.allocate_temp_result(code)
3089 # self.dup.generate_result_code is run only if it is not buffer access
3090 if self.operator == "**":
3094 if self.lhs.type.is_pyobject:
3095 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3096 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3097 self.dup.generate_result_code(code)
3098 self.result_value_temp.allocate(code)
3100 "%s = %s(%s, %s%s); %s" % (
3101 self.result_value.result(),
3102 self.py_operation_function(),
3103 self.dup.py_result(),
3104 self.rhs.py_result(),
3106 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3107 code.put_gotref(self.result_value.py_result())
3108 self.result_value.generate_evaluation_code(code) # May be a type check...
3109 self.rhs.generate_disposal_code(code)
3110 self.rhs.free_temps(code)
3111 self.dup.generate_disposal_code(code)
3112 self.dup.free_temps(code)
3113 self.lhs.generate_assignment_code(self.result_value, code)
3114 self.result_value_temp.release(code)
3116 c_op = self.operator
3120 if self.lhs.type.is_int and self.rhs.type.is_int:
3121 error(self.pos, "** with two C int types is ambiguous")
3123 error(self.pos, "No C inplace power operator")
3124 # have to do assignment directly to avoid side-effects
3125 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3126 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3128 self.dup.generate_result_code(code)
3129 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3130 self.rhs.generate_disposal_code(code)
3131 self.rhs.free_temps(code)
3132 if self.dup.is_temp:
3133 self.dup.generate_subexpr_disposal_code(code)
3134 self.dup.free_subexpr_temps(code)
3136 def create_dup_node(self, env):
3139 self.dup.analyse_types(env)
3140 if isinstance(self.lhs, ExprNodes.NameNode):
3141 target_lhs = ExprNodes.NameNode(self.dup.pos,
3142 name = self.dup.name,
3143 is_temp = self.dup.is_temp,
3144 entry = self.dup.entry)
3145 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3146 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3147 obj = ExprNodes.CloneNode(self.lhs.obj),
3148 attribute = self.dup.attribute,
3149 is_temp = self.dup.is_temp)
3150 elif isinstance(self.lhs, ExprNodes.IndexNode):
3152 index = ExprNodes.CloneNode(self.lhs.index)
3155 if self.lhs.indices:
3156 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3159 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3160 base = ExprNodes.CloneNode(self.dup.base),
3163 is_temp = self.dup.is_temp)
3166 self.lhs = target_lhs
3169 def py_operation_function(self):
3170 return self.py_functions[self.operator]
3173 "|": "PyNumber_InPlaceOr",
3174 "^": "PyNumber_InPlaceXor",
3175 "&": "PyNumber_InPlaceAnd",
3176 "+": "PyNumber_InPlaceAdd",
3177 "-": "PyNumber_InPlaceSubtract",
3178 "*": "PyNumber_InPlaceMultiply",
3179 "/": "PyNumber_InPlaceDivide",
3180 "%": "PyNumber_InPlaceRemainder",
3181 "<<": "PyNumber_InPlaceLshift",
3182 ">>": "PyNumber_InPlaceRshift",
3183 "**": "PyNumber_InPlacePower",
3184 "//": "PyNumber_InPlaceFloorDivide",
3187 def annotate(self, code):
3188 self.lhs.annotate(code)
3189 self.rhs.annotate(code)
3190 self.dup.annotate(code)
3193 class PrintStatNode(StatNode):
3196 # arg_tuple TupleNode
3197 # append_newline boolean
3199 child_attrs = ["arg_tuple"]
3201 def analyse_expressions(self, env):
3202 self.arg_tuple.analyse_expressions(env)
3203 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3204 self.arg_tuple.release_temp(env)
3205 env.use_utility_code(printing_utility_code)
3206 if len(self.arg_tuple.args) == 1 and self.append_newline:
3207 env.use_utility_code(printing_one_utility_code)
3209 gil_check = StatNode._gil_check
3210 gil_message = "Python print statement"
3212 def generate_execution_code(self, code):
3213 if len(self.arg_tuple.args) == 1 and self.append_newline:
3214 arg = self.arg_tuple.args[0]
3215 arg.generate_evaluation_code(code)
3218 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3220 code.error_goto(self.pos)))
3221 arg.generate_disposal_code(code)
3222 arg.free_temps(code)
3224 self.arg_tuple.generate_evaluation_code(code)
3226 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3227 self.arg_tuple.py_result(),
3228 self.append_newline,
3229 code.error_goto(self.pos)))
3230 self.arg_tuple.generate_disposal_code(code)
3231 self.arg_tuple.free_temps(code)
3233 def annotate(self, code):
3234 self.arg_tuple.annotate(code)
3237 class ExecStatNode(StatNode):
3242 child_attrs = ["args"]
3244 def analyse_expressions(self, env):
3245 for i, arg in enumerate(self.args):
3246 arg.analyse_expressions(env)
3247 arg = arg.coerce_to_pyobject(env)
3248 arg.release_temp(env)
3250 self.temp_result = env.allocate_temp_pyobject()
3251 env.release_temp(self.temp_result)
3252 env.use_utility_code(Builtin.pyexec_utility_code)
3254 gil_check = StatNode._gil_check
3255 gil_message = "Python exec statement"
3257 def generate_execution_code(self, code):
3259 for arg in self.args:
3260 arg.generate_evaluation_code(code)
3261 args.append( arg.py_result() )
3262 args = tuple(args + ['0', '0'][:3-len(args)])
3263 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3264 (self.temp_result,) + args))
3265 for arg in self.args:
3266 arg.generate_disposal_code(code)
3267 arg.free_temps(code)
3269 code.error_goto_if_null(self.temp_result, self.pos))
3270 code.put_gotref(self.temp_result)
3271 code.put_decref_clear(self.temp_result, py_object_type)
3273 def annotate(self, code):
3274 for arg in self.args:
3278 class DelStatNode(StatNode):
3283 child_attrs = ["args"]
3285 def analyse_declarations(self, env):
3286 for arg in self.args:
3287 arg.analyse_target_declaration(env)
3289 def analyse_expressions(self, env):
3290 for arg in self.args:
3291 arg.analyse_target_expression(env, None)
3292 if not arg.type.is_pyobject:
3293 error(arg.pos, "Deletion of non-Python object")
3294 #arg.release_target_temp(env)
3296 def gil_check(self, env):
3297 for arg in self.args:
3298 if arg.type.is_pyobject:
3299 self._gil_check(env)
3301 gil_message = "Deleting Python object"
3303 def generate_execution_code(self, code):
3304 for arg in self.args:
3305 if arg.type.is_pyobject:
3306 arg.generate_deletion_code(code)
3307 # else error reported earlier
3309 def annotate(self, code):
3310 for arg in self.args:
3314 class PassStatNode(StatNode):
3319 def analyse_expressions(self, env):
3322 def generate_execution_code(self, code):
3326 class BreakStatNode(StatNode):
3330 def analyse_expressions(self, env):
3333 def generate_execution_code(self, code):
3334 if not code.break_label:
3335 error(self.pos, "break statement not inside loop")
3337 code.put_goto(code.break_label)
3340 class ContinueStatNode(StatNode):
3344 def analyse_expressions(self, env):
3347 def generate_execution_code(self, code):
3348 if code.funcstate.in_try_finally:
3349 error(self.pos, "continue statement inside try of try...finally")
3350 elif not code.continue_label:
3351 error(self.pos, "continue statement not inside loop")
3353 code.put_goto(code.continue_label)
3356 class ReturnStatNode(StatNode):
3359 # value ExprNode or None
3360 # return_type PyrexType
3361 # temps_in_use [Entry] Temps in use at time of return
3363 child_attrs = ["value"]
3365 def analyse_expressions(self, env):
3366 return_type = env.return_type
3367 self.return_type = return_type
3368 self.temps_in_use = env.temps_in_use()
3370 error(self.pos, "Return not inside a function body")
3373 self.value.analyse_types(env)
3374 if return_type.is_void or return_type.is_returncode:
3375 error(self.value.pos,
3376 "Return with value in void function")
3378 self.value = self.value.coerce_to(env.return_type, env)
3379 self.value.allocate_temps(env)
3380 self.value.release_temp(env)
3382 if (not return_type.is_void
3383 and not return_type.is_pyobject
3384 and not return_type.is_returncode):
3385 error(self.pos, "Return value required")
3387 def gil_check(self, env):
3388 if self.return_type.is_pyobject:
3389 self._gil_check(env)
3391 gil_message = "Returning Python object"
3393 def generate_execution_code(self, code):
3394 code.mark_pos(self.pos)
3395 if not self.return_type:
3396 # error reported earlier
3398 if self.return_type.is_pyobject:
3399 code.put_xdecref(Naming.retval_cname,
3402 self.value.generate_evaluation_code(code)
3403 self.value.make_owned_reference(code)
3406 Naming.retval_cname,
3407 self.value.result_as(self.return_type)))
3408 self.value.generate_post_assignment_code(code)
3409 self.value.free_temps(code)
3411 if self.return_type.is_pyobject:
3412 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3413 elif self.return_type.is_returncode:
3416 Naming.retval_cname,
3417 self.return_type.default_value))
3418 # free temps the old way
3419 for entry in self.temps_in_use:
3420 code.put_var_decref_clear(entry)
3421 # free temps the new way
3422 for cname, type in code.funcstate.temps_holding_reference():
3423 code.put_decref_clear(cname, type)
3426 # code.return_label)
3427 code.put_goto(code.return_label)
3429 def annotate(self, code):
3431 self.value.annotate(code)
3434 class RaiseStatNode(StatNode):
3437 # exc_type ExprNode or None
3438 # exc_value ExprNode or None
3439 # exc_tb ExprNode or None
3441 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3443 def analyse_expressions(self, env):
3445 self.exc_type.analyse_types(env)
3446 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3447 self.exc_type.allocate_temps(env)
3449 self.exc_value.analyse_types(env)
3450 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3451 self.exc_value.allocate_temps(env)
3453 self.exc_tb.analyse_types(env)
3454 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3455 self.exc_tb.allocate_temps(env)
3457 self.exc_type.release_temp(env)
3459 self.exc_value.release_temp(env)
3461 self.exc_tb.release_temp(env)
3462 env.use_utility_code(raise_utility_code)
3463 env.use_utility_code(restore_exception_utility_code)
3465 gil_check = StatNode._gil_check
3466 gil_message = "Raising exception"
3468 def generate_execution_code(self, code):
3470 self.exc_type.generate_evaluation_code(code)
3471 type_code = self.exc_type.py_result()
3475 self.exc_value.generate_evaluation_code(code)
3476 value_code = self.exc_value.py_result()
3480 self.exc_tb.generate_evaluation_code(code)
3481 tb_code = self.exc_tb.py_result()
3484 if self.exc_type or self.exc_value or self.exc_tb:
3486 "__Pyx_Raise(%s, %s, %s);" % (
3493 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3495 obj.generate_disposal_code(code)
3496 obj.free_temps(code)
3498 code.error_goto(self.pos))
3500 def annotate(self, code):
3502 self.exc_type.annotate(code)
3504 self.exc_value.annotate(code)
3506 self.exc_tb.annotate(code)
3509 class ReraiseStatNode(StatNode):
3513 def analyse_expressions(self, env):
3514 env.use_utility_code(raise_utility_code)
3515 env.use_utility_code(restore_exception_utility_code)
3517 gil_check = StatNode._gil_check
3518 gil_message = "Raising exception"
3520 def generate_execution_code(self, code):
3521 vars = code.funcstate.exc_vars
3523 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3524 code.putln(code.error_goto(self.pos))
3526 error(self.pos, "Reraise not inside except clause")
3529 class AssertStatNode(StatNode):
3533 # value ExprNode or None
3535 child_attrs = ["cond", "value"]
3537 def analyse_expressions(self, env):
3538 self.cond = self.cond.analyse_boolean_expression(env)
3540 self.value.analyse_types(env)
3541 self.value = self.value.coerce_to_pyobject(env)
3542 self.value.allocate_temps(env)
3543 self.cond.release_temp(env)
3545 self.value.release_temp(env)
3546 #env.recycle_pending_temps() # TEMPORARY
3548 gil_check = StatNode._gil_check
3549 gil_message = "Raising exception"
3551 def generate_execution_code(self, code):
3552 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3553 self.cond.generate_evaluation_code(code)
3555 "if (unlikely(!%s)) {" %
3558 self.value.generate_evaluation_code(code)
3560 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3561 self.value.py_result())
3562 self.value.generate_disposal_code(code)
3563 self.value.free_temps(code)
3566 "PyErr_SetNone(PyExc_AssertionError);")
3568 code.error_goto(self.pos))
3571 self.cond.generate_disposal_code(code)
3572 self.cond.free_temps(code)
3573 code.putln("#endif")
3575 def annotate(self, code):
3576 self.cond.annotate(code)
3578 self.value.annotate(code)
3581 class IfStatNode(StatNode):
3584 # if_clauses [IfClauseNode]
3585 # else_clause StatNode or None
3587 child_attrs = ["if_clauses", "else_clause"]
3589 def analyse_control_flow(self, env):
3590 env.start_branching(self.pos)
3591 for if_clause in self.if_clauses:
3592 if_clause.analyse_control_flow(env)
3593 env.next_branch(if_clause.end_pos())
3594 if self.else_clause:
3595 self.else_clause.analyse_control_flow(env)
3596 env.finish_branching(self.end_pos())
3598 def analyse_declarations(self, env):
3599 for if_clause in self.if_clauses:
3600 if_clause.analyse_declarations(env)
3601 if self.else_clause:
3602 self.else_clause.analyse_declarations(env)
3604 def analyse_expressions(self, env):
3605 for if_clause in self.if_clauses:
3606 if_clause.analyse_expressions(env)
3607 if self.else_clause:
3608 self.else_clause.analyse_expressions(env)
3610 def generate_execution_code(self, code):
3611 code.mark_pos(self.pos)
3612 end_label = code.new_label()
3613 for if_clause in self.if_clauses:
3614 if_clause.generate_execution_code(code, end_label)
3615 if self.else_clause:
3616 code.putln("/*else*/ {")
3617 self.else_clause.generate_execution_code(code)
3619 code.put_label(end_label)
3621 def annotate(self, code):
3622 for if_clause in self.if_clauses:
3623 if_clause.annotate(code)
3624 if self.else_clause:
3625 self.else_clause.annotate(code)
3628 class IfClauseNode(Node):
3629 # if or elif clause in an if statement
3631 # condition ExprNode
3634 child_attrs = ["condition", "body"]
3636 def analyse_control_flow(self, env):
3637 self.body.analyse_control_flow(env)
3639 def analyse_declarations(self, env):
3640 self.condition.analyse_declarations(env)
3641 self.body.analyse_declarations(env)
3643 def analyse_expressions(self, env):
3645 self.condition.analyse_temp_boolean_expression(env)
3646 self.condition.release_temp(env)
3647 self.body.analyse_expressions(env)
3649 def generate_execution_code(self, code, end_label):
3650 self.condition.generate_evaluation_code(code)
3653 self.condition.result())
3654 self.condition.generate_disposal_code(code)
3655 self.condition.free_temps(code)
3656 self.body.generate_execution_code(code)
3660 code.put_goto(end_label)
3663 def annotate(self, code):
3664 self.condition.annotate(code)
3665 self.body.annotate(code)
3668 class SwitchCaseNode(StatNode):
3669 # Generated in the optimization of an if-elif-else node
3671 # conditions [ExprNode]
3674 child_attrs = ['conditions', 'body']
3676 def generate_execution_code(self, code):
3677 for cond in self.conditions:
3678 code.mark_pos(cond.pos)
3679 cond.generate_evaluation_code(code)
3680 code.putln("case %s:" % cond.result())
3681 self.body.generate_execution_code(code)
3682 code.putln("break;")
3684 def annotate(self, code):
3685 for cond in self.conditions:
3687 self.body.annotate(code)
3689 class SwitchStatNode(StatNode):
3690 # Generated in the optimization of an if-elif-else node
3693 # cases [SwitchCaseNode]
3694 # else_clause StatNode or None
3696 child_attrs = ['test', 'cases', 'else_clause']
3698 def generate_execution_code(self, code):
3699 code.putln("switch (%s) {" % self.test.result())
3700 for case in self.cases:
3701 case.generate_execution_code(code)
3702 if self.else_clause is not None:
3703 code.putln("default:")
3704 self.else_clause.generate_execution_code(code)
3705 code.putln("break;")
3708 def annotate(self, code):
3709 self.test.annotate(code)
3710 for case in self.cases:
3712 if self.else_clause is not None:
3713 self.else_clause.annotate(code)
3715 class LoopNode(object):
3717 def analyse_control_flow(self, env):
3718 env.start_branching(self.pos)
3719 self.body.analyse_control_flow(env)
3720 env.next_branch(self.body.end_pos())
3721 if self.else_clause:
3722 self.else_clause.analyse_control_flow(env)
3723 env.finish_branching(self.end_pos())
3726 class WhileStatNode(LoopNode, StatNode):
3729 # condition ExprNode
3731 # else_clause StatNode
3733 child_attrs = ["condition", "body", "else_clause"]
3735 def analyse_declarations(self, env):
3736 self.body.analyse_declarations(env)
3737 if self.else_clause:
3738 self.else_clause.analyse_declarations(env)
3740 def analyse_expressions(self, env):
3742 self.condition.analyse_temp_boolean_expression(env)
3743 self.condition.release_temp(env)
3744 #env.recycle_pending_temps() # TEMPORARY
3745 self.body.analyse_expressions(env)
3746 if self.else_clause:
3747 self.else_clause.analyse_expressions(env)
3749 def generate_execution_code(self, code):
3750 old_loop_labels = code.new_loop_labels()
3753 self.condition.generate_evaluation_code(code)
3754 self.condition.generate_disposal_code(code)
3757 self.condition.result())
3758 self.condition.free_temps(code)
3759 self.body.generate_execution_code(code)
3760 code.put_label(code.continue_label)
3762 break_label = code.break_label
3763 code.set_loop_labels(old_loop_labels)
3764 if self.else_clause:
3765 code.putln("/*else*/ {")
3766 self.else_clause.generate_execution_code(code)
3768 code.put_label(break_label)
3770 def annotate(self, code):
3771 self.condition.annotate(code)
3772 self.body.annotate(code)
3773 if self.else_clause:
3774 self.else_clause.annotate(code)
3777 def ForStatNode(pos, **kw):
3778 if 'iterator' in kw:
3779 return ForInStatNode(pos, **kw)
3781 return ForFromStatNode(pos, **kw)
3783 class ForInStatNode(LoopNode, StatNode):
3787 # iterator IteratorNode
3789 # else_clause StatNode
3790 # item NextNode used internally
3792 child_attrs = ["target", "iterator", "body", "else_clause"]
3795 def analyse_declarations(self, env):
3796 self.target.analyse_target_declaration(env)
3797 self.body.analyse_declarations(env)
3798 if self.else_clause:
3799 self.else_clause.analyse_declarations(env)
3801 def analyse_expressions(self, env):
3803 self.target.analyse_target_types(env)
3804 self.iterator.analyse_expressions(env)
3805 self.item = ExprNodes.NextNode(self.iterator, env)
3806 self.item = self.item.coerce_to(self.target.type, env)
3807 self.item.allocate_temps(env)
3808 self.target.allocate_target_temps(env, self.item)
3809 #self.item.release_temp(env)
3810 #self.target.release_target_temp(env)
3811 self.body.analyse_expressions(env)
3812 if self.else_clause:
3813 self.else_clause.analyse_expressions(env)
3814 self.iterator.release_temp(env)
3816 def generate_execution_code(self, code):
3817 old_loop_labels = code.new_loop_labels()
3818 self.iterator.allocate_counter_temp(code)
3819 self.iterator.generate_evaluation_code(code)
3822 self.item.generate_evaluation_code(code)
3823 self.target.generate_assignment_code(self.item, code)
3824 self.body.generate_execution_code(code)
3825 code.put_label(code.continue_label)
3828 break_label = code.break_label
3829 code.set_loop_labels(old_loop_labels)
3830 if self.else_clause:
3831 code.putln("/*else*/ {")
3832 self.else_clause.generate_execution_code(code)
3834 code.put_label(break_label)
3835 self.iterator.release_counter_temp(code)
3836 self.iterator.generate_disposal_code(code)
3837 self.iterator.free_temps(code)
3839 def annotate(self, code):
3840 self.target.annotate(code)
3841 self.iterator.annotate(code)
3842 self.body.annotate(code)
3843 if self.else_clause:
3844 self.else_clause.annotate(code)
3845 self.item.annotate(code)
3848 class ForFromStatNode(LoopNode, StatNode):
3849 # for name from expr rel name rel expr
3856 # step ExprNode or None
3858 # else_clause StatNode or None
3864 # loopvar_node ExprNode (usually a NameNode or temp node)
3865 # py_loopvar_node PyTempNode or None
3866 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3868 is_py_target = False
3870 py_loopvar_node = None
3873 def analyse_declarations(self, env):
3874 self.target.analyse_target_declaration(env)
3875 self.body.analyse_declarations(env)
3876 if self.else_clause:
3877 self.else_clause.analyse_declarations(env)
3879 def analyse_expressions(self, env):
3881 self.target.analyse_target_types(env)
3882 self.bound1.analyse_types(env)
3883 self.bound2.analyse_types(env)
3884 if self.step is not None:
3885 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3886 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3887 self.step.analyse_types(env)
3889 target_type = self.target.type
3890 if self.target.type.is_numeric:
3891 loop_type = self.target.type
3893 loop_type = PyrexTypes.c_int_type
3894 if not self.bound1.type.is_pyobject:
3895 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3896 if not self.bound2.type.is_pyobject:
3897 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3898 if self.step is not None and not self.step.type.is_pyobject:
3899 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3900 self.bound1 = self.bound1.coerce_to(loop_type, env)
3901 self.bound2 = self.bound2.coerce_to(loop_type, env)
3902 if not self.bound2.is_literal:
3903 self.bound2 = self.bound2.coerce_to_temp(env)
3904 if self.step is not None:
3905 self.step = self.step.coerce_to(loop_type, env)
3906 if not self.step.is_literal:
3907 self.step = self.step.coerce_to_temp(env)
3909 target_type = self.target.type
3910 if not (target_type.is_pyobject or target_type.is_numeric):
3911 error(self.target.pos,
3912 "for-from loop variable must be c numeric type or Python object")
3913 if target_type.is_numeric:
3914 self.is_py_target = False
3915 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3916 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3917 self.loopvar_node = self.target
3918 self.py_loopvar_node = None
3920 self.is_py_target = True
3921 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3922 c_loopvar_node.allocate_temps(env)
3923 self.loopvar_node = c_loopvar_node
3924 self.py_loopvar_node = \
3925 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3926 self.bound1.allocate_temps(env)
3927 self.bound2.allocate_temps(env)
3928 if self.step is not None:
3929 self.step.allocate_temps(env)
3930 if self.is_py_target:
3931 self.py_loopvar_node.allocate_temps(env)
3932 self.target.allocate_target_temps(env, self.py_loopvar_node)
3933 #self.target.release_target_temp(env)
3934 #self.py_loopvar_node.release_temp(env)
3935 self.body.analyse_expressions(env)
3936 if self.is_py_target:
3937 c_loopvar_node.release_temp(env)
3938 if self.else_clause:
3939 self.else_clause.analyse_expressions(env)
3940 self.bound1.release_temp(env)
3941 self.bound2.release_temp(env)
3942 if self.step is not None:
3943 self.step.release_temp(env)
3945 def generate_execution_code(self, code):
3946 old_loop_labels = code.new_loop_labels()
3947 from_range = self.from_range
3948 self.bound1.generate_evaluation_code(code)
3949 self.bound2.generate_evaluation_code(code)
3950 offset, incop = self.relation_table[self.relation1]
3951 if self.step is not None:
3952 self.step.generate_evaluation_code(code)
3953 step = self.step.result()
3954 incop = "%s=%s" % (incop[0], step)
3956 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3957 self.loopvar_node.allocate(code)
3958 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3959 self.py_loopvar_node.allocate(code)
3961 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3963 loopvar_name = self.loopvar_node.result()
3965 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3967 self.bound1.result(), offset,
3968 loopvar_name, self.relation2, self.bound2.result(),
3969 loopvar_name, incop))
3970 if self.py_loopvar_node:
3971 self.py_loopvar_node.generate_evaluation_code(code)
3972 self.target.generate_assignment_code(self.py_loopvar_node, code)
3974 code.putln("%s = %s;" % (
3975 self.target.result(), loopvar_name))
3976 self.body.generate_execution_code(code)
3977 code.put_label(code.continue_label)
3978 if self.py_loopvar_node:
3979 # Reassign py variable to loop var here.
3980 # (For consistancy, should rarely come up in practice.)
3982 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, self.target, None)
3983 from_py_node.temp_code = loopvar_name
3984 from_py_node.generate_result_code(code)
3986 if self.py_loopvar_node:
3987 # This is potentially wasteful, but we don't want the semantics to
3988 # depend on whether or not the loop is a python type.
3989 self.py_loopvar_node.generate_evaluation_code(code)
3990 self.target.generate_assignment_code(self.py_loopvar_node, code)
3991 break_label = code.break_label
3992 code.set_loop_labels(old_loop_labels)
3993 if self.else_clause:
3994 code.putln("/*else*/ {")
3995 self.else_clause.generate_execution_code(code)
3997 code.put_label(break_label)
3998 self.bound1.generate_disposal_code(code)
3999 self.bound1.free_temps(code)
4000 self.bound2.generate_disposal_code(code)
4001 self.bound2.free_temps(code)
4002 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4003 self.loopvar_node.release(code)
4004 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4005 self.py_loopvar_node.release(code)
4006 if self.step is not None:
4007 self.step.generate_disposal_code(code)
4008 self.step.free_temps(code)
4010 code.funcstate.release_temp(loopvar_name)
4013 # {relop : (initial offset, increment op)}
4020 def annotate(self, code):
4021 self.target.annotate(code)
4022 self.bound1.annotate(code)
4023 self.bound2.annotate(code)
4025 self.bound2.annotate(code)
4026 self.body.annotate(code)
4027 if self.else_clause:
4028 self.else_clause.annotate(code)
4031 class WithStatNode(StatNode):
4033 Represents a Python with statement.
4035 This is only used at parse tree level; and is not present in
4036 analysis or generation phases.
4038 # manager The with statement manager object
4039 # target Node (lhs expression)
4041 child_attrs = ["manager", "target", "body"]
4043 class TryExceptStatNode(StatNode):
4044 # try .. except statement
4047 # except_clauses [ExceptClauseNode]
4048 # else_clause StatNode or None
4049 # cleanup_list [Entry] old style temps to clean up on error
4051 child_attrs = ["body", "except_clauses", "else_clause"]
4053 def analyse_control_flow(self, env):
4054 env.start_branching(self.pos)
4055 self.body.analyse_control_flow(env)
4056 successful_try = env.control_flow # grab this for later
4057 env.next_branch(self.body.end_pos())
4058 env.finish_branching(self.body.end_pos())
4060 env.start_branching(self.except_clauses[0].pos)
4061 for except_clause in self.except_clauses:
4062 except_clause.analyse_control_flow(env)
4063 env.next_branch(except_clause.end_pos())
4065 # the else cause it executed only when the try clause finishes
4066 env.control_flow.incoming = successful_try
4067 if self.else_clause:
4068 self.else_clause.analyse_control_flow(env)
4069 env.finish_branching(self.end_pos())
4071 def analyse_declarations(self, env):
4072 self.body.analyse_declarations(env)
4073 for except_clause in self.except_clauses:
4074 except_clause.analyse_declarations(env)
4075 if self.else_clause:
4076 self.else_clause.analyse_declarations(env)
4077 env.use_utility_code(reset_exception_utility_code)
4079 def analyse_expressions(self, env):
4080 self.body.analyse_expressions(env)
4081 self.cleanup_list = env.free_temp_entries[:]
4082 default_clause_seen = 0
4083 for except_clause in self.except_clauses:
4084 except_clause.analyse_expressions(env)
4085 if default_clause_seen:
4086 error(except_clause.pos, "default 'except:' must be last")
4087 if not except_clause.pattern:
4088 default_clause_seen = 1
4089 self.has_default_clause = default_clause_seen
4090 if self.else_clause:
4091 self.else_clause.analyse_expressions(env)
4093 gil_check = StatNode._gil_check
4094 gil_message = "Try-except statement"
4096 def generate_execution_code(self, code):
4097 old_return_label = code.return_label
4098 old_break_label = code.break_label
4099 old_continue_label = code.continue_label
4100 old_error_label = code.new_error_label()
4101 our_error_label = code.error_label
4102 except_end_label = code.new_label('exception_handled')
4103 except_error_label = code.new_label('except_error')
4104 except_return_label = code.new_label('except_return')
4105 try_return_label = code.new_label('try_return')
4106 try_break_label = code.new_label('try_break')
4107 try_continue_label = code.new_label('try_continue')
4108 try_end_label = code.new_label('try_end')
4111 code.putln("PyObject %s;" %
4112 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4113 code.putln("__Pyx_ExceptionSave(%s);" %
4114 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4115 for var in Naming.exc_save_vars:
4116 code.put_xgotref(var)
4119 code.return_label = try_return_label
4120 code.break_label = try_break_label
4121 code.continue_label = try_continue_label
4122 self.body.generate_execution_code(code)
4125 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4126 code.error_label = except_error_label
4127 code.return_label = except_return_label
4128 if self.else_clause:
4131 self.else_clause.generate_execution_code(code)
4134 for var in Naming.exc_save_vars:
4135 code.put_xdecref_clear(var, py_object_type)
4136 code.put_goto(try_end_label)
4137 if code.label_used(try_return_label):
4138 code.put_label(try_return_label)
4139 for var in Naming.exc_save_vars:
4140 code.put_xdecref_clear(var, py_object_type)
4141 code.put_goto(old_return_label)
4142 code.put_label(our_error_label)
4143 code.put_var_xdecrefs_clear(self.cleanup_list)
4144 for temp_name, type in temps_to_clean_up:
4145 code.put_xdecref_clear(temp_name, type)
4146 for except_clause in self.except_clauses:
4147 except_clause.generate_handling_code(code, except_end_label)
4149 error_label_used = code.label_used(except_error_label)
4150 if error_label_used or not self.has_default_clause:
4151 if error_label_used:
4152 code.put_label(except_error_label)
4153 for var in Naming.exc_save_vars:
4154 code.put_xdecref(var, py_object_type)
4155 code.put_goto(old_error_label)
4157 if code.label_used(try_break_label):
4158 code.put_label(try_break_label)
4159 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4160 code.putln("__Pyx_ExceptionReset(%s);" %
4161 ', '.join(Naming.exc_save_vars))
4162 code.put_goto(old_break_label)
4164 if code.label_used(try_continue_label):
4165 code.put_label(try_continue_label)
4166 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4167 code.putln("__Pyx_ExceptionReset(%s);" %
4168 ', '.join(Naming.exc_save_vars))
4169 code.put_goto(old_continue_label)
4171 if code.label_used(except_return_label):
4172 code.put_label(except_return_label)
4173 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4174 code.putln("__Pyx_ExceptionReset(%s);" %
4175 ', '.join(Naming.exc_save_vars))
4176 code.put_goto(old_return_label)
4178 if code.label_used(except_end_label):
4179 code.put_label(except_end_label)
4180 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4181 code.putln("__Pyx_ExceptionReset(%s);" %
4182 ', '.join(Naming.exc_save_vars))
4183 code.put_label(try_end_label)
4186 code.return_label = old_return_label
4187 code.break_label = old_break_label
4188 code.continue_label = old_continue_label
4189 code.error_label = old_error_label
4191 def annotate(self, code):
4192 self.body.annotate(code)
4193 for except_node in self.except_clauses:
4194 except_node.annotate(code)
4195 if self.else_clause:
4196 self.else_clause.annotate(code)
4199 class ExceptClauseNode(Node):
4200 # Part of try ... except statement.
4203 # target ExprNode or None
4205 # excinfo_target NameNode or None optional target for exception info
4206 # match_flag string result of exception match
4207 # exc_value ExcValueNode used internally
4208 # function_name string qualified name of enclosing function
4209 # exc_vars (string * 3) local exception variables
4211 # excinfo_target is never set by the parser, but can be set by a transform
4212 # in order to extract more extensive information about the exception as a
4213 # sys.exc_info()-style tuple into a target variable
4215 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4218 excinfo_target = None
4220 def analyse_declarations(self, env):
4222 self.target.analyse_target_declaration(env)
4223 if self.excinfo_target is not None:
4224 self.excinfo_target.analyse_target_declaration(env)
4225 self.body.analyse_declarations(env)
4227 def analyse_expressions(self, env):
4229 genv = env.global_scope()
4230 self.function_name = env.qualified_name
4232 self.pattern.analyse_expressions(env)
4233 self.pattern = self.pattern.coerce_to_pyobject(env)
4234 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4235 self.pattern.release_temp(env)
4236 env.release_temp(self.match_flag)
4238 if self.target or self.excinfo_target:
4239 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4241 self.exc_vars = None
4244 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4245 self.exc_value.allocate_temps(env)
4246 self.target.analyse_target_expression(env, self.exc_value)
4247 if self.excinfo_target is not None:
4249 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4250 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4251 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4252 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4254 self.excinfo_tuple.analyse_expressions(env)
4255 self.excinfo_tuple.allocate_temps(env)
4256 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4258 self.body.analyse_expressions(env)
4261 for var in self.exc_vars:
4262 env.release_temp(var)
4264 def generate_handling_code(self, code, end_label):
4265 code.mark_pos(self.pos)
4267 self.pattern.generate_evaluation_code(code)
4269 "%s = PyErr_ExceptionMatches(%s);" % (
4271 self.pattern.py_result()))
4272 self.pattern.generate_disposal_code(code)
4273 self.pattern.free_temps(code)
4278 code.putln("/*except:*/ {")
4281 exc_vars = self.exc_vars
4282 elif not getattr(self.body, 'stats', True):
4283 # most simple case: no exception variable, empty body (pass)
4284 # => reset the exception state, done
4285 code.putln("PyErr_Restore(0,0,0);")
4286 code.put_goto(end_label)
4290 # during type analysis, we didn't know if we need the
4291 # exception value, but apparently, we do
4292 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4296 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4297 # We always have to fetch the exception value even if
4298 # there is no target, because this also normalises the
4299 # exception and stores it in the thread state.
4300 code.globalstate.use_utility_code(get_exception_utility_code)
4301 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4302 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4303 code.error_goto(self.pos)))
4307 self.exc_value.generate_evaluation_code(code)
4308 self.target.generate_assignment_code(self.exc_value, code)
4309 if self.excinfo_target is not None:
4310 self.excinfo_tuple.generate_evaluation_code(code)
4311 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4314 old_break_label, old_continue_label = code.break_label, code.continue_label
4315 code.break_label = code.new_label('except_break')
4316 code.continue_label = code.new_label('except_continue')
4318 old_exc_vars = code.funcstate.exc_vars
4319 code.funcstate.exc_vars = exc_vars
4320 self.body.generate_execution_code(code)
4321 code.funcstate.exc_vars = old_exc_vars
4322 for var in exc_vars:
4323 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4324 code.put_goto(end_label)
4326 if code.label_used(code.break_label):
4327 code.put_label(code.break_label)
4328 for var in exc_vars:
4329 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4330 code.put_goto(old_break_label)
4331 code.break_label = old_break_label
4333 if code.label_used(code.continue_label):
4334 code.put_label(code.continue_label)
4335 for var in exc_vars:
4336 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4337 code.put_goto(old_continue_label)
4338 code.continue_label = old_continue_label
4340 if not self.exc_vars:
4341 # clean up locally allocated temps
4342 for temp in exc_vars:
4343 code.funcstate.release_temp(temp)
4348 def annotate(self, code):
4350 self.pattern.annotate(code)
4352 self.target.annotate(code)
4353 self.body.annotate(code)
4356 class TryFinallyStatNode(StatNode):
4357 # try ... finally statement
4360 # finally_clause StatNode
4362 # cleanup_list [Entry] old_style temps to clean up on error
4364 # The plan is that we funnel all continue, break
4365 # return and error gotos into the beginning of the
4366 # finally block, setting a variable to remember which
4367 # one we're doing. At the end of the finally block, we
4368 # switch on the variable to figure out where to go.
4369 # In addition, if we're doing an error, we save the
4370 # exception on entry to the finally block and restore
4373 child_attrs = ["body", "finally_clause"]
4375 preserve_exception = 1
4377 disallow_continue_in_try_finally = 0
4378 # There doesn't seem to be any point in disallowing
4379 # continue in the try block, since we have no problem
4382 def create_analysed(pos, env, body, finally_clause):
4383 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4384 node.cleanup_list = []
4386 create_analysed = staticmethod(create_analysed)
4388 def analyse_control_flow(self, env):
4389 env.start_branching(self.pos)
4390 self.body.analyse_control_flow(env)
4391 env.next_branch(self.body.end_pos())
4392 env.finish_branching(self.body.end_pos())
4393 self.finally_clause.analyse_control_flow(env)
4395 def analyse_declarations(self, env):
4396 self.body.analyse_declarations(env)
4397 self.finally_clause.analyse_declarations(env)
4399 def analyse_expressions(self, env):
4400 self.body.analyse_expressions(env)
4401 self.cleanup_list = env.free_temp_entries[:]
4402 self.finally_clause.analyse_expressions(env)
4404 gil_check = StatNode._gil_check
4405 gil_message = "Try-finally statement"
4407 def generate_execution_code(self, code):
4408 old_error_label = code.error_label
4409 old_labels = code.all_new_labels()
4410 new_labels = code.get_all_labels()
4411 new_error_label = code.error_label
4412 catch_label = code.new_label()
4415 if self.disallow_continue_in_try_finally:
4416 was_in_try_finally = code.funcstate.in_try_finally
4417 code.funcstate.in_try_finally = 1
4418 self.body.generate_execution_code(code)
4419 if self.disallow_continue_in_try_finally:
4420 code.funcstate.in_try_finally = was_in_try_finally
4423 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4427 error_label_used = 0
4428 for i, new_label in enumerate(new_labels):
4429 if new_label in code.labels_used:
4430 cases_used.append(i)
4431 if new_label == new_error_label:
4432 error_label_used = 1
4433 error_label_case = i
4437 if error_label_used and self.preserve_exception:
4439 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4441 "int %s;" % Naming.exc_lineno_name)
4442 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4443 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4444 code.putln(exc_var_init_zero)
4446 exc_var_init_zero = None
4447 code.use_label(catch_label)
4449 "__pyx_why = 0; goto %s;" % catch_label)
4450 for i in cases_used:
4451 new_label = new_labels[i]
4452 #if new_label and new_label != "<try>":
4453 if new_label == new_error_label and self.preserve_exception:
4454 self.put_error_catcher(code,
4455 new_error_label, i+1, catch_label, temps_to_clean_up)
4457 code.put('%s: ' % new_label)
4458 if exc_var_init_zero:
4459 code.putln(exc_var_init_zero)
4460 code.putln("__pyx_why = %s; goto %s;" % (
4463 code.put_label(catch_label)
4464 code.set_all_labels(old_labels)
4465 if error_label_used:
4466 code.new_error_label()
4467 finally_error_label = code.error_label
4468 self.finally_clause.generate_execution_code(code)
4469 if error_label_used:
4470 if finally_error_label in code.labels_used and self.preserve_exception:
4471 over_label = code.new_label()
4472 code.put_goto(over_label);
4473 code.put_label(finally_error_label)
4474 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4475 for var in Naming.exc_vars:
4476 code.putln("Py_XDECREF(%s);" % var)
4478 code.put_goto(old_error_label)
4479 code.put_label(over_label)
4480 code.error_label = old_error_label
4483 "switch (__pyx_why) {")
4484 for i in cases_used:
4485 old_label = old_labels[i]
4486 if old_label == old_error_label and self.preserve_exception:
4487 self.put_error_uncatcher(code, i+1, old_error_label)
4489 code.use_label(old_label)
4491 "case %s: goto %s;" % (
4499 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4500 code.globalstate.use_utility_code(restore_exception_utility_code)
4507 code.put_var_xdecrefs_clear(self.cleanup_list)
4508 for temp_name, type in temps_to_clean_up:
4509 code.put_xdecref_clear(temp_name, type)
4511 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4515 Naming.exc_lineno_name, Naming.lineno_cname))
4519 code.put_goto(catch_label)
4523 def put_error_uncatcher(self, code, i, error_label):
4524 code.globalstate.use_utility_code(restore_exception_utility_code)
4529 "__Pyx_ErrRestore(%s, %s, %s);" %
4533 Naming.lineno_cname, Naming.exc_lineno_name))
4534 for var in Naming.exc_vars:
4538 code.put_goto(error_label)
4542 def annotate(self, code):
4543 self.body.annotate(code)
4544 self.finally_clause.annotate(code)
4547 class GILStatNode(TryFinallyStatNode):
4548 # 'with gil' or 'with nogil' statement
4550 # state string 'gil' or 'nogil'
4554 preserve_exception = 0
4556 def __init__(self, pos, state, body):
4558 TryFinallyStatNode.__init__(self, pos,
4560 finally_clause = GILExitNode(pos, state = state))
4562 def analyse_expressions(self, env):
4563 env.use_utility_code(force_init_threads_utility_code)
4564 was_nogil = env.nogil
4566 TryFinallyStatNode.analyse_expressions(self, env)
4567 env.nogil = was_nogil
4569 def gil_check(self, env):
4572 def generate_execution_code(self, code):
4573 code.mark_pos(self.pos)
4574 if self.state == 'gil':
4575 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4577 code.putln("{ PyThreadState *_save;")
4578 code.putln("Py_UNBLOCK_THREADS")
4579 TryFinallyStatNode.generate_execution_code(self, code)
4583 class GILExitNode(StatNode):
4584 # Used as the 'finally' block in a GILStatNode
4586 # state string 'gil' or 'nogil'
4590 def analyse_expressions(self, env):
4593 def generate_execution_code(self, code):
4594 if self.state == 'gil':
4595 code.putln("PyGILState_Release();")
4597 code.putln("Py_BLOCK_THREADS")
4600 class CImportStatNode(StatNode):
4603 # module_name string Qualified name of module being imported
4604 # as_name string or None Name specified in "as" clause, if any
4608 def analyse_declarations(self, env):
4609 if not env.is_module_scope:
4610 error(self.pos, "cimport only allowed at module level")
4612 module_scope = env.find_module(self.module_name, self.pos)
4613 if "." in self.module_name:
4614 names = [EncodedString(name) for name in self.module_name.split(".")]
4616 top_module_scope = env.context.find_submodule(top_name)
4617 module_scope = top_module_scope
4618 for name in names[1:]:
4619 submodule_scope = module_scope.find_submodule(name)
4620 module_scope.declare_module(name, submodule_scope, self.pos)
4621 module_scope = submodule_scope
4623 env.declare_module(self.as_name, module_scope, self.pos)
4625 env.declare_module(top_name, top_module_scope, self.pos)
4627 name = self.as_name or self.module_name
4628 env.declare_module(name, module_scope, self.pos)
4630 def analyse_expressions(self, env):
4633 def generate_execution_code(self, code):
4637 class FromCImportStatNode(StatNode):
4638 # from ... cimport statement
4640 # module_name string Qualified name of module
4641 # imported_names [(pos, name, as_name, kind)] Names to be imported
4645 def analyse_declarations(self, env):
4646 if not env.is_module_scope:
4647 error(self.pos, "cimport only allowed at module level")
4649 module_scope = env.find_module(self.module_name, self.pos)
4650 env.add_imported_module(module_scope)
4651 for pos, name, as_name, kind in self.imported_names:
4653 for local_name, entry in module_scope.entries.items():
4654 env.add_imported_entry(local_name, entry, pos)
4656 entry = module_scope.lookup(name)
4658 if kind and not self.declaration_matches(entry, kind):
4659 entry.redeclared(pos)
4661 if kind == 'struct' or kind == 'union':
4662 entry = module_scope.declare_struct_or_union(name,
4663 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4664 elif kind == 'class':
4665 entry = module_scope.declare_c_class(name, pos = pos,
4666 module_name = self.module_name)
4668 error(pos, "Name '%s' not declared in module '%s'"
4669 % (name, self.module_name))
4672 local_name = as_name or name
4673 env.add_imported_entry(local_name, entry, pos)
4675 def declaration_matches(self, entry, kind):
4676 if not entry.is_type:
4680 if not type.is_extension_type:
4683 if not type.is_struct_or_union:
4685 if kind != type.kind:
4689 def analyse_expressions(self, env):
4692 def generate_execution_code(self, code):
4696 class FromImportStatNode(StatNode):
4697 # from ... import statement
4700 # items [(string, NameNode)]
4701 # interned_items [(string, NameNode, ExprNode)]
4702 # item PyTempNode used internally
4703 # import_star boolean used internally
4705 child_attrs = ["module"]
4708 def analyse_declarations(self, env):
4709 for name, target in self.items:
4711 if not env.is_module_scope:
4712 error(self.pos, "import * only allowed at module level")
4714 env.has_import_star = 1
4715 self.import_star = 1
4717 target.analyse_target_declaration(env)
4719 def analyse_expressions(self, env):
4721 self.module.analyse_expressions(env)
4722 self.item = ExprNodes.PyTempNode(self.pos, env)
4723 self.item.allocate_temp(env)
4724 self.interned_items = []
4725 for name, target in self.items:
4727 for _, entry in env.entries.items():
4728 if not entry.is_type and entry.type.is_extension_type:
4729 env.use_utility_code(ExprNodes.type_test_utility_code)
4732 entry = env.lookup(target.name)
4733 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4734 continue # already cimported
4735 target.analyse_target_expression(env, None)
4736 if target.type is py_object_type:
4739 coerced_item = self.item.coerce_to(target.type, env)
4740 self.interned_items.append(
4741 (name, target, coerced_item))
4742 #target.release_target_temp(env) # was release_temp ?!?
4743 self.module.release_temp(env)
4744 self.item.release_temp(env)
4746 def generate_execution_code(self, code):
4747 self.module.generate_evaluation_code(code)
4748 if self.import_star:
4750 'if (%s(%s) < 0) %s;' % (
4752 self.module.py_result(),
4753 code.error_goto(self.pos)))
4754 self.item.allocate(code)
4755 for name, target, coerced_item in self.interned_items:
4756 cname = code.intern_identifier(name)
4758 '%s = PyObject_GetAttr(%s, %s); %s' % (
4760 self.module.py_result(),
4762 code.error_goto_if_null(self.item.result(), self.pos)))
4763 code.put_gotref(self.item.py_result())
4764 if coerced_item is None:
4765 target.generate_assignment_code(self.item, code)
4767 coerced_item.allocate_temp_result(code)
4768 coerced_item.generate_result_code(code)
4769 target.generate_assignment_code(coerced_item, code)
4770 if self.item.result() != coerced_item.result():
4771 code.put_decref_clear(self.item.result(), self.item.type)
4772 self.item.release(code)
4773 self.module.generate_disposal_code(code)
4774 self.module.free_temps(code)
4778 #------------------------------------------------------------------------------------
4780 # Runtime support code
4782 #------------------------------------------------------------------------------------
4784 utility_function_predeclarations = \
4787 #define INLINE __inline__
4789 #define INLINE __inline
4794 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4798 static int %(skip_dispatch_cname)s = 0;
4800 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4802 if Options.gcc_branch_hints:
4803 branch_prediction_macros = \
4806 /* Test for GCC > 2.95 */
4807 #if __GNUC__ > 2 || \
4808 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4809 #define likely(x) __builtin_expect(!!(x), 1)
4810 #define unlikely(x) __builtin_expect(!!(x), 0)
4811 #else /* __GNUC__ > 2 ... */
4812 #define likely(x) (x)
4813 #define unlikely(x) (x)
4814 #endif /* __GNUC__ > 2 ... */
4815 #else /* __GNUC__ */
4816 #define likely(x) (x)
4817 #define unlikely(x) (x)
4818 #endif /* __GNUC__ */
4821 branch_prediction_macros = \
4823 #define likely(x) (x)
4824 #define unlikely(x) (x)
4827 #get_name_predeclaration = \
4828 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4830 #get_name_interned_predeclaration = \
4831 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4833 #------------------------------------------------------------------------------------
4835 printing_utility_code = UtilityCode(
4837 static int __Pyx_Print(PyObject *, int); /*proto*/
4838 #if PY_MAJOR_VERSION >= 3
4839 static PyObject* %s = 0;
4840 static PyObject* %s = 0;
4842 """ % (Naming.print_function, Naming.print_function_kwargs),
4844 #if PY_MAJOR_VERSION < 3
4845 static PyObject *__Pyx_GetStdout(void) {
4846 PyObject *f = PySys_GetObject((char *)"stdout");
4848 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4853 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4858 if (!(f = __Pyx_GetStdout()))
4860 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4861 if (PyFile_SoftSpace(f, 1)) {
4862 if (PyFile_WriteString(" ", f) < 0)
4865 v = PyTuple_GET_ITEM(arg_tuple, i);
4866 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4868 if (PyString_Check(v)) {
4869 char *s = PyString_AsString(v);
4870 Py_ssize_t len = PyString_Size(v);
4872 isspace(Py_CHARMASK(s[len-1])) &&
4874 PyFile_SoftSpace(f, 0);
4878 if (PyFile_WriteString("\n", f) < 0)
4880 PyFile_SoftSpace(f, 0);
4885 #else /* Python 3 has a print function */
4887 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4888 PyObject* kwargs = 0;
4889 PyObject* result = 0;
4890 PyObject* end_string;
4891 if (!%(PRINT_FUNCTION)s) {
4892 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4893 if (!%(PRINT_FUNCTION)s)
4897 if (!%(PRINT_KWARGS)s) {
4898 %(PRINT_KWARGS)s = PyDict_New();
4899 if (!%(PRINT_KWARGS)s)
4901 end_string = PyUnicode_FromStringAndSize(" ", 1);
4904 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4905 Py_DECREF(end_string);
4908 Py_DECREF(end_string);
4910 kwargs = %(PRINT_KWARGS)s;
4912 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4920 """ % {'BUILTINS' : Naming.builtins_cname,
4921 'PRINT_FUNCTION' : Naming.print_function,
4922 'PRINT_KWARGS' : Naming.print_function_kwargs}
4926 printing_one_utility_code = UtilityCode(
4928 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4931 #if PY_MAJOR_VERSION < 3
4933 static int __Pyx_PrintOne(PyObject *o) {
4935 if (!(f = __Pyx_GetStdout()))
4937 if (PyFile_SoftSpace(f, 0)) {
4938 if (PyFile_WriteString(" ", f) < 0)
4941 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4943 if (PyFile_WriteString("\n", f) < 0)
4946 /* the line below is just to avoid compiler
4947 * compiler warnings about unused functions */
4948 return __Pyx_Print(NULL, 0);
4951 #else /* Python 3 has a print function */
4953 static int __Pyx_PrintOne(PyObject *o) {
4955 PyObject* arg_tuple = PyTuple_New(1);
4956 if (unlikely(!arg_tuple))
4959 PyTuple_SET_ITEM(arg_tuple, 0, o);
4960 res = __Pyx_Print(arg_tuple, 1);
4961 Py_DECREF(arg_tuple);
4967 requires=[printing_utility_code])
4971 #------------------------------------------------------------------------------------
4973 # The following function is based on do_raise() from ceval.c.
4975 raise_utility_code = UtilityCode(
4977 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4980 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4984 /* First, check the traceback argument, replacing None with NULL. */
4985 if (tb == Py_None) {
4989 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4990 PyErr_SetString(PyExc_TypeError,
4991 "raise: arg 3 must be a traceback or None");
4994 /* Next, replace a missing value with None */
4995 if (value == NULL) {
4999 #if PY_VERSION_HEX < 0x02050000
5000 if (!PyClass_Check(type))
5002 if (!PyType_Check(type))
5005 /* Raising an instance. The value should be a dummy. */
5006 if (value != Py_None) {
5007 PyErr_SetString(PyExc_TypeError,
5008 "instance exception may not have a separate value");
5011 /* Normalize to raise <class>, <instance> */
5014 #if PY_VERSION_HEX < 0x02050000
5015 if (PyInstance_Check(type)) {
5016 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5021 PyErr_SetString(PyExc_TypeError,
5022 "raise: exception must be an old-style class or instance");
5026 type = (PyObject*) Py_TYPE(type);
5028 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5029 PyErr_SetString(PyExc_TypeError,
5030 "raise: exception class must be a subclass of BaseException");
5035 __Pyx_ErrRestore(type, value, tb);
5045 #------------------------------------------------------------------------------------
5047 reraise_utility_code = UtilityCode(
5049 static void __Pyx_ReRaise(void); /*proto*/
5052 static void __Pyx_ReRaise(void) {
5053 PyThreadState *tstate = PyThreadState_GET();
5054 PyObject* tmp_type = tstate->curexc_type;
5055 PyObject* tmp_value = tstate->curexc_value;
5056 PyObject* tmp_tb = tstate->curexc_traceback;
5057 tstate->curexc_type = tstate->exc_type;
5058 tstate->curexc_value = tstate->exc_value;
5059 tstate->curexc_traceback = tstate->exc_traceback;
5060 tstate->exc_type = 0;
5061 tstate->exc_value = 0;
5062 tstate->exc_traceback = 0;
5063 Py_XDECREF(tmp_type);
5064 Py_XDECREF(tmp_value);
5069 #------------------------------------------------------------------------------------
5071 arg_type_test_utility_code = UtilityCode(
5073 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5074 const char *name, int exact); /*proto*/
5077 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5078 const char *name, int exact)
5081 PyErr_Format(PyExc_SystemError, "Missing type object");
5084 if (none_allowed && obj == Py_None) return 1;
5086 if (Py_TYPE(obj) == type) return 1;
5089 if (PyObject_TypeCheck(obj, type)) return 1;
5091 PyErr_Format(PyExc_TypeError,
5092 "Argument '%s' has incorrect type (expected %s, got %s)",
5093 name, type->tp_name, Py_TYPE(obj)->tp_name);
5098 #------------------------------------------------------------------------------------
5100 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5101 # many or too few positional arguments were found. This handles
5102 # Py_ssize_t formatting correctly.
5104 raise_argtuple_invalid_utility_code = UtilityCode(
5106 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5107 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5110 static void __Pyx_RaiseArgtupleInvalid(
5111 const char* func_name,
5115 Py_ssize_t num_found)
5117 Py_ssize_t num_expected;
5118 const char *number, *more_or_less;
5120 if (num_found < num_min) {
5121 num_expected = num_min;
5122 more_or_less = "at least";
5124 num_expected = num_max;
5125 more_or_less = "at most";
5128 more_or_less = "exactly";
5130 number = (num_expected == 1) ? "" : "s";
5131 PyErr_Format(PyExc_TypeError,
5132 #if PY_VERSION_HEX < 0x02050000
5133 "%s() takes %s %d positional argument%s (%d given)",
5135 "%s() takes %s %zd positional argument%s (%zd given)",
5137 func_name, more_or_less, num_expected, number, num_found);
5141 raise_keyword_required_utility_code = UtilityCode(
5143 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5146 static INLINE void __Pyx_RaiseKeywordRequired(
5147 const char* func_name,
5150 PyErr_Format(PyExc_TypeError,
5151 #if PY_MAJOR_VERSION >= 3
5152 "%s() needs keyword-only argument %U", func_name, kw_name);
5154 "%s() needs keyword-only argument %s", func_name,
5155 PyString_AS_STRING(kw_name));
5160 raise_double_keywords_utility_code = UtilityCode(
5162 static void __Pyx_RaiseDoubleKeywordsError(
5163 const char* func_name, PyObject* kw_name); /*proto*/
5166 static void __Pyx_RaiseDoubleKeywordsError(
5167 const char* func_name,
5170 PyErr_Format(PyExc_TypeError,
5171 #if PY_MAJOR_VERSION >= 3
5172 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5174 "%s() got multiple values for keyword argument '%s'", func_name,
5175 PyString_AS_STRING(kw_name));
5180 #------------------------------------------------------------------------------------
5182 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5183 # were passed to a function, or if any keywords were passed to a
5184 # function that does not accept them.
5186 keyword_string_check_utility_code = UtilityCode(
5188 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5189 const char* function_name, int kw_allowed); /*proto*/
5192 static INLINE int __Pyx_CheckKeywordStrings(
5194 const char* function_name,
5199 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5200 #if PY_MAJOR_VERSION < 3
5201 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5203 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5205 goto invalid_keyword_type;
5207 if ((!kw_allowed) && unlikely(key))
5208 goto invalid_keyword;
5210 invalid_keyword_type:
5211 PyErr_Format(PyExc_TypeError,
5212 "%s() keywords must be strings", function_name);
5215 PyErr_Format(PyExc_TypeError,
5216 #if PY_MAJOR_VERSION < 3
5217 "%s() got an unexpected keyword argument '%s'",
5218 function_name, PyString_AsString(key));
5220 "%s() got an unexpected keyword argument '%U'",
5221 function_name, key);
5227 #------------------------------------------------------------------------------------
5229 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5230 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5231 # keywords will raise an invalid keyword error.
5233 # Three kinds of errors are checked: 1) non-string keywords, 2)
5234 # unexpected keywords and 3) overlap with positional arguments.
5236 # If num_posargs is greater 0, it denotes the number of positional
5237 # arguments that were passed and that must therefore not appear
5238 # amongst the keywords as well.
5240 # This method does not check for required keyword arguments.
5243 parse_keywords_utility_code = UtilityCode(
5245 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5246 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5247 const char* function_name); /*proto*/
5250 static int __Pyx_ParseOptionalKeywords(
5252 PyObject **argnames[],
5255 Py_ssize_t num_pos_args,
5256 const char* function_name)
5258 PyObject *key = 0, *value = 0;
5261 PyObject*** first_kw_arg = argnames + num_pos_args;
5263 while (PyDict_Next(kwds, &pos, &key, &value)) {
5264 name = first_kw_arg;
5265 while (*name && (**name != key)) name++;
5267 values[name-argnames] = value;
5269 #if PY_MAJOR_VERSION < 3
5270 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5272 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5274 goto invalid_keyword_type;
5276 for (name = first_kw_arg; *name; name++) {
5277 #if PY_MAJOR_VERSION >= 3
5278 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5279 PyUnicode_Compare(**name, key) == 0) break;
5281 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5282 _PyString_Eq(**name, key)) break;
5286 values[name-argnames] = value;
5288 /* unexpected keyword found */
5289 for (name=argnames; name != first_kw_arg; name++) {
5290 if (**name == key) goto arg_passed_twice;
5291 #if PY_MAJOR_VERSION >= 3
5292 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5293 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5295 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5296 _PyString_Eq(**name, key)) goto arg_passed_twice;
5300 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5302 goto invalid_keyword;
5310 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5312 invalid_keyword_type:
5313 PyErr_Format(PyExc_TypeError,
5314 "%s() keywords must be strings", function_name);
5317 PyErr_Format(PyExc_TypeError,
5318 #if PY_MAJOR_VERSION < 3
5319 "%s() got an unexpected keyword argument '%s'",
5320 function_name, PyString_AsString(key));
5322 "%s() got an unexpected keyword argument '%U'",
5323 function_name, key);
5330 #------------------------------------------------------------------------------------
5332 traceback_utility_code = UtilityCode(
5334 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5337 #include "compile.h"
5338 #include "frameobject.h"
5339 #include "traceback.h"
5341 static void __Pyx_AddTraceback(const char *funcname) {
5342 PyObject *py_srcfile = 0;
5343 PyObject *py_funcname = 0;
5344 PyObject *py_globals = 0;
5345 PyObject *empty_string = 0;
5346 PyCodeObject *py_code = 0;
5347 PyFrameObject *py_frame = 0;
5349 #if PY_MAJOR_VERSION < 3
5350 py_srcfile = PyString_FromString(%(FILENAME)s);
5352 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5354 if (!py_srcfile) goto bad;
5356 #if PY_MAJOR_VERSION < 3
5357 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5359 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5363 #if PY_MAJOR_VERSION < 3
5364 py_funcname = PyString_FromString(funcname);
5366 py_funcname = PyUnicode_FromString(funcname);
5369 if (!py_funcname) goto bad;
5370 py_globals = PyModule_GetDict(%(GLOBALS)s);
5371 if (!py_globals) goto bad;
5372 #if PY_MAJOR_VERSION < 3
5373 empty_string = PyString_FromStringAndSize("", 0);
5375 empty_string = PyBytes_FromStringAndSize("", 0);
5377 if (!empty_string) goto bad;
5378 py_code = PyCode_New(
5379 0, /*int argcount,*/
5380 #if PY_MAJOR_VERSION >= 3
5381 0, /*int kwonlyargcount,*/
5384 0, /*int stacksize,*/
5386 empty_string, /*PyObject *code,*/
5387 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5388 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5389 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5390 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5391 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5392 py_srcfile, /*PyObject *filename,*/
5393 py_funcname, /*PyObject *name,*/
5394 %(LINENO)s, /*int firstlineno,*/
5395 empty_string /*PyObject *lnotab*/
5397 if (!py_code) goto bad;
5398 py_frame = PyFrame_New(
5399 PyThreadState_GET(), /*PyThreadState *tstate,*/
5400 py_code, /*PyCodeObject *code,*/
5401 py_globals, /*PyObject *globals,*/
5402 0 /*PyObject *locals*/
5404 if (!py_frame) goto bad;
5405 py_frame->f_lineno = %(LINENO)s;
5406 PyTraceBack_Here(py_frame);
5408 Py_XDECREF(py_srcfile);
5409 Py_XDECREF(py_funcname);
5410 Py_XDECREF(empty_string);
5411 Py_XDECREF(py_code);
5412 Py_XDECREF(py_frame);
5415 'FILENAME': Naming.filename_cname,
5416 'LINENO': Naming.lineno_cname,
5417 'CFILENAME': Naming.cfilenm_cname,
5418 'CLINENO': Naming.clineno_cname,
5419 'GLOBALS': Naming.module_cname,
5420 'EMPTY_TUPLE' : Naming.empty_tuple,
5423 restore_exception_utility_code = UtilityCode(
5425 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5426 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5429 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5430 PyObject *tmp_type, *tmp_value, *tmp_tb;
5431 PyThreadState *tstate = PyThreadState_GET();
5433 #if PY_MAJOR_VERSION >= 3
5434 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5435 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5436 tmp_type = tstate->exc_type;
5437 tmp_value = tstate->exc_value;
5438 tmp_tb = tstate->exc_traceback;
5439 PyErr_NormalizeException(&type, &value, &tb);
5440 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5441 tstate->exc_type = 0;
5442 tstate->exc_value = 0;
5443 tstate->exc_traceback = 0;
5444 PyException_SetContext(value, tmp_value);
5445 Py_DECREF(tmp_type);
5450 tmp_type = tstate->curexc_type;
5451 tmp_value = tstate->curexc_value;
5452 tmp_tb = tstate->curexc_traceback;
5453 tstate->curexc_type = type;
5454 tstate->curexc_value = value;
5455 tstate->curexc_traceback = tb;
5456 Py_XDECREF(tmp_type);
5457 Py_XDECREF(tmp_value);
5461 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5462 PyThreadState *tstate = PyThreadState_GET();
5463 *type = tstate->curexc_type;
5464 *value = tstate->curexc_value;
5465 *tb = tstate->curexc_traceback;
5467 tstate->curexc_type = 0;
5468 tstate->curexc_value = 0;
5469 tstate->curexc_traceback = 0;
5474 #------------------------------------------------------------------------------------
5476 unraisable_exception_utility_code = UtilityCode(
5478 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5481 static void __Pyx_WriteUnraisable(const char *name) {
5482 PyObject *old_exc, *old_val, *old_tb;
5484 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5485 #if PY_MAJOR_VERSION < 3
5486 ctx = PyString_FromString(name);
5488 ctx = PyUnicode_FromString(name);
5490 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5492 PyErr_WriteUnraisable(Py_None);
5494 PyErr_WriteUnraisable(ctx);
5499 requires=[restore_exception_utility_code])
5501 #------------------------------------------------------------------------------------
5503 set_vtable_utility_code = UtilityCode(
5505 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5508 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5509 PyObject *pycobj = 0;
5512 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5515 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5528 #------------------------------------------------------------------------------------
5530 get_vtable_utility_code = UtilityCode(
5532 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5535 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5539 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5542 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5543 if (!*(void **)vtabptr)
5556 #------------------------------------------------------------------------------------
5558 init_string_tab_utility_code = UtilityCode(
5560 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5563 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5565 #if PY_MAJOR_VERSION < 3
5566 if (t->is_unicode && (!t->is_identifier)) {
5567 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5568 } else if (t->intern) {
5569 *t->p = PyString_InternFromString(t->s);
5571 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5573 #else /* Python 3+ has unicode identifiers */
5574 if (t->is_identifier || (t->is_unicode && t->intern)) {
5575 *t->p = PyUnicode_InternFromString(t->s);
5576 } else if (t->is_unicode) {
5577 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5579 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5590 #------------------------------------------------------------------------------------
5592 get_exception_utility_code = UtilityCode(
5594 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5597 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5598 PyObject *tmp_type, *tmp_value, *tmp_tb;
5599 PyThreadState *tstate = PyThreadState_GET();
5600 *type = tstate->curexc_type;
5601 *value = tstate->curexc_value;
5602 *tb = tstate->curexc_traceback;
5603 tstate->curexc_type = 0;
5604 tstate->curexc_value = 0;
5605 tstate->curexc_traceback = 0;
5606 PyErr_NormalizeException(type, value, tb);
5607 if (PyErr_Occurred())
5612 tmp_type = tstate->exc_type;
5613 tmp_value = tstate->exc_value;
5614 tmp_tb = tstate->exc_traceback;
5615 tstate->exc_type = *type;
5616 tstate->exc_value = *value;
5617 tstate->exc_traceback = *tb;
5618 /* Make sure tstate is in a consistent state when we XDECREF
5619 these objects (XDECREF may run arbitrary code). */
5620 Py_XDECREF(tmp_type);
5621 Py_XDECREF(tmp_value);
5633 #------------------------------------------------------------------------------------
5635 reset_exception_utility_code = UtilityCode(
5637 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5638 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5641 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5642 PyThreadState *tstate = PyThreadState_GET();
5643 *type = tstate->exc_type;
5644 *value = tstate->exc_value;
5645 *tb = tstate->exc_traceback;
5651 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5652 PyObject *tmp_type, *tmp_value, *tmp_tb;
5653 PyThreadState *tstate = PyThreadState_GET();
5654 tmp_type = tstate->exc_type;
5655 tmp_value = tstate->exc_value;
5656 tmp_tb = tstate->exc_traceback;
5657 tstate->exc_type = type;
5658 tstate->exc_value = value;
5659 tstate->exc_traceback = tb;
5660 Py_XDECREF(tmp_type);
5661 Py_XDECREF(tmp_value);
5666 #------------------------------------------------------------------------------------
5668 force_init_threads_utility_code = UtilityCode(
5670 #ifndef __PYX_FORCE_INIT_THREADS
5671 #if PY_VERSION_HEX < 0x02040200
5672 #define __PYX_FORCE_INIT_THREADS 1
5674 #define __PYX_FORCE_INIT_THREADS 0
5679 #------------------------------------------------------------------------------------