2 # Pyrex - Parse tree nodes
5 import string, sys, os, time, copy
8 from Errors import error, warning, InternalError
12 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
13 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
14 StructOrUnionScope, PyClassScope, CClassScope
15 from Cython.Utils import open_new_file, replace_suffix
16 from StringEncoding import EncodedString, escape_byte_string, split_docstring
20 from DebugFlags import debug_disposal_code
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 # pos (string, int, int) Source file position
72 # is_name boolean Is a NameNode
73 # is_literal boolean Is a ConstNode
74 # options dict Compiler directives in effect for this node
81 # All descandants should set child_attrs to a list of the attributes
82 # containing nodes considered "children" in the tree. Each such attribute
83 # can either contain a single node or a list of nodes. See Visitor.py.
86 def __init__(self, pos, **kw):
88 self.__dict__.update(kw)
90 gil_message = "Operation"
92 def gil_check(self, env):
97 error(self.pos, "%s not allowed without gil" % self.gil_message)
100 """Clone the node. This is defined as a shallow copy, except for member lists
101 amongst the child attributes (from get_child_accessors) which are also
102 copied. Lists containing child nodes are thus seen as a way for the node
103 to hold multiple children directly; the list is not treated as a seperate
104 level in the tree."""
105 result = copy.copy(self)
106 for attrname in result.child_attrs:
107 value = getattr(result, attrname)
108 if isinstance(value, list):
109 setattr(result, attrname, [x for x in value])
114 # There are 4 phases of parse tree processing, applied in order to
115 # all the statements in a given scope-block:
117 # (0) analyse_control_flow
118 # Create the control flow tree into which state can be asserted and
121 # (1) analyse_declarations
122 # Make symbol table entries for all declarations at the current
123 # level, both explicit (def, cdef, etc.) and implicit (assignment
124 # to an otherwise undeclared name).
126 # (2) analyse_expressions
127 # Determine the result types of expressions and fill in the
128 # 'type' attribute of each ExprNode. Insert coercion nodes into the
129 # tree where needed to convert to and from Python objects.
130 # Allocate temporary locals for intermediate results. Fill
131 # in the 'result_code' attribute of each ExprNode with a C code
135 # Emit C code for all declarations, statements and expressions.
136 # Recursively applies the 3 processing phases to the bodies of
140 def analyse_control_flow(self, env):
143 def analyse_declarations(self, env):
146 def analyse_expressions(self, env):
147 raise InternalError("analyse_expressions not implemented for %s" % \
148 self.__class__.__name__)
150 def generate_code(self, code):
151 raise InternalError("generate_code not implemented for %s" % \
152 self.__class__.__name__)
154 def annotate(self, code):
155 # mro does the wrong thing
156 if isinstance(self, BlockNode):
157 self.body.annotate(code)
160 if not self.child_attrs:
164 except AttributeError:
166 for attr in self.child_attrs:
167 child = getattr(self, attr)
168 # Sometimes lists, sometimes nodes
171 elif isinstance(child, list):
173 pos = max(pos, c.end_pos())
175 pos = max(pos, child.end_pos())
179 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
181 return "<...nesting level cutoff...>"
182 if encountered is None:
184 if id(self) in encountered:
185 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
186 encountered.add(id(self))
188 def dump_child(x, level):
189 if isinstance(x, Node):
190 return x.dump(level, filter_out, cutoff-1, encountered)
191 elif isinstance(x, list):
192 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
197 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
199 return "<%s (%d)>" % (self.__class__.__name__, id(self))
202 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
203 for key, value in attrs:
204 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
205 res += "%s>" % indent
209 # Mixin class for nodes representing a declaration block.
211 def generate_const_definitions(self, env, code):
212 if env.const_entries:
213 for entry in env.const_entries:
214 if not entry.is_interned:
215 code.globalstate.add_const_definition(entry)
217 def generate_interned_string_decls(self, env, code):
218 entries = env.global_scope().new_interned_string_entries
220 for entry in entries:
221 code.globalstate.add_interned_string_decl(entry)
224 def generate_py_string_decls(self, env, code):
226 return # earlier error
227 entries = env.pystring_entries
229 for entry in entries:
230 if not entry.is_interned:
231 code.globalstate.add_py_string_decl(entry)
233 def generate_interned_num_decls(self, env, code):
234 # Flush accumulated interned nums from the global scope
235 # and generate declarations for them.
236 genv = env.global_scope()
237 entries = genv.interned_nums
239 for entry in entries:
240 code.globalstate.add_interned_num_decl(entry)
243 def generate_cached_builtins_decls(self, env, code):
244 entries = env.global_scope().undeclared_cached_builtins
245 for entry in entries:
246 code.globalstate.add_cached_builtin_decl(entry)
250 class StatListNode(Node):
251 # stats a list of StatNode
253 child_attrs = ["stats"]
255 def create_analysed(pos, env, *args, **kw):
256 node = StatListNode(pos, *args, **kw)
257 return node # No node-specific analysis necesarry
258 create_analysed = staticmethod(create_analysed)
260 def analyse_control_flow(self, env):
261 for stat in self.stats:
262 stat.analyse_control_flow(env)
264 def analyse_declarations(self, env):
265 #print "StatListNode.analyse_declarations" ###
266 for stat in self.stats:
267 stat.analyse_declarations(env)
269 def analyse_expressions(self, env):
270 #print "StatListNode.analyse_expressions" ###
271 for stat in self.stats:
272 stat.analyse_expressions(env)
274 def generate_function_definitions(self, env, code):
275 #print "StatListNode.generate_function_definitions" ###
276 for stat in self.stats:
277 stat.generate_function_definitions(env, code)
279 def generate_execution_code(self, code):
280 #print "StatListNode.generate_execution_code" ###
281 for stat in self.stats:
282 code.mark_pos(stat.pos)
283 stat.generate_execution_code(code)
285 def annotate(self, code):
286 for stat in self.stats:
290 class StatNode(Node):
292 # Code generation for statements is split into the following subphases:
294 # (1) generate_function_definitions
295 # Emit C code for the definitions of any structs,
296 # unions, enums and functions defined in the current
299 # (2) generate_execution_code
300 # Emit C code for executable statements.
303 def generate_function_definitions(self, env, code):
306 def generate_execution_code(self, code):
307 raise InternalError("generate_execution_code not implemented for %s" % \
308 self.__class__.__name__)
311 class CDefExternNode(StatNode):
312 # include_file string or None
315 child_attrs = ["body"]
317 def analyse_declarations(self, env):
318 if self.include_file:
319 env.add_include_file(self.include_file)
320 old_cinclude_flag = env.in_cinclude
322 self.body.analyse_declarations(env)
323 env.in_cinclude = old_cinclude_flag
325 def analyse_expressions(self, env):
328 def generate_execution_code(self, code):
331 def annotate(self, code):
332 self.body.annotate(code)
335 class CDeclaratorNode(Node):
336 # Part of a C declaration.
338 # Processing during analyse_declarations phase:
341 # Returns (name, type) pair where name is the
342 # CNameDeclaratorNode of the name being declared
343 # and type is the type it is being declared as.
345 # calling_convention string Calling convention of CFuncDeclaratorNode
346 # for which this is a base
350 calling_convention = ""
353 class CNameDeclaratorNode(CDeclaratorNode):
354 # name string The Pyrex name being declared
355 # cname string or None C name, if specified
356 # default ExprNode or None the value assigned on declaration
358 child_attrs = ['default']
362 def analyse(self, base_type, env, nonempty = 0):
363 if nonempty and self.name == '':
364 # May have mistaken the name for the type.
365 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
366 error(self.pos, "Missing argument name")
367 elif base_type.is_void:
368 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
369 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
370 base_type = py_object_type
371 self.type = base_type
372 return self, base_type
374 class CPtrDeclaratorNode(CDeclaratorNode):
375 # base CDeclaratorNode
377 child_attrs = ["base"]
379 def analyse(self, base_type, env, nonempty = 0):
380 if base_type.is_pyobject:
382 "Pointer base type cannot be a Python object")
383 ptr_type = PyrexTypes.c_ptr_type(base_type)
384 return self.base.analyse(ptr_type, env, nonempty = nonempty)
386 class CArrayDeclaratorNode(CDeclaratorNode):
387 # base CDeclaratorNode
390 child_attrs = ["base", "dimension"]
392 def analyse(self, base_type, env, nonempty = 0):
394 self.dimension.analyse_const_expression(env)
395 if not self.dimension.type.is_int:
396 error(self.dimension.pos, "Array dimension not integer")
397 size = self.dimension.result_code
400 if not base_type.is_complete():
402 "Array element type '%s' is incomplete" % base_type)
403 if base_type.is_pyobject:
405 "Array element cannot be a Python object")
406 if base_type.is_cfunction:
408 "Array element cannot be a function")
409 array_type = PyrexTypes.c_array_type(base_type, size)
410 return self.base.analyse(array_type, env, nonempty = nonempty)
413 class CFuncDeclaratorNode(CDeclaratorNode):
414 # base CDeclaratorNode
415 # args [CArgDeclNode]
416 # has_varargs boolean
417 # exception_value ConstNode
418 # exception_check boolean True if PyErr_Occurred check needed
419 # nogil boolean Can be called without gil
420 # with_gil boolean Acquire gil around function body
422 child_attrs = ["base", "args", "exception_value"]
425 optional_arg_count = 0
427 def analyse(self, return_type, env, nonempty = 0):
431 for arg_node in self.args:
432 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
433 name = name_declarator.name
434 if name_declarator.cname:
436 "Function argument cannot have C name specification")
437 # Turn *[] argument into **
439 type = PyrexTypes.c_ptr_type(type.base_type)
440 # Catch attempted C-style func(void) decl
442 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
443 # if type.is_pyobject and self.nogil:
445 # "Function with Python argument cannot be declared nogil")
446 func_type_args.append(
447 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
449 self.optional_arg_count += 1
450 elif self.optional_arg_count:
451 error(self.pos, "Non-default argument follows default argument")
453 if self.optional_arg_count:
454 scope = StructOrUnionScope()
455 scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
456 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
457 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
458 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
459 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
464 cname = struct_cname)
465 self.op_args_struct.defined_in_pxd = 1
466 self.op_args_struct.used = 1
470 if return_type.is_pyobject \
471 and (self.exception_value or self.exception_check) \
472 and self.exception_check != '+':
474 "Exception clause not allowed for function returning Python object")
476 if self.exception_value:
477 self.exception_value.analyse_const_expression(env)
478 if self.exception_check == '+':
479 exc_val_type = self.exception_value.type
480 if not exc_val_type.is_error and \
481 not exc_val_type.is_pyobject and \
482 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
483 error(self.exception_value.pos,
484 "Exception value must be a Python exception or cdef function with no arguments.")
485 exc_val = self.exception_value
487 exc_val = self.exception_value.result_code
488 if not return_type.assignable_from(self.exception_value.type):
489 error(self.exception_value.pos,
490 "Exception value incompatible with function return type")
491 exc_check = self.exception_check
492 if return_type.is_array:
494 "Function cannot return an array")
495 if return_type.is_cfunction:
497 "Function cannot return a function")
498 func_type = PyrexTypes.CFuncType(
499 return_type, func_type_args, self.has_varargs,
500 optional_arg_count = self.optional_arg_count,
501 exception_value = exc_val, exception_check = exc_check,
502 calling_convention = self.base.calling_convention,
503 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
504 if self.optional_arg_count:
505 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
506 return self.base.analyse(func_type, env)
509 class CArgDeclNode(Node):
510 # Item in a function declaration argument list.
512 # base_type CBaseTypeNode
513 # declarator CDeclaratorNode
514 # not_none boolean Tagged with 'not None'
515 # default ExprNode or None
516 # default_entry Symtab.Entry Entry for the variable holding the default value
517 # default_result_code string cname or code fragment for default value
518 # is_self_arg boolean Is the "self" arg of an extension type method
519 # is_kw_only boolean Is a keyword-only argument
521 child_attrs = ["base_type", "declarator", "default"]
526 def analyse(self, env, nonempty = 0):
527 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
528 base_type = self.base_type.analyse(env)
529 return self.declarator.analyse(base_type, env, nonempty = nonempty)
531 def annotate(self, code):
533 self.default.annotate(code)
536 class CBaseTypeNode(Node):
537 # Abstract base class for C base type nodes.
539 # Processing during analyse_declarations phase:
546 class CSimpleBaseTypeNode(CBaseTypeNode):
548 # module_path [string] Qualifying name components
549 # is_basic_c_type boolean
552 # is_self_arg boolean Is self argument of C method
556 def analyse(self, env):
557 # Return type descriptor.
558 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
560 if self.is_basic_c_type:
561 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
563 error(self.pos, "Unrecognised type modifier combination")
564 elif self.name == "object" and not self.module_path:
565 type = py_object_type
566 elif self.name is None:
567 if self.is_self_arg and env.is_c_class_scope:
568 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
569 type = env.parent_type
571 type = py_object_type
573 scope = env.find_imported_module(self.module_path, self.pos)
575 if scope.is_c_class_scope:
576 scope = scope.global_scope()
577 entry = scope.find(self.name, self.pos)
578 if entry and entry.is_type:
581 error(self.pos, "'%s' is not a type identifier" % self.name)
585 return PyrexTypes.error_type
587 class CBufferAccessTypeNode(CBaseTypeNode):
589 # positional_args [ExprNode] List of positional arguments
590 # keyword_args DictNode Keyword arguments
591 # base_type_node CBaseTypeNode
594 # type PyrexType.BufferType ...containing the right options
597 child_attrs = ["base_type_node", "positional_args",
598 "keyword_args", "dtype_node"]
602 def analyse(self, env):
603 base_type = self.base_type_node.analyse(env)
604 if base_type.is_error: return base_type
607 options = Buffer.analyse_buffer_options(
610 self.positional_args,
612 base_type.buffer_defaults)
614 self.type = PyrexTypes.BufferType(base_type, **options)
617 class CComplexBaseTypeNode(CBaseTypeNode):
618 # base_type CBaseTypeNode
619 # declarator CDeclaratorNode
621 child_attrs = ["base_type", "declarator"]
623 def analyse(self, env):
624 base = self.base_type.analyse(env)
625 _, type = self.declarator.analyse(base, env)
629 class CVarDefNode(StatNode):
630 # C variable definition or forward/extern function declaration.
632 # visibility 'private' or 'public' or 'extern'
633 # base_type CBaseTypeNode
634 # declarators [CDeclaratorNode]
637 # need_properties [entry]
639 child_attrs = ["base_type", "declarators"]
642 def analyse_declarations(self, env, dest_scope = None):
645 self.dest_scope = dest_scope
646 base_type = self.base_type.analyse(env)
647 if (dest_scope.is_c_class_scope
648 and self.visibility == 'public'
649 and base_type.is_pyobject
650 and (base_type.is_builtin_type or base_type.is_extension_type)):
651 self.need_properties = []
653 visibility = 'private'
655 need_property = False
656 visibility = self.visibility
658 for declarator in self.declarators:
659 name_declarator, type = declarator.analyse(base_type, env)
660 if not type.is_complete():
661 if not (self.visibility == 'extern' and type.is_array):
662 error(declarator.pos,
663 "Variable type '%s' is incomplete" % type)
664 if self.visibility == 'extern' and type.is_pyobject:
665 error(declarator.pos,
666 "Python object cannot be declared extern")
667 name = name_declarator.name
668 cname = name_declarator.cname
670 error(declarator.pos, "Missing name in declaration.")
672 if type.is_cfunction:
673 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
674 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
677 if self.in_pxd and self.visibility != 'extern':
679 "Only 'extern' C variable declaration allowed in .pxd file")
680 entry = dest_scope.declare_var(name, type, declarator.pos,
681 cname = cname, visibility = visibility, is_cdef = 1)
683 self.need_properties.append(entry)
684 entry.needs_property = 1
687 class CStructOrUnionDefNode(StatNode):
689 # cname string or None
690 # kind "struct" or "union"
691 # typedef_flag boolean
692 # visibility "public" or "private"
694 # attributes [CVarDefNode] or None
697 child_attrs = ["attributes"]
699 def analyse_declarations(self, env):
701 if self.attributes is not None:
702 scope = StructOrUnionScope(self.name)
703 self.entry = env.declare_struct_or_union(
704 self.name, self.kind, scope, self.typedef_flag, self.pos,
705 self.cname, visibility = self.visibility)
706 if self.attributes is not None:
707 if self.in_pxd and not env.in_cinclude:
708 self.entry.defined_in_pxd = 1
709 for attr in self.attributes:
710 attr.analyse_declarations(env, scope)
712 def analyse_expressions(self, env):
715 def generate_execution_code(self, code):
719 class CEnumDefNode(StatNode):
720 # name string or None
721 # cname string or None
722 # items [CEnumDefItemNode]
723 # typedef_flag boolean
724 # visibility "public" or "private"
728 child_attrs = ["items"]
730 def analyse_declarations(self, env):
731 self.entry = env.declare_enum(self.name, self.pos,
732 cname = self.cname, typedef_flag = self.typedef_flag,
733 visibility = self.visibility)
734 if self.items is not None:
735 if self.in_pxd and not env.in_cinclude:
736 self.entry.defined_in_pxd = 1
737 for item in self.items:
738 item.analyse_declarations(env, self.entry)
740 def analyse_expressions(self, env):
741 if self.visibility == 'public':
742 self.temp = env.allocate_temp_pyobject()
743 env.release_temp(self.temp)
745 def generate_execution_code(self, code):
746 if self.visibility == 'public':
747 for item in self.entry.enum_values:
748 code.putln("%s = PyInt_FromLong(%s); %s" % (
751 code.error_goto_if_null(self.temp, item.pos)))
752 code.putln('if (PyObject_SetAttrString(%s, "%s", %s) < 0) %s' % (
756 code.error_goto(item.pos)))
757 code.putln("%s = 0;" % self.temp)
760 class CEnumDefItemNode(StatNode):
762 # cname string or None
763 # value ExprNode or None
765 child_attrs = ["value"]
767 def analyse_declarations(self, env, enum_entry):
769 self.value.analyse_const_expression(env)
770 if not self.value.type.is_int:
771 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
772 self.value.analyse_const_expression(env)
773 value = self.value.result_code
776 entry = env.declare_const(self.name, enum_entry.type,
777 value, self.pos, cname = self.cname, visibility = enum_entry.visibility)
778 enum_entry.enum_values.append(entry)
781 class CTypeDefNode(StatNode):
782 # base_type CBaseTypeNode
783 # declarator CDeclaratorNode
784 # visibility "public" or "private"
787 child_attrs = ["base_type", "declarator"]
789 def analyse_declarations(self, env):
790 base = self.base_type.analyse(env)
791 name_declarator, type = self.declarator.analyse(base, env)
792 name = name_declarator.name
793 cname = name_declarator.cname
794 entry = env.declare_typedef(name, type, self.pos,
795 cname = cname, visibility = self.visibility)
796 if self.in_pxd and not env.in_cinclude:
797 entry.defined_in_pxd = 1
799 def analyse_expressions(self, env):
801 def generate_execution_code(self, code):
805 class FuncDefNode(StatNode, BlockNode):
806 # Base class for function definition nodes.
808 # return_type PyrexType
809 # #filename string C name of filename string const
811 # needs_closure boolean Whether or not this function has inner functions/classes/yield
815 needs_closure = False
817 def analyse_default_values(self, env):
818 genv = env.global_scope()
819 for arg in self.args:
822 if not hasattr(arg, 'default_entry'):
823 arg.default.analyse_types(env)
824 arg.default = arg.default.coerce_to(arg.type, genv)
825 if arg.default.is_literal:
826 arg.default_entry = arg.default
827 arg.default_result_code = arg.default.calculate_result_code()
828 if arg.default.type != arg.type and not arg.type.is_int:
829 arg.default_result_code = arg.type.cast_code(arg.default_result_code)
831 arg.default.allocate_temps(genv)
832 arg.default_entry = genv.add_default_value(arg.type)
833 arg.default_entry.used = 1
834 arg.default_result_code = arg.default_entry.cname
837 "This argument cannot have a default value")
840 def need_gil_acquisition(self, lenv):
843 def create_local_scope(self, env):
845 while env.is_py_class_scope or env.is_c_class_scope:
846 env = env.outer_scope
847 if self.needs_closure:
848 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
850 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
851 lenv.return_type = self.return_type
852 type = self.entry.type
853 if type.is_cfunction:
854 lenv.nogil = type.nogil and not type.with_gil
855 self.local_scope = lenv
858 def generate_function_definitions(self, env, code):
861 lenv = self.local_scope
863 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
864 self.entry.scope.is_c_class_scope)
866 # Generate C code for header and body of function
867 code.enter_cfunc_scope()
868 code.return_from_error_cleanup_label = code.new_label()
870 # ----- Top-level constants used by this function
871 code.mark_pos(self.pos)
872 self.generate_interned_num_decls(lenv, code)
873 self.generate_interned_string_decls(lenv, code)
874 self.generate_py_string_decls(lenv, code)
875 self.generate_cached_builtins_decls(lenv, code)
877 #code.put_var_declarations(lenv.const_entries, static = 1)
878 self.generate_const_definitions(lenv, code)
879 # ----- Function header
882 self.py_func.generate_function_header(code,
883 with_pymethdef = env.is_py_class_scope,
885 self.generate_function_header(code,
886 with_pymethdef = env.is_py_class_scope)
887 # ----- Local variable declarations
888 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
889 self.generate_argument_declarations(lenv, code)
890 if self.needs_closure:
891 code.putln("/* TODO: declare and create scope object */")
892 code.put_var_declarations(lenv.var_entries)
894 if not self.return_type.is_void:
897 (self.return_type.declaration_code(
898 Naming.retval_cname),
900 tempvardecl_code = code.insertion_point()
901 self.generate_keyword_list(code)
902 # ----- Extern library function declarations
903 lenv.generate_library_function_declarations(code)
904 # ----- GIL acquisition
905 acquire_gil = self.need_gil_acquisition(lenv)
907 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
908 # ----- Automatic lead-ins for certain special functions
909 if is_getbuffer_slot:
910 self.getbuffer_init(code)
911 # ----- Fetch arguments
912 self.generate_argument_parsing_code(env, code)
913 # If an argument is assigned to in the body, we must
914 # incref it to properly keep track of refcounts.
915 for entry in lenv.arg_entries:
916 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
917 code.put_var_incref(entry)
918 # ----- Initialise local variables
919 for entry in lenv.var_entries:
920 if entry.type.is_pyobject and entry.init_to_none and entry.used:
921 code.put_init_var_to_py_none(entry)
922 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
923 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
924 # ----- Check and convert arguments
925 self.generate_argument_type_tests(code)
926 # ----- Acquire buffer arguments
927 for entry in lenv.arg_entries:
928 if entry.type.is_buffer:
929 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
930 # ----- Function body
931 self.body.generate_execution_code(code)
932 # ----- Default return value
934 if self.return_type.is_pyobject:
935 #if self.return_type.is_extension_type:
936 # lhs = "(PyObject *)%s" % Naming.retval_cname
938 lhs = Naming.retval_cname
939 code.put_init_to_py_none(lhs, self.return_type)
941 val = self.return_type.default_value
943 code.putln("%s = %s;" % (Naming.retval_cname, val))
944 # ----- Error cleanup
945 if code.error_label in code.labels_used:
946 code.put_goto(code.return_label)
947 code.put_label(code.error_label)
948 code.put_var_xdecrefs(lenv.temp_entries)
950 # Clean up buffers -- this calls a Python function
951 # so need to save and restore error state
952 buffers_present = len(lenv.buffer_entries) > 0
954 code.globalstate.use_utility_code(restore_exception_utility_code)
955 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
956 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
957 for entry in lenv.buffer_entries:
958 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
959 #code.putln("%s = 0;" % entry.cname)
960 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
962 err_val = self.error_value()
963 exc_check = self.caller_will_check_exceptions()
964 if err_val is not None or exc_check:
965 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
967 warning(self.entry.pos, "Unraisable exception in function '%s'." \
968 % self.entry.qualified_name, 0)
970 '__Pyx_WriteUnraisable("%s");' %
971 self.entry.qualified_name)
972 env.use_utility_code(unraisable_exception_utility_code)
973 env.use_utility_code(restore_exception_utility_code)
974 default_retval = self.return_type.default_value
975 if err_val is None and default_retval:
976 err_val = default_retval
977 if err_val is not None:
983 if is_getbuffer_slot:
984 self.getbuffer_error_cleanup(code)
986 # If we are using the non-error cleanup section we should
987 # jump past it if we have an error. The if-test below determine
988 # whether this section is used.
989 if buffers_present or is_getbuffer_slot:
990 code.put_goto(code.return_from_error_cleanup_label)
993 # ----- Non-error return cleanup
994 # If you add anything here, remember to add a condition to the
995 # if-test above in the error block (so that it can jump past this
997 code.put_label(code.return_label)
998 for entry in lenv.buffer_entries:
1000 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1001 if is_getbuffer_slot:
1002 self.getbuffer_normal_cleanup(code)
1003 # ----- Return cleanup for both error and no-error return
1004 code.put_label(code.return_from_error_cleanup_label)
1005 if not Options.init_local_none:
1006 for entry in lenv.var_entries:
1007 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1008 entry.xdecref_cleanup = 1
1009 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1010 # Decref any increfed args
1011 for entry in lenv.arg_entries:
1012 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1013 code.put_var_decref(entry)
1015 code.putln("PyGILState_Release(_save);")
1016 # code.putln("/* TODO: decref scope object */")
1018 if not self.return_type.is_void:
1019 code.putln("return %s;" % Naming.retval_cname)
1021 # ----- Go back and insert temp variable declarations
1022 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1023 tempvardecl_code.put_temp_declarations(code.funcstate)
1024 # ----- Python version
1025 code.exit_cfunc_scope()
1027 self.py_func.generate_function_definitions(env, code)
1028 self.generate_optarg_wrapper_function(env, code)
1030 def declare_argument(self, env, arg):
1031 if arg.type.is_void:
1032 error(arg.pos, "Invalid use of 'void'")
1033 elif not arg.type.is_complete() and not arg.type.is_array:
1035 "Argument type '%s' is incomplete" % arg.type)
1036 return env.declare_arg(arg.name, arg.type, arg.pos)
1037 def generate_optarg_wrapper_function(self, env, code):
1040 def generate_execution_code(self, code):
1041 # Evaluate and store argument default values
1042 for arg in self.args:
1043 default = arg.default
1045 if not default.is_literal:
1046 default.generate_evaluation_code(code)
1047 default.make_owned_reference(code)
1050 arg.default_entry.cname,
1051 default.result_as(arg.default_entry.type)))
1052 if default.is_temp and default.type.is_pyobject:
1055 default.result_code)
1056 # For Python class methods, create and store function object
1058 self.assmt.generate_execution_code(code)
1061 # Special code for the __getbuffer__ function
1063 def getbuffer_init(self, code):
1064 info = self.local_scope.arg_entries[1].cname
1065 # Python 3.0 betas have a bug in memoryview which makes it call
1066 # getbuffer with a NULL parameter. For now we work around this;
1067 # the following line should be removed when this bug is fixed.
1068 code.putln("if (%s == NULL) return 0;" % info)
1069 code.putln("%s->obj = Py_None; Py_INCREF(Py_None);" % info)
1071 def getbuffer_error_cleanup(self, code):
1072 info = self.local_scope.arg_entries[1].cname
1073 code.putln("Py_DECREF(%s->obj); %s->obj = NULL;" %
1076 def getbuffer_normal_cleanup(self, code):
1077 info = self.local_scope.arg_entries[1].cname
1078 code.putln("if (%s->obj == Py_None) { Py_DECREF(Py_None); %s->obj = NULL; }" %
1081 class CFuncDefNode(FuncDefNode):
1082 # C function definition.
1084 # modifiers ['inline']
1085 # visibility 'private' or 'public' or 'extern'
1086 # base_type CBaseTypeNode
1087 # declarator CDeclaratorNode
1091 # with_gil boolean Acquire GIL around body
1093 # py_func wrapper for calling from Python
1095 child_attrs = ["base_type", "declarator", "body", "py_func"]
1097 def unqualified_name(self):
1098 return self.entry.name
1100 def analyse_declarations(self, env):
1101 base_type = self.base_type.analyse(env)
1102 # The 2 here is because we need both function and argument names.
1103 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1104 if not type.is_cfunction:
1106 "Suite attached to non-function declaration")
1107 # Remember the actual type according to the function header
1108 # written here, because the type in the symbol table entry
1109 # may be different if we're overriding a C method inherited
1110 # from the base type of an extension type.
1112 type.is_overridable = self.overridable
1113 declarator = self.declarator
1114 while not hasattr(declarator, 'args'):
1115 declarator = declarator.base
1116 self.args = declarator.args
1117 for formal_arg, type_arg in zip(self.args, type.args):
1118 formal_arg.type = type_arg.type
1119 formal_arg.cname = type_arg.cname
1120 name = name_declarator.name
1121 cname = name_declarator.cname
1122 self.entry = env.declare_cfunction(
1123 name, type, self.pos,
1124 cname = cname, visibility = self.visibility,
1125 defining = self.body is not None,
1127 self.return_type = type.return_type
1129 if self.overridable:
1131 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1132 self.py_func = DefNode(pos = self.pos,
1133 name = self.entry.name,
1136 starstar_arg = None,
1138 body = py_func_body,
1140 self.py_func.is_module_scope = env.is_module_scope
1141 self.py_func.analyse_declarations(env)
1142 self.entry.as_variable = self.py_func.entry
1143 # Reset scope entry the above cfunction
1144 env.entries[name] = self.entry
1145 self.py_func.interned_attr_cname = env.intern_identifier(
1146 self.py_func.entry.name)
1147 if not env.is_module_scope or Options.lookup_module_cpdef:
1148 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1149 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1151 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1153 args = self.type.args
1154 if omit_optional_args:
1155 args = args[:len(args) - self.type.optional_arg_count]
1156 arg_names = [arg.name for arg in args]
1158 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1160 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1161 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1162 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1163 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)
1164 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1166 def declare_arguments(self, env):
1167 for arg in self.type.args:
1169 error(arg.pos, "Missing argument name")
1170 self.declare_argument(env, arg)
1172 def need_gil_acquisition(self, lenv):
1174 with_gil = self.type.with_gil
1175 if type.nogil and not with_gil:
1176 if type.return_type.is_pyobject:
1178 "Function with Python return type cannot be declared nogil")
1179 for entry in lenv.var_entries + lenv.temp_entries:
1180 if entry.type.is_pyobject:
1181 error(self.pos, "Function declared nogil has Python locals or temporaries")
1184 def analyse_expressions(self, env):
1185 self.analyse_default_values(env)
1186 if self.overridable:
1187 self.py_func.analyse_expressions(env)
1189 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1):
1192 visibility = self.entry.visibility
1193 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1194 arg_decls.append(arg.declaration_code())
1195 if type.optional_arg_count and with_opt_args:
1196 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1197 if type.has_varargs:
1198 arg_decls.append("...")
1200 arg_decls = ["void"]
1201 cname = self.entry.func_cname
1202 if not with_opt_args:
1203 cname += Naming.no_opt_args
1204 entity = type.function_header_code(cname, string.join(arg_decls, ", "))
1205 if visibility == 'public':
1206 dll_linkage = "DL_EXPORT"
1209 header = self.return_type.declaration_code(entity,
1210 dll_linkage = dll_linkage)
1211 if visibility != 'private':
1212 storage_class = "%s " % Naming.extern_c_macro
1214 storage_class = "static "
1215 code.putln("%s%s %s {" % (
1217 ' '.join(self.modifiers).upper(), # macro forms
1220 def generate_argument_declarations(self, env, code):
1221 for arg in self.args:
1223 code.putln('%s = %s;' % (arg.type.declaration_code(arg.cname), arg.default_result_code))
1225 def generate_keyword_list(self, code):
1228 def generate_argument_parsing_code(self, env, code):
1230 if self.type.optional_arg_count:
1231 code.putln('if (%s) {' % Naming.optional_args_cname)
1232 for arg in self.args:
1234 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1235 declarator = arg.declarator
1236 while not hasattr(declarator, 'name'):
1237 declarator = declarator.base
1238 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1240 for _ in range(self.type.optional_arg_count):
1244 def generate_argument_conversion_code(self, code):
1247 def generate_argument_type_tests(self, code):
1248 # Generate type tests for args whose type in a parent
1249 # class is a supertype of the declared type.
1250 for arg in self.type.args:
1251 if arg.needs_type_test:
1252 self.generate_arg_type_test(arg, code)
1254 def generate_arg_type_test(self, arg, code):
1255 # Generate type test for one argument.
1256 if arg.type.typeobj_is_available():
1257 typeptr_cname = arg.type.typeptr_cname
1258 arg_code = "((PyObject *)%s)" % arg.cname
1260 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1265 type.is_builtin_type,
1266 code.error_goto(arg.pos)))
1268 error(arg.pos, "Cannot test type of extern C class "
1269 "without type object name specification")
1271 def error_value(self):
1272 if self.return_type.is_pyobject:
1276 return self.entry.type.exception_value
1278 def caller_will_check_exceptions(self):
1279 return self.entry.type.exception_check
1281 def generate_optarg_wrapper_function(self, env, code):
1282 if self.type.optional_arg_count and \
1283 self.type.original_sig and not self.type.original_sig.optional_arg_count:
1285 self.generate_function_header(code, 0, with_opt_args = 0)
1286 if not self.return_type.is_void:
1288 args = self.type.args
1289 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1290 arglist.append('NULL')
1291 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1295 class PyArgDeclNode(Node):
1296 # Argument which must be a Python object (used
1297 # for * and ** arguments).
1300 # entry Symtab.Entry
1304 class DecoratorNode(Node):
1307 # decorator NameNode or CallNode
1308 child_attrs = ['decorator']
1311 class DefNode(FuncDefNode):
1312 # A Python function definition.
1314 # name string the Python name of the function
1315 # decorators [DecoratorNode] list of decorators
1316 # args [CArgDeclNode] formal arguments
1317 # star_arg PyArgDeclNode or None * argument
1318 # starstar_arg PyArgDeclNode or None ** argument
1319 # doc EncodedString or None
1322 # The following subnode is constructed internally
1323 # when the def statement is inside a Python class definition.
1325 # assmt AssignmentNode Function construction/assignment
1327 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1331 num_required_kw_args = 0
1332 reqd_kw_flags_cname = "0"
1336 def __init__(self, pos, **kwds):
1337 FuncDefNode.__init__(self, pos, **kwds)
1339 for arg in self.args:
1346 self.num_kwonly_args = k
1347 self.num_required_kw_args = rk
1348 self.num_required_args = r
1352 def analyse_declarations(self, env):
1353 for arg in self.args:
1354 base_type = arg.base_type.analyse(env)
1355 name_declarator, type = \
1356 arg.declarator.analyse(base_type, env)
1357 arg.name = name_declarator.name
1358 if name_declarator.cname:
1360 "Python function argument cannot have C name specification")
1361 arg.type = type.as_argument_type()
1363 arg.needs_conversion = 0
1364 arg.needs_type_test = 0
1366 if arg.not_none and not arg.type.is_extension_type:
1368 "Only extension type arguments can have 'not None'")
1369 self.declare_pyfunction(env)
1370 self.analyse_signature(env)
1371 self.return_type = self.entry.signature.return_type()
1373 def analyse_signature(self, env):
1374 any_type_tests_needed = 0
1375 # Use the simpler calling signature for zero- and one-argument functions.
1376 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1377 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1378 if len(self.args) == 0:
1379 self.entry.signature = TypeSlots.pyfunction_noargs
1380 elif len(self.args) == 1:
1381 if self.args[0].default is None and not self.args[0].kw_only:
1382 self.entry.signature = TypeSlots.pyfunction_onearg
1383 elif self.entry.signature is TypeSlots.pymethod_signature:
1384 if len(self.args) == 1:
1385 self.entry.signature = TypeSlots.unaryfunc
1386 elif len(self.args) == 2:
1387 if self.args[1].default is None and not self.args[1].kw_only:
1388 self.entry.signature = TypeSlots.ibinaryfunc
1389 elif self.entry.is_special:
1390 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1391 sig = self.entry.signature
1392 nfixed = sig.num_fixed_args()
1393 for i in range(nfixed):
1394 if i < len(self.args):
1397 if sig.is_self_arg(i):
1399 arg.hdr_type = arg.type = env.parent_type
1400 arg.needs_conversion = 0
1402 arg.hdr_type = sig.fixed_arg_type(i)
1403 if not arg.type.same_as(arg.hdr_type):
1404 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1405 arg.needs_type_test = 1
1406 any_type_tests_needed = 1
1408 arg.needs_conversion = 1
1409 if arg.needs_conversion:
1410 arg.hdr_cname = Naming.arg_prefix + arg.name
1412 arg.hdr_cname = Naming.var_prefix + arg.name
1414 self.bad_signature()
1416 if nfixed < len(self.args):
1417 if not sig.has_generic_args:
1418 self.bad_signature()
1419 for arg in self.args:
1420 if arg.is_generic and \
1421 (arg.type.is_extension_type or arg.type.is_builtin_type):
1422 arg.needs_type_test = 1
1423 any_type_tests_needed = 1
1424 elif arg.type is PyrexTypes.c_py_ssize_t_type:
1425 # Want to use __index__ rather than __int__ method
1426 # that PyArg_ParseTupleAndKeywords calls
1427 arg.needs_conversion = 1
1428 arg.hdr_type = PyrexTypes.py_object_type
1429 arg.hdr_cname = Naming.arg_prefix + arg.name
1430 if any_type_tests_needed:
1431 env.use_utility_code(arg_type_test_utility_code)
1433 def bad_signature(self):
1434 sig = self.entry.signature
1435 expected_str = "%d" % sig.num_fixed_args()
1436 if sig.has_generic_args:
1437 expected_str = expected_str + " or more"
1439 if name.startswith("__") and name.endswith("__"):
1440 desc = "Special method"
1444 "%s %s has wrong number of arguments "
1445 "(%d declared, %s expected)" % (
1446 desc, self.name, len(self.args), expected_str))
1448 def signature_has_nongeneric_args(self):
1449 argcount = len(self.args)
1450 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1454 def signature_has_generic_args(self):
1455 return self.entry.signature.has_generic_args
1457 def declare_pyfunction(self, env):
1458 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1460 entry = env.lookup_here(self.name)
1461 if entry and entry.type.is_cfunction and not self.is_wrapper:
1462 warning(self.pos, "Overriding cdef method with def method.", 5)
1463 entry = env.declare_pyfunction(self.name, self.pos)
1465 prefix = env.scope_prefix
1466 entry.func_cname = \
1467 Naming.pyfunc_prefix + prefix + name
1468 entry.pymethdef_cname = \
1469 Naming.pymethdef_prefix + prefix + name
1470 if Options.docstrings:
1471 entry.doc = embed_position(self.pos, self.doc)
1473 Naming.funcdoc_prefix + prefix + name
1477 def declare_arguments(self, env):
1478 for arg in self.args:
1480 error(arg.pos, "Missing argument name")
1481 if arg.needs_conversion:
1482 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1483 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1484 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1485 if arg.type.is_pyobject:
1486 arg.entry.init = "0"
1487 arg.entry.init_to_none = 0
1489 arg.entry = self.declare_argument(env, arg)
1491 arg.entry.is_self_arg = arg.is_self_arg
1492 if not arg.is_self_arg:
1493 arg.name_entry = env.get_string_const(
1494 arg.name, identifier = True)
1495 env.add_py_string(arg.name_entry, identifier = True)
1497 if arg.is_self_arg or \
1498 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1499 arg.entry.is_declared_generic = 1
1500 self.declare_python_arg(env, self.star_arg)
1501 self.declare_python_arg(env, self.starstar_arg)
1503 def declare_python_arg(self, env, arg):
1505 entry = env.declare_var(arg.name,
1506 PyrexTypes.py_object_type, arg.pos)
1509 entry.init_to_none = 0
1510 entry.xdecref_cleanup = 1
1512 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1514 def analyse_expressions(self, env):
1515 self.analyse_default_values(env)
1516 if env.is_py_class_scope:
1517 self.synthesize_assignment_node(env)
1519 def synthesize_assignment_node(self, env):
1521 self.assmt = SingleAssignmentNode(self.pos,
1522 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1523 rhs = ExprNodes.UnboundMethodNode(self.pos,
1524 class_cname = env.class_obj_cname,
1525 function = ExprNodes.PyCFunctionNode(self.pos,
1526 pymethdef_cname = self.entry.pymethdef_cname)))
1527 self.assmt.analyse_declarations(env)
1528 self.assmt.analyse_expressions(env)
1530 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1532 sig = self.entry.signature
1533 if sig.has_dummy_arg:
1534 arg_code_list.append(
1535 "PyObject *%s" % Naming.self_cname)
1536 for arg in self.args:
1537 if not arg.is_generic:
1539 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1541 arg_code_list.append(
1542 arg.hdr_type.declaration_code(arg.hdr_cname))
1543 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1544 arg_code_list.append("PyObject *unused")
1545 if sig.has_generic_args:
1546 arg_code_list.append(
1547 "PyObject *%s, PyObject *%s"
1548 % (Naming.args_cname, Naming.kwds_cname))
1549 arg_code = ", ".join(arg_code_list)
1550 dc = self.return_type.declaration_code(self.entry.func_cname)
1551 header = "static %s(%s)" % (dc, arg_code)
1552 code.putln("%s; /*proto*/" % header)
1555 if self.entry.doc and Options.docstrings:
1556 docstr = self.entry.doc
1557 if not isinstance(docstr, str):
1558 docstr = docstr.utf8encode()
1560 'static char %s[] = "%s";' % (
1561 self.entry.doc_cname,
1562 split_docstring(escape_byte_string(docstr))))
1565 "static PyMethodDef %s = " %
1566 self.entry.pymethdef_cname)
1567 code.put_pymethoddef(self.entry, ";")
1568 code.putln("%s {" % header)
1570 def generate_argument_declarations(self, env, code):
1571 for arg in self.args:
1572 if arg.is_generic: # or arg.needs_conversion:
1573 if arg.needs_conversion:
1574 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1576 code.put_var_declaration(arg.entry)
1578 def generate_keyword_list(self, code):
1579 if self.signature_has_generic_args() and \
1580 self.signature_has_nongeneric_args():
1582 "static PyObject **%s[] = {" %
1583 Naming.pykwdlist_cname)
1584 for arg in self.args:
1586 code.put('&%s,' % arg.name_entry.pystring_cname)
1589 def generate_argument_parsing_code(self, env, code):
1590 # Generate PyArg_ParseTuple call for generic
1591 # arguments, if any.
1592 if self.entry.signature.has_dummy_arg:
1593 # get rid of unused argument warning
1594 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1596 old_error_label = code.new_error_label()
1597 our_error_label = code.error_label
1598 end_label = code.new_label("argument_unpacking_done")
1600 has_kwonly_args = self.num_kwonly_args > 0
1601 has_star_or_kw_args = self.star_arg is not None \
1602 or self.starstar_arg is not None or has_kwonly_args
1604 if not self.signature_has_generic_args():
1605 if has_star_or_kw_args:
1606 error(self.pos, "This method cannot have * or keyword arguments")
1607 self.generate_argument_conversion_code(code)
1609 elif not self.signature_has_nongeneric_args():
1610 # func(*args) or func(**kw) or func(*args, **kw)
1611 self.generate_stararg_copy_code(code)
1614 positional_args = []
1617 for arg in self.args:
1618 arg_entry = arg.entry
1624 arg.default_result_code))
1626 if not arg.is_self_arg:
1628 kw_only_args.append(arg)
1630 positional_args.append(arg)
1632 kw_only_args.append(arg)
1635 error(arg.pos, "Non-default argument following default argument")
1636 elif not arg.is_self_arg:
1637 positional_args.append(arg)
1638 if arg.needs_conversion:
1639 format = arg.hdr_type.parsetuple_format
1641 format = arg_entry.type.parsetuple_format
1644 "Cannot convert Python object argument to type '%s' (when parsing input arguments)"
1647 self.generate_tuple_and_keyword_parsing_code(
1648 positional_args, kw_only_args, end_label, code)
1650 code.error_label = old_error_label
1651 if code.label_used(our_error_label):
1652 if not code.label_used(end_label):
1653 code.put_goto(end_label)
1654 code.put_label(our_error_label)
1655 if has_star_or_kw_args:
1656 self.generate_arg_decref(self.star_arg, code)
1657 if self.starstar_arg:
1658 if self.starstar_arg.entry.xdecref_cleanup:
1659 code.put_var_xdecref(self.starstar_arg.entry)
1661 code.put_var_decref(self.starstar_arg.entry)
1662 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1663 code.putln("return %s;" % self.error_value())
1664 if code.label_used(end_label):
1665 code.put_label(end_label)
1667 def generate_arg_assignment(self, arg, item, code):
1668 if arg.type.is_pyobject:
1670 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1671 code.putln("%s = %s;" % (arg.entry.cname, item))
1673 func = arg.type.from_py_function
1675 code.putln("%s = %s(%s); %s" % (
1679 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1681 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1683 def generate_arg_xdecref(self, arg, code):
1685 code.put_var_xdecref(arg.entry)
1687 def generate_arg_decref(self, arg, code):
1689 code.put_var_decref(arg.entry)
1691 def generate_stararg_copy_code(self, code):
1692 if not self.star_arg:
1693 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1694 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1696 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1697 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1700 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1702 if self.starstar_arg:
1704 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1706 kwarg_check = "%s" % Naming.kwds_cname
1708 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1709 Naming.kwds_cname, Naming.kwds_cname)
1711 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1712 kwarg_check, Naming.kwds_cname, self.name,
1713 bool(self.starstar_arg), self.error_value()))
1715 if self.starstar_arg:
1716 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1717 self.starstar_arg.entry.cname,
1720 code.putln("if (unlikely(!%s)) return %s;" % (
1721 self.starstar_arg.entry.cname, self.error_value()))
1722 self.starstar_arg.entry.xdecref_cleanup = 0
1725 code.put_incref(Naming.args_cname, py_object_type)
1726 code.putln("%s = %s;" % (
1727 self.star_arg.entry.cname,
1729 self.star_arg.entry.xdecref_cleanup = 0
1731 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1732 kw_only_args, success_label, code):
1733 argtuple_error_label = code.new_label("argtuple_error")
1735 min_positional_args = self.num_required_args - self.num_required_kw_args
1736 if len(self.args) > 0 and self.args[0].is_self_arg:
1737 min_positional_args -= 1
1738 max_positional_args = len(positional_args)
1739 has_fixed_positional_count = not self.star_arg and \
1740 min_positional_args == max_positional_args
1742 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
1743 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1744 if self.num_required_kw_args:
1745 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
1747 if self.starstar_arg or self.star_arg:
1748 self.generate_stararg_init_code(max_positional_args, code)
1750 # --- optimised code when we receive keyword arguments
1751 if self.num_required_kw_args:
1752 code.putln("if (likely(%s)) {" % Naming.kwds_cname)
1754 code.putln("if (unlikely(%s) && (PyDict_Size(%s) > 0)) {" % (
1755 Naming.kwds_cname, Naming.kwds_cname))
1756 self.generate_keyword_unpacking_code(
1757 min_positional_args, max_positional_args,
1758 has_fixed_positional_count,
1759 positional_args, kw_only_args, argtuple_error_label, code)
1761 # --- optimised code when we do not receive any keyword arguments
1762 if min_positional_args > 0 or min_positional_args == max_positional_args:
1763 # Python raises arg tuple related errors first, so we must
1764 # check the length here
1765 if min_positional_args == max_positional_args and not self.star_arg:
1769 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
1770 Naming.args_cname, compare, min_positional_args))
1771 code.put_goto(argtuple_error_label)
1773 if self.num_required_kw_args:
1774 # pure error case: keywords required but not passed
1775 if max_positional_args > min_positional_args and not self.star_arg:
1776 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
1777 Naming.args_cname, max_positional_args))
1778 code.put_goto(argtuple_error_label)
1779 code.putln('} else {')
1780 for i, arg in enumerate(kw_only_args):
1782 # required keyword-only argument missing
1783 code.put('__Pyx_RaiseKeywordRequired("%s", *%s[%d]); ' % (
1784 self.name.utf8encode(), Naming.pykwdlist_cname,
1785 len(positional_args) + i))
1786 code.putln(code.error_goto(self.pos))
1788 elif min_positional_args == max_positional_args:
1789 # parse the exact number of positional arguments from the
1791 code.putln('} else {')
1792 for i, arg in enumerate(positional_args):
1793 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
1794 self.generate_arg_assignment(arg, item, code)
1796 # parse the positional arguments from the variable length
1798 code.putln('} else {')
1799 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
1800 reversed_args = list(enumerate(positional_args))[::-1]
1801 for i, arg in reversed_args:
1802 if i >= min_positional_args-1:
1803 if min_positional_args > 1:
1804 code.putln('case %2d:' % (i+1)) # pure code beautification
1806 code.put('case %2d: ' % (i+1))
1807 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
1808 self.generate_arg_assignment(arg, item, code)
1809 if not self.star_arg:
1810 if min_positional_args == 0:
1811 code.put('case 0: ')
1812 code.putln('break;')
1813 code.put('default: ')
1814 code.put_goto(argtuple_error_label)
1819 if code.label_used(argtuple_error_label):
1820 code.put_goto(success_label)
1821 code.put_label(argtuple_error_label)
1822 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
1823 self.name.utf8encode(), has_fixed_positional_count,
1824 min_positional_args, max_positional_args,
1826 code.putln(code.error_goto(self.pos))
1828 def generate_stararg_init_code(self, max_positional_args, code):
1829 if self.starstar_arg:
1830 self.starstar_arg.entry.xdecref_cleanup = 0
1831 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
1832 self.starstar_arg.entry.cname,
1833 self.starstar_arg.entry.cname,
1834 self.error_value()))
1836 self.star_arg.entry.xdecref_cleanup = 0
1837 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
1839 max_positional_args))
1840 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
1841 self.star_arg.entry.cname, Naming.args_cname,
1842 max_positional_args, Naming.args_cname))
1843 if self.starstar_arg:
1845 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
1846 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
1847 code.putln('return %s;' % self.error_value())
1850 code.putln("if (unlikely(!%s)) return %s;" % (
1851 self.star_arg.entry.cname, self.error_value()))
1852 code.putln('} else {')
1853 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
1854 code.put_incref(Naming.empty_tuple, py_object_type)
1857 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
1858 has_fixed_positional_count, positional_args,
1859 kw_only_args, argtuple_error_label, code):
1860 all_args = tuple(positional_args) + tuple(kw_only_args)
1861 max_args = len(all_args)
1863 code.putln("PyObject* values[%d] = {%s};" % (
1864 max_args, ('0,'*max_args)[:-1]))
1865 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
1868 # parse the tuple and check that it's not too long
1869 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
1871 code.putln('default:')
1872 for i in range(max_positional_args-1, -1, -1):
1873 code.put('case %2d: ' % (i+1))
1874 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
1875 i, Naming.args_cname, i))
1876 code.putln('case 0: break;')
1877 if not self.star_arg:
1878 code.put('default: ') # more arguments than allowed
1879 code.put_goto(argtuple_error_label)
1882 # now fill up the arguments with values from the kw dict
1883 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
1884 for i, arg in enumerate(all_args):
1885 if i <= max_positional_args:
1886 if self.star_arg and i == max_positional_args:
1887 code.putln('default:')
1889 code.putln('case %2d:' % i)
1890 code.putln('values[%d] = PyDict_GetItem(%s, *%s[%d]);' % (
1891 i, Naming.kwds_cname, Naming.pykwdlist_cname, i))
1892 if i < min_positional_args:
1893 code.putln('if (likely(values[%d])) kw_args--;' % i);
1895 # special case: we know arg 0 is missing
1897 code.put_goto(argtuple_error_label)
1899 # provide the correct number of values (args or
1900 # kwargs) that were passed into positional
1901 # arguments up to this point
1902 code.putln('else {')
1903 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
1904 self.name.utf8encode(), has_fixed_positional_count,
1905 min_positional_args, max_positional_args, i))
1906 code.putln(code.error_goto(self.pos))
1909 code.putln('if (values[%d]) kw_args--;' % i);
1910 if arg.kw_only and not arg.default:
1911 code.putln('else {')
1912 code.put('__Pyx_RaiseKeywordRequired("%s", *%s[%d]); ' %(
1913 self.name.utf8encode(), Naming.pykwdlist_cname, i))
1914 code.putln(code.error_goto(self.pos))
1918 code.putln('if (unlikely(kw_args > 0)) {')
1919 # non-positional kw args left in the dict: **kwargs or error
1921 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
1922 Naming.args_cname, max_positional_args,
1923 Naming.args_cname, max_positional_args))
1924 pos_arg_count = "used_pos_args"
1926 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
1927 code.globalstate.use_utility_code(split_keywords_utility_code)
1929 'if (unlikely(__Pyx_SplitKeywords(%s, %s, %s, %s, "%s") < 0)) ' % (
1931 Naming.pykwdlist_cname,
1932 self.starstar_arg and self.starstar_arg.entry.cname or '0',
1934 self.name.utf8encode()))
1935 code.putln(code.error_goto(self.pos))
1938 # convert arg values to their final type and assign them
1939 for i, arg in enumerate(all_args):
1941 code.putln("if (values[%d]) {" % i)
1942 self.generate_arg_assignment(arg, "values[%d]" % i, code)
1946 def generate_argument_conversion_code(self, code):
1947 # Generate code to convert arguments from
1948 # signature type to declared type, if needed.
1949 for arg in self.args:
1950 if arg.needs_conversion:
1951 self.generate_arg_conversion(arg, code)
1953 def generate_arg_conversion(self, arg, code):
1954 # Generate conversion code for one argument.
1955 old_type = arg.hdr_type
1957 if old_type.is_pyobject:
1959 code.putln("if (%s) {" % arg.hdr_cname)
1961 code.putln("assert(%s); {" % arg.hdr_cname)
1962 self.generate_arg_conversion_from_pyobject(arg, code)
1964 elif new_type.is_pyobject:
1965 self.generate_arg_conversion_to_pyobject(arg, code)
1967 if new_type.assignable_from(old_type):
1969 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
1972 "Cannot convert 1 argument from '%s' to '%s'" %
1973 (old_type, new_type))
1975 def generate_arg_conversion_from_pyobject(self, arg, code):
1977 func = new_type.from_py_function
1978 # copied from CoerceFromPyTypeNode
1980 code.putln("%s = %s(%s); %s" % (
1984 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
1987 "Cannot convert Python object argument to type '%s'"
1990 def generate_arg_conversion_to_pyobject(self, arg, code):
1991 old_type = arg.hdr_type
1992 func = old_type.to_py_function
1994 code.putln("%s = %s(%s); %s" % (
1998 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2001 "Cannot convert argument of type '%s' to Python object"
2004 def generate_argument_type_tests(self, code):
2005 # Generate type tests for args whose signature
2006 # type is PyObject * and whose declared type is
2007 # a subtype thereof.
2008 for arg in self.args:
2009 if arg.needs_type_test:
2010 self.generate_arg_type_test(arg, code)
2012 def generate_arg_type_test(self, arg, code):
2013 # Generate type test for one argument.
2014 if arg.type.typeobj_is_available():
2015 typeptr_cname = arg.type.typeptr_cname
2016 arg_code = "((PyObject *)%s)" % arg.entry.cname
2018 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2023 arg.type.is_builtin_type,
2024 code.error_goto(arg.pos)))
2026 error(arg.pos, "Cannot test type of extern C class "
2027 "without type object name specification")
2029 def error_value(self):
2030 return self.entry.signature.error_value
2032 def caller_will_check_exceptions(self):
2035 class OverrideCheckNode(StatNode):
2036 # A Node for dispatching to the def method if it
2045 child_attrs = ['body']
2049 def analyse_expressions(self, env):
2050 self.args = env.arg_entries
2051 if self.py_func.is_module_scope:
2056 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2057 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2058 call_node = ExprNodes.SimpleCallNode(self.pos,
2059 function=self.func_node,
2060 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2061 self.body = ReturnStatNode(self.pos, value=call_node)
2062 self.body.analyse_expressions(env)
2064 def generate_execution_code(self, code):
2065 # Check to see if we are an extension type
2066 if self.py_func.is_module_scope:
2067 self_arg = "((PyObject *)%s)" % Naming.module_cname
2069 self_arg = "((PyObject *)%s)" % self.args[0].cname
2070 code.putln("/* Check if called by wrapper */")
2071 code.putln("if (unlikely(%s)) %s = 0;" % (Naming.skip_dispatch_cname, Naming.skip_dispatch_cname))
2072 code.putln("/* Check if overriden in Python */")
2073 if self.py_func.is_module_scope:
2074 code.putln("else {")
2076 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2077 err = code.error_goto_if_null(self.func_node.result_code, self.pos)
2078 # need to get attribute manually--scope would return cdef method
2079 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (self.func_node.result_code, self_arg, self.py_func.interned_attr_cname, err))
2080 # It appears that this type is not anywhere exposed in the Python/C API
2081 is_builtin_function_or_method = '(strcmp(Py_TYPE(%s)->tp_name, "builtin_function_or_method") == 0)' % self.func_node.result_code
2082 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (self.func_node.result_code, self.py_func.entry.func_cname)
2083 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2084 self.body.generate_execution_code(code)
2086 code.put_decref_clear(self.func_node.result_code, PyrexTypes.py_object_type)
2089 class ClassDefNode(StatNode, BlockNode):
2092 class PyClassDefNode(ClassDefNode):
2093 # A Python class definition.
2095 # name EncodedString Name of the class
2096 # doc string or None
2097 # body StatNode Attribute definition code
2098 # entry Symtab.Entry
2099 # scope PyClassScope
2101 # The following subnodes are constructed internally:
2103 # dict DictNode Class dictionary
2104 # classobj ClassNode Class object
2105 # target NameNode Variable to assign class object to
2107 child_attrs = ["body", "dict", "classobj", "target"]
2109 def __init__(self, pos, name, bases, doc, body):
2110 StatNode.__init__(self, pos)
2115 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2116 if self.doc and Options.docstrings:
2117 doc = embed_position(self.pos, self.doc)
2118 doc_node = ExprNodes.StringNode(pos, value = doc)
2121 self.classobj = ExprNodes.ClassNode(pos, name = name,
2122 bases = bases, dict = self.dict, doc = doc_node)
2123 self.target = ExprNodes.NameNode(pos, name = name)
2125 def create_scope(self, env):
2127 while env.is_py_class_scope or env.is_c_class_scope:
2128 env = env.outer_scope
2129 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2132 def analyse_declarations(self, env):
2133 self.target.analyse_target_declaration(env)
2134 cenv = self.create_scope(env)
2135 cenv.class_obj_cname = self.target.entry.cname
2136 self.body.analyse_declarations(cenv)
2138 def analyse_expressions(self, env):
2139 self.dict.analyse_expressions(env)
2140 self.classobj.analyse_expressions(env)
2141 genv = env.global_scope()
2143 cenv.class_dict_cname = self.dict.result_code
2144 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result_code
2145 self.body.analyse_expressions(cenv)
2146 self.target.analyse_target_expression(env, self.classobj)
2147 self.dict.release_temp(env)
2148 #self.classobj.release_temp(env)
2149 #self.target.release_target_temp(env)
2151 def generate_function_definitions(self, env, code):
2152 self.generate_py_string_decls(self.scope, code)
2153 self.body.generate_function_definitions(self.scope, code)
2155 def generate_execution_code(self, code):
2156 self.dict.generate_evaluation_code(code)
2157 self.classobj.generate_evaluation_code(code)
2158 self.body.generate_execution_code(code)
2159 self.target.generate_assignment_code(self.classobj, code)
2160 self.dict.generate_disposal_code(code)
2163 class CClassDefNode(ClassDefNode):
2164 # An extension type definition.
2166 # visibility 'private' or 'public' or 'extern'
2167 # typedef_flag boolean
2169 # module_name string or None For import of extern type objects
2170 # class_name string Unqualified name of class
2171 # as_name string or None Name to declare as in this scope
2172 # base_class_module string or None Module containing the base class
2173 # base_class_name string or None Name of the base class
2174 # objstruct_name string or None Specified C name of object struct
2175 # typeobj_name string or None Specified C name of type object
2176 # in_pxd boolean Is in a .pxd file
2177 # doc string or None
2178 # body StatNode or None
2179 # entry Symtab.Entry
2180 # base_type PyExtensionType or None
2181 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2182 # buffer_defaults_pos
2184 child_attrs = ["body"]
2185 buffer_defaults_node = None
2186 buffer_defaults_pos = None
2188 def analyse_declarations(self, env):
2189 #print "CClassDefNode.analyse_declarations:", self.class_name
2190 #print "...visibility =", self.visibility
2191 #print "...module_name =", self.module_name
2194 if self.buffer_defaults_node:
2195 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2196 env, [], self.buffer_defaults_node,
2197 need_complete=False)
2199 buffer_defaults = None
2201 if env.in_cinclude and not self.objstruct_name:
2202 error(self.pos, "Object struct name specification required for "
2203 "C class defined in 'extern from' block")
2204 self.base_type = None
2205 # Now that module imports are cached, we need to
2206 # import the modules for extern classes.
2207 if self.module_name:
2209 for module in env.cimported_modules:
2210 if module.name == self.module_name:
2211 self.module = module
2212 if self.module is None:
2213 self.module = ModuleScope(self.module_name, None, env.context)
2214 self.module.has_extern_class = 1
2215 env.cimported_modules.append(self.module)
2217 if self.base_class_name:
2218 if self.base_class_module:
2219 base_class_scope = env.find_module(self.base_class_module, self.pos)
2221 base_class_scope = env
2222 if base_class_scope:
2223 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2224 if base_class_entry:
2225 if not base_class_entry.is_type:
2226 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2227 elif not base_class_entry.type.is_extension_type:
2228 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2229 elif not base_class_entry.type.is_complete():
2230 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2232 self.base_type = base_class_entry.type
2233 has_body = self.body is not None
2234 if self.module_name and self.visibility != 'extern':
2235 module_path = self.module_name.split(".")
2236 home_scope = env.find_imported_module(module_path, self.pos)
2241 self.entry = home_scope.declare_c_class(
2242 name = self.class_name,
2244 defining = has_body and self.in_pxd,
2245 implementing = has_body and not self.in_pxd,
2246 module_name = self.module_name,
2247 base_type = self.base_type,
2248 objstruct_cname = self.objstruct_name,
2249 typeobj_cname = self.typeobj_name,
2250 visibility = self.visibility,
2251 typedef_flag = self.typedef_flag,
2253 buffer_defaults = buffer_defaults)
2254 if home_scope is not env and self.visibility == 'extern':
2255 env.add_imported_entry(self.class_name, self.entry, pos)
2256 scope = self.entry.type.scope
2258 if self.doc and Options.docstrings:
2259 scope.doc = embed_position(self.pos, self.doc)
2262 self.body.analyse_declarations(scope)
2266 scope.implemented = 1
2267 env.allocate_vtable_names(self.entry)
2269 def analyse_expressions(self, env):
2271 scope = self.entry.type.scope
2272 self.body.analyse_expressions(scope)
2274 def generate_function_definitions(self, env, code):
2275 self.generate_py_string_decls(self.entry.type.scope, code)
2277 self.body.generate_function_definitions(
2278 self.entry.type.scope, code)
2280 def generate_execution_code(self, code):
2281 # This is needed to generate evaluation code for
2282 # default values of method arguments.
2284 self.body.generate_execution_code(code)
2286 def annotate(self, code):
2288 self.body.annotate(code)
2291 class PropertyNode(StatNode):
2292 # Definition of a property in an extension type.
2295 # doc EncodedString or None Doc string
2298 child_attrs = ["body"]
2300 def analyse_declarations(self, env):
2301 entry = env.declare_property(self.name, self.doc, self.pos)
2303 if self.doc and Options.docstrings:
2304 doc_entry = env.get_string_const(
2305 self.doc, identifier = False)
2306 entry.doc_cname = doc_entry.cname
2307 self.body.analyse_declarations(entry.scope)
2309 def analyse_expressions(self, env):
2310 self.body.analyse_expressions(env)
2312 def generate_function_definitions(self, env, code):
2313 self.body.generate_function_definitions(env, code)
2315 def generate_execution_code(self, code):
2318 def annotate(self, code):
2319 self.body.annotate(code)
2322 class GlobalNode(StatNode):
2323 # Global variable declaration.
2329 def analyse_declarations(self, env):
2330 for name in self.names:
2331 env.declare_global(name, self.pos)
2333 def analyse_expressions(self, env):
2336 def generate_execution_code(self, code):
2340 class ExprStatNode(StatNode):
2341 # Expression used as a statement.
2345 child_attrs = ["expr"]
2347 def analyse_expressions(self, env):
2348 self.expr.analyse_expressions(env)
2349 self.expr.release_temp(env)
2351 def generate_execution_code(self, code):
2352 self.expr.generate_evaluation_code(code)
2353 if not self.expr.is_temp and self.expr.result_code:
2354 code.putln("%s;" % self.expr.result_code)
2355 self.expr.generate_disposal_code(code)
2357 def annotate(self, code):
2358 self.expr.annotate(code)
2361 class AssignmentNode(StatNode):
2362 # Abstract base class for assignment nodes.
2364 # The analyse_expressions and generate_execution_code
2365 # phases of assignments are split into two sub-phases
2366 # each, to enable all the right hand sides of a
2367 # parallel assignment to be evaluated before assigning
2368 # to any of the left hand sides.
2370 def analyse_expressions(self, env):
2371 self.analyse_types(env)
2372 self.allocate_rhs_temps(env)
2373 self.allocate_lhs_temps(env)
2375 # def analyse_expressions(self, env):
2376 # self.analyse_expressions_1(env)
2377 # self.analyse_expressions_2(env)
2379 def generate_execution_code(self, code):
2380 self.generate_rhs_evaluation_code(code)
2381 self.generate_assignment_code(code)
2384 class SingleAssignmentNode(AssignmentNode):
2385 # The simplest case:
2389 # lhs ExprNode Left hand side
2390 # rhs ExprNode Right hand side
2391 # first bool Is this guaranteed the first assignment to lhs?
2393 child_attrs = ["lhs", "rhs"]
2396 def analyse_declarations(self, env):
2397 self.lhs.analyse_target_declaration(env)
2399 def analyse_types(self, env, use_temp = 0):
2400 self.rhs.analyse_types(env)
2401 self.lhs.analyse_target_types(env)
2402 self.lhs.gil_assignment_check(env)
2403 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2405 self.rhs = self.rhs.coerce_to_temp(env)
2407 def allocate_rhs_temps(self, env):
2408 self.rhs.allocate_temps(env)
2410 def allocate_lhs_temps(self, env):
2411 self.lhs.allocate_target_temps(env, self.rhs)
2412 #self.lhs.release_target_temp(env)
2413 #self.rhs.release_temp(env)
2415 # def analyse_expressions_1(self, env, use_temp = 0):
2416 # self.rhs.analyse_types(env)
2417 # self.lhs.analyse_target_types(env)
2418 # self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2420 # self.rhs = self.rhs.coerce_to_temp(env)
2421 # self.rhs.allocate_temps(env)
2423 # def analyse_expressions_2(self, env):
2424 # self.lhs.allocate_target_temps(env)
2425 # self.lhs.release_target_temp(env)
2426 # self.rhs.release_temp(env)
2428 def generate_rhs_evaluation_code(self, code):
2429 self.rhs.generate_evaluation_code(code)
2431 def generate_assignment_code(self, code):
2432 self.lhs.generate_assignment_code(self.rhs, code)
2434 def annotate(self, code):
2435 self.lhs.annotate(code)
2436 self.rhs.annotate(code)
2439 class CascadedAssignmentNode(AssignmentNode):
2440 # An assignment with multiple left hand sides:
2444 # lhs_list [ExprNode] Left hand sides
2445 # rhs ExprNode Right hand sides
2449 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2451 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2452 coerced_rhs_list = None
2454 def analyse_declarations(self, env):
2455 for lhs in self.lhs_list:
2456 lhs.analyse_target_declaration(env)
2458 def analyse_types(self, env, use_temp = 0):
2459 self.rhs.analyse_types(env)
2461 self.rhs = self.rhs.coerce_to_temp(env)
2463 self.rhs = self.rhs.coerce_to_simple(env)
2464 from ExprNodes import CloneNode
2465 self.coerced_rhs_list = []
2466 for lhs in self.lhs_list:
2467 lhs.analyse_target_types(env)
2468 lhs.gil_assignment_check(env)
2469 rhs = CloneNode(self.rhs)
2470 rhs = rhs.coerce_to(lhs.type, env)
2471 self.coerced_rhs_list.append(rhs)
2473 def allocate_rhs_temps(self, env):
2474 self.rhs.allocate_temps(env)
2476 def allocate_lhs_temps(self, env):
2477 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2478 rhs.allocate_temps(env)
2479 lhs.allocate_target_temps(env, rhs)
2480 #lhs.release_target_temp(env)
2481 #rhs.release_temp(env)
2482 self.rhs.release_temp(env)
2484 # def analyse_expressions_1(self, env, use_temp = 0):
2485 # self.rhs.analyse_types(env)
2487 # self.rhs = self.rhs.coerce_to_temp(env)
2489 # self.rhs = self.rhs.coerce_to_simple(env)
2490 # self.rhs.allocate_temps(env)
2492 # def analyse_expressions_2(self, env):
2493 # from ExprNodes import CloneNode
2494 # self.coerced_rhs_list = []
2495 # for lhs in self.lhs_list:
2496 # lhs.analyse_target_types(env)
2497 # rhs = CloneNode(self.rhs)
2498 # rhs = rhs.coerce_to(lhs.type, env)
2499 # self.coerced_rhs_list.append(rhs)
2500 # rhs.allocate_temps(env)
2501 # lhs.allocate_target_temps(env)
2502 # lhs.release_target_temp(env)
2503 # rhs.release_temp(env)
2504 # self.rhs.release_temp(env)
2506 def generate_rhs_evaluation_code(self, code):
2507 self.rhs.generate_evaluation_code(code)
2509 def generate_assignment_code(self, code):
2510 for i in range(len(self.lhs_list)):
2511 lhs = self.lhs_list[i]
2512 rhs = self.coerced_rhs_list[i]
2513 rhs.generate_evaluation_code(code)
2514 lhs.generate_assignment_code(rhs, code)
2515 # Assignment has disposed of the cloned RHS
2516 self.rhs.generate_disposal_code(code)
2518 def annotate(self, code):
2519 for i in range(len(self.lhs_list)):
2520 lhs = self.lhs_list[i].annotate(code)
2521 rhs = self.coerced_rhs_list[i].annotate(code)
2522 self.rhs.annotate(code)
2525 class ParallelAssignmentNode(AssignmentNode):
2526 # A combined packing/unpacking assignment:
2530 # This has been rearranged by the parser into
2532 # a = d ; b = e ; c = f
2534 # but we must evaluate all the right hand sides
2535 # before assigning to any of the left hand sides.
2537 # stats [AssignmentNode] The constituent assignments
2539 child_attrs = ["stats"]
2541 def analyse_declarations(self, env):
2542 for stat in self.stats:
2543 stat.analyse_declarations(env)
2545 def analyse_expressions(self, env):
2546 for stat in self.stats:
2547 stat.analyse_types(env, use_temp = 1)
2548 stat.allocate_rhs_temps(env)
2549 for stat in self.stats:
2550 stat.allocate_lhs_temps(env)
2552 # def analyse_expressions(self, env):
2553 # for stat in self.stats:
2554 # stat.analyse_expressions_1(env, use_temp = 1)
2555 # for stat in self.stats:
2556 # stat.analyse_expressions_2(env)
2558 def generate_execution_code(self, code):
2559 for stat in self.stats:
2560 stat.generate_rhs_evaluation_code(code)
2561 for stat in self.stats:
2562 stat.generate_assignment_code(code)
2564 def annotate(self, code):
2565 for stat in self.stats:
2569 class InPlaceAssignmentNode(AssignmentNode):
2570 # An in place arithmatic operand:
2576 # lhs ExprNode Left hand side
2577 # rhs ExprNode Right hand side
2578 # op char one of "+-*/%^&|"
2579 # dup (ExprNode) copy of lhs used for operation (auto-generated)
2581 # This code is a bit tricky because in order to obey Python
2582 # semantics the sub-expressions (e.g. indices) of the lhs must
2583 # not be evaluated twice. So we must re-use the values calculated
2584 # in evaluation phase for the assignment phase as well.
2585 # Fortunately, the type of the lhs node is fairly constrained
2586 # (it must be a NameNode, AttributeNode, or IndexNode).
2588 child_attrs = ["lhs", "rhs"]
2591 def analyse_declarations(self, env):
2592 self.lhs.analyse_target_declaration(env)
2594 def analyse_types(self, env):
2595 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
2596 self.rhs.analyse_types(env)
2597 self.lhs.analyse_target_types(env)
2598 if Options.incref_local_binop and self.dup.type.is_pyobject:
2599 self.dup = self.dup.coerce_to_temp(env)
2601 def allocate_rhs_temps(self, env):
2603 if self.lhs.type.is_pyobject:
2604 self.rhs = self.rhs.coerce_to_pyobject(env)
2605 elif self.rhs.type.is_pyobject:
2606 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2607 if self.lhs.type.is_pyobject:
2608 self.result = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
2609 self.result.allocate_temps(env)
2611 # self.rhs = self.rhs.coerce_to_temp(env)
2612 self.rhs.allocate_temps(env)
2613 self.dup.allocate_subexpr_temps(env)
2614 self.dup.allocate_temp(env)
2616 def allocate_lhs_temps(self, env):
2617 self.lhs.allocate_target_temps(env, self.rhs)
2618 # self.lhs.release_target_temp(env)
2619 self.dup.release_temp(env)
2620 if self.dup.is_temp:
2621 self.dup.release_subexpr_temps(env)
2622 # self.rhs.release_temp(env)
2623 if self.lhs.type.is_pyobject:
2624 self.result.release_temp(env)
2626 def generate_execution_code(self, code):
2627 self.rhs.generate_evaluation_code(code)
2628 self.dup.generate_subexpr_evaluation_code(code)
2629 # self.dup.generate_result_code is run only if it is not buffer access
2630 if self.operator == "**":
2635 if self.lhs.type.is_pyobject:
2636 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
2637 error(self.pos, "In-place operators not allowed on object buffers in this release.")
2638 self.dup.generate_result_code(code)
2640 "%s = %s(%s, %s%s); %s" % (
2641 self.result.result_code,
2642 self.py_operation_function(),
2643 self.dup.py_result(),
2644 self.rhs.py_result(),
2646 code.error_goto_if_null(self.result.py_result(), self.pos)))
2647 self.result.generate_evaluation_code(code) # May be a type check...
2648 self.rhs.generate_disposal_code(code)
2649 self.dup.generate_disposal_code(code)
2650 self.lhs.generate_assignment_code(self.result, code)
2652 c_op = self.operator
2656 if self.lhs.type.is_int and self.rhs.type.is_int:
2657 error(self.pos, "** with two C int types is ambiguous")
2659 error(self.pos, "No C inplace power operator")
2660 # have to do assignment directly to avoid side-effects
2661 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
2662 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
2664 self.dup.generate_result_code(code)
2665 code.putln("%s %s= %s;" % (self.lhs.result_code, c_op, self.rhs.result_code) )
2666 self.rhs.generate_disposal_code(code)
2667 if self.dup.is_temp:
2668 self.dup.generate_subexpr_disposal_code(code)
2670 def create_dup_node(self, env):
2673 self.dup.analyse_types(env)
2674 if isinstance(self.lhs, ExprNodes.NameNode):
2675 target_lhs = ExprNodes.NameNode(self.dup.pos,
2676 name = self.dup.name,
2677 is_temp = self.dup.is_temp,
2678 entry = self.dup.entry,
2679 options = self.dup.options)
2680 elif isinstance(self.lhs, ExprNodes.AttributeNode):
2681 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
2682 obj = ExprNodes.CloneNode(self.lhs.obj),
2683 attribute = self.dup.attribute,
2684 is_temp = self.dup.is_temp,
2685 options = self.dup.options)
2686 elif isinstance(self.lhs, ExprNodes.IndexNode):
2688 index = ExprNodes.CloneNode(self.lhs.index)
2691 if self.lhs.indices:
2692 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
2695 target_lhs = ExprNodes.IndexNode(self.dup.pos,
2696 base = ExprNodes.CloneNode(self.dup.base),
2699 is_temp = self.dup.is_temp,
2700 options = self.dup.options)
2701 self.lhs = target_lhs
2704 def py_operation_function(self):
2705 return self.py_functions[self.operator]
2708 "|": "PyNumber_InPlaceOr",
2709 "^": "PyNumber_InPlaceXor",
2710 "&": "PyNumber_InPlaceAnd",
2711 "+": "PyNumber_InPlaceAdd",
2712 "-": "PyNumber_InPlaceSubtract",
2713 "*": "PyNumber_InPlaceMultiply",
2714 "/": "PyNumber_InPlaceDivide",
2715 "%": "PyNumber_InPlaceRemainder",
2716 "<<": "PyNumber_InPlaceLshift",
2717 ">>": "PyNumber_InPlaceRshift",
2718 "**": "PyNumber_InPlacePower",
2719 "//": "PyNumber_InPlaceFloorDivide",
2722 def annotate(self, code):
2723 self.lhs.annotate(code)
2724 self.rhs.annotate(code)
2725 self.dup.annotate(code)
2728 class PrintStatNode(StatNode):
2731 # arg_tuple TupleNode
2732 # append_newline boolean
2734 child_attrs = ["arg_tuple"]
2736 def analyse_expressions(self, env):
2737 self.arg_tuple.analyse_expressions(env)
2738 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
2739 self.arg_tuple.release_temp(env)
2740 env.use_utility_code(printing_utility_code)
2743 gil_message = "Python print statement"
2745 def generate_execution_code(self, code):
2746 self.arg_tuple.generate_evaluation_code(code)
2748 "if (__Pyx_Print(%s, %d) < 0) %s" % (
2749 self.arg_tuple.py_result(),
2750 self.append_newline,
2751 code.error_goto(self.pos)))
2752 self.arg_tuple.generate_disposal_code(code)
2754 def annotate(self, code):
2755 self.arg_tuple.annotate(code)
2758 class DelStatNode(StatNode):
2763 child_attrs = ["args"]
2765 def analyse_declarations(self, env):
2766 for arg in self.args:
2767 arg.analyse_target_declaration(env)
2769 def analyse_expressions(self, env):
2770 for arg in self.args:
2771 arg.analyse_target_expression(env, None)
2772 if arg.type.is_pyobject:
2775 error(arg.pos, "Deletion of non-Python object")
2776 #arg.release_target_temp(env)
2778 gil_message = "Deleting Python object"
2780 def generate_execution_code(self, code):
2781 for arg in self.args:
2782 if arg.type.is_pyobject:
2783 arg.generate_deletion_code(code)
2784 # else error reported earlier
2786 def annotate(self, code):
2787 for arg in self.args:
2791 class PassStatNode(StatNode):
2796 def analyse_expressions(self, env):
2799 def generate_execution_code(self, code):
2803 class BreakStatNode(StatNode):
2807 def analyse_expressions(self, env):
2810 def generate_execution_code(self, code):
2811 if not code.break_label:
2812 error(self.pos, "break statement not inside loop")
2817 code.put_goto(code.break_label)
2820 class ContinueStatNode(StatNode):
2824 def analyse_expressions(self, env):
2827 def generate_execution_code(self, code):
2828 if code.funcstate.in_try_finally:
2829 error(self.pos, "continue statement inside try of try...finally")
2830 elif not code.continue_label:
2831 error(self.pos, "continue statement not inside loop")
2833 code.put_goto(code.continue_label)
2836 class ReturnStatNode(StatNode):
2839 # value ExprNode or None
2840 # return_type PyrexType
2841 # temps_in_use [Entry] Temps in use at time of return
2843 child_attrs = ["value"]
2845 def analyse_expressions(self, env):
2846 return_type = env.return_type
2847 self.return_type = return_type
2848 self.temps_in_use = env.temps_in_use()
2850 error(self.pos, "Return not inside a function body")
2853 self.value.analyse_types(env)
2854 if return_type.is_void or return_type.is_returncode:
2855 error(self.value.pos,
2856 "Return with value in void function")
2858 self.value = self.value.coerce_to(env.return_type, env)
2859 self.value.allocate_temps(env)
2860 self.value.release_temp(env)
2862 if (not return_type.is_void
2863 and not return_type.is_pyobject
2864 and not return_type.is_returncode):
2865 error(self.pos, "Return value required")
2866 if return_type.is_pyobject:
2869 gil_message = "Returning Python object"
2871 def generate_execution_code(self, code):
2872 code.mark_pos(self.pos)
2873 if not self.return_type:
2874 # error reported earlier
2877 self.value.generate_evaluation_code(code)
2878 self.value.make_owned_reference(code)
2881 Naming.retval_cname,
2882 self.value.result_as(self.return_type)))
2883 self.value.generate_post_assignment_code(code)
2885 if self.return_type.is_pyobject:
2886 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
2887 elif self.return_type.is_returncode:
2890 Naming.retval_cname,
2891 self.return_type.default_value))
2892 for entry in self.temps_in_use:
2893 code.put_var_decref_clear(entry)
2896 # code.return_label)
2897 code.put_goto(code.return_label)
2899 def annotate(self, code):
2901 self.value.annotate(code)
2904 class RaiseStatNode(StatNode):
2907 # exc_type ExprNode or None
2908 # exc_value ExprNode or None
2909 # exc_tb ExprNode or None
2911 child_attrs = ["exc_type", "exc_value", "exc_tb"]
2913 def analyse_expressions(self, env):
2915 self.exc_type.analyse_types(env)
2916 self.exc_type = self.exc_type.coerce_to_pyobject(env)
2917 self.exc_type.allocate_temps(env)
2919 self.exc_value.analyse_types(env)
2920 self.exc_value = self.exc_value.coerce_to_pyobject(env)
2921 self.exc_value.allocate_temps(env)
2923 self.exc_tb.analyse_types(env)
2924 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
2925 self.exc_tb.allocate_temps(env)
2927 self.exc_type.release_temp(env)
2929 self.exc_value.release_temp(env)
2931 self.exc_tb.release_temp(env)
2932 env.use_utility_code(raise_utility_code)
2933 env.use_utility_code(restore_exception_utility_code)
2936 gil_message = "Raising exception"
2938 def generate_execution_code(self, code):
2940 self.exc_type.generate_evaluation_code(code)
2941 type_code = self.exc_type.py_result()
2945 self.exc_value.generate_evaluation_code(code)
2946 value_code = self.exc_value.py_result()
2950 self.exc_tb.generate_evaluation_code(code)
2951 tb_code = self.exc_tb.py_result()
2954 if self.exc_type or self.exc_value or self.exc_tb:
2956 "__Pyx_Raise(%s, %s, %s);" % (
2964 self.exc_type.generate_disposal_code(code)
2966 self.exc_value.generate_disposal_code(code)
2968 self.exc_tb.generate_disposal_code(code)
2970 code.error_goto(self.pos))
2972 def annotate(self, code):
2974 self.exc_type.annotate(code)
2976 self.exc_value.annotate(code)
2978 self.exc_tb.annotate(code)
2981 class ReraiseStatNode(StatNode):
2985 def analyse_expressions(self, env):
2987 env.use_utility_code(raise_utility_code)
2988 env.use_utility_code(restore_exception_utility_code)
2990 gil_message = "Raising exception"
2992 def generate_execution_code(self, code):
2993 vars = code.funcstate.exc_vars
2995 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
2996 code.putln(code.error_goto(self.pos))
2998 error(self.pos, "Reraise not inside except clause")
3001 class AssertStatNode(StatNode):
3005 # value ExprNode or None
3007 child_attrs = ["cond", "value"]
3009 def analyse_expressions(self, env):
3010 self.cond = self.cond.analyse_boolean_expression(env)
3012 self.value.analyse_types(env)
3013 self.value = self.value.coerce_to_pyobject(env)
3014 self.value.allocate_temps(env)
3015 self.cond.release_temp(env)
3017 self.value.release_temp(env)
3019 #env.recycle_pending_temps() # TEMPORARY
3021 gil_message = "Raising exception"
3023 def generate_execution_code(self, code):
3024 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3025 self.cond.generate_evaluation_code(code)
3027 "if (unlikely(!%s)) {" %
3028 self.cond.result_code)
3030 self.value.generate_evaluation_code(code)
3032 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3033 self.value.py_result())
3034 self.value.generate_disposal_code(code)
3037 "PyErr_SetNone(PyExc_AssertionError);")
3039 code.error_goto(self.pos))
3042 self.cond.generate_disposal_code(code)
3043 code.putln("#endif")
3045 def annotate(self, code):
3046 self.cond.annotate(code)
3048 self.value.annotate(code)
3051 class IfStatNode(StatNode):
3054 # if_clauses [IfClauseNode]
3055 # else_clause StatNode or None
3057 child_attrs = ["if_clauses", "else_clause"]
3059 def analyse_control_flow(self, env):
3060 env.start_branching(self.pos)
3061 for if_clause in self.if_clauses:
3062 if_clause.analyse_control_flow(env)
3063 env.next_branch(if_clause.end_pos())
3064 if self.else_clause:
3065 self.else_clause.analyse_control_flow(env)
3066 env.finish_branching(self.end_pos())
3068 def analyse_declarations(self, env):
3069 for if_clause in self.if_clauses:
3070 if_clause.analyse_declarations(env)
3071 if self.else_clause:
3072 self.else_clause.analyse_declarations(env)
3074 def analyse_expressions(self, env):
3075 for if_clause in self.if_clauses:
3076 if_clause.analyse_expressions(env)
3077 if self.else_clause:
3078 self.else_clause.analyse_expressions(env)
3080 def generate_execution_code(self, code):
3081 code.mark_pos(self.pos)
3082 end_label = code.new_label()
3083 for if_clause in self.if_clauses:
3084 if_clause.generate_execution_code(code, end_label)
3085 if self.else_clause:
3086 code.putln("/*else*/ {")
3087 self.else_clause.generate_execution_code(code)
3089 code.put_label(end_label)
3091 def annotate(self, code):
3092 for if_clause in self.if_clauses:
3093 if_clause.annotate(code)
3094 if self.else_clause:
3095 self.else_clause.annotate(code)
3098 class IfClauseNode(Node):
3099 # if or elif clause in an if statement
3101 # condition ExprNode
3104 child_attrs = ["condition", "body"]
3106 def analyse_control_flow(self, env):
3107 self.body.analyse_control_flow(env)
3109 def analyse_declarations(self, env):
3110 self.condition.analyse_declarations(env)
3111 self.body.analyse_declarations(env)
3113 def analyse_expressions(self, env):
3115 self.condition.analyse_temp_boolean_expression(env)
3116 self.condition.release_temp(env)
3117 self.body.analyse_expressions(env)
3119 def generate_execution_code(self, code, end_label):
3120 self.condition.generate_evaluation_code(code)
3123 self.condition.result_code)
3124 self.body.generate_execution_code(code)
3128 code.put_goto(end_label)
3131 def annotate(self, code):
3132 self.condition.annotate(code)
3133 self.body.annotate(code)
3136 class SwitchCaseNode(StatNode):
3137 # Generated in the optimization of an if-elif-else node
3139 # conditions [ExprNode]
3142 child_attrs = ['conditions', 'body']
3144 def generate_execution_code(self, code):
3145 for cond in self.conditions:
3146 code.putln("case %s:" % cond.calculate_result_code())
3147 self.body.generate_execution_code(code)
3148 code.putln("break;")
3150 def annotate(self, code):
3151 for cond in self.conditions:
3153 self.body.annotate(code)
3155 class SwitchStatNode(StatNode):
3156 # Generated in the optimization of an if-elif-else node
3159 # cases [SwitchCaseNode]
3160 # else_clause StatNode or None
3162 child_attrs = ['test', 'cases', 'else_clause']
3164 def generate_execution_code(self, code):
3165 code.putln("switch (%s) {" % self.test.calculate_result_code())
3166 for case in self.cases:
3167 case.generate_execution_code(code)
3168 if self.else_clause is not None:
3169 code.putln("default:")
3170 self.else_clause.generate_execution_code(code)
3173 def annotate(self, code):
3174 self.test.annotate(code)
3175 for case in self.cases:
3177 if self.else_clause is not None:
3178 self.else_clause.annotate(code)
3182 def analyse_control_flow(self, env):
3183 env.start_branching(self.pos)
3184 self.body.analyse_control_flow(env)
3185 env.next_branch(self.body.end_pos())
3186 if self.else_clause:
3187 self.else_clause.analyse_control_flow(env)
3188 env.finish_branching(self.end_pos())
3191 class WhileStatNode(LoopNode, StatNode):
3194 # condition ExprNode
3196 # else_clause StatNode
3198 child_attrs = ["condition", "body", "else_clause"]
3200 def analyse_declarations(self, env):
3201 self.body.analyse_declarations(env)
3202 if self.else_clause:
3203 self.else_clause.analyse_declarations(env)
3205 def analyse_expressions(self, env):
3207 self.condition.analyse_temp_boolean_expression(env)
3208 self.condition.release_temp(env)
3209 #env.recycle_pending_temps() # TEMPORARY
3210 self.body.analyse_expressions(env)
3211 if self.else_clause:
3212 self.else_clause.analyse_expressions(env)
3214 def generate_execution_code(self, code):
3215 old_loop_labels = code.new_loop_labels()
3218 self.condition.generate_evaluation_code(code)
3221 self.condition.result_code)
3222 self.body.generate_execution_code(code)
3223 code.put_label(code.continue_label)
3225 break_label = code.break_label
3226 code.set_loop_labels(old_loop_labels)
3227 if self.else_clause:
3228 code.putln("/*else*/ {")
3229 self.else_clause.generate_execution_code(code)
3231 code.put_label(break_label)
3233 def annotate(self, code):
3234 self.condition.annotate(code)
3235 self.body.annotate(code)
3236 if self.else_clause:
3237 self.else_clause.annotate(code)
3240 def ForStatNode(pos, **kw):
3241 if kw.has_key('iterator'):
3242 return ForInStatNode(pos, **kw)
3244 return ForFromStatNode(pos, **kw)
3246 class ForInStatNode(LoopNode, StatNode):
3250 # iterator IteratorNode
3252 # else_clause StatNode
3253 # item NextNode used internally
3255 child_attrs = ["target", "iterator", "body", "else_clause"]
3258 def analyse_declarations(self, env):
3259 self.target.analyse_target_declaration(env)
3260 self.body.analyse_declarations(env)
3261 if self.else_clause:
3262 self.else_clause.analyse_declarations(env)
3264 def analyse_range_step(self, args):
3266 # The direction must be determined at compile time to set relations.
3267 # Otherwise, return False.
3269 self.step = ExprNodes.IntNode(pos = args[0].pos, value='1')
3270 self.relation1 = '<='
3271 self.relation2 = '<'
3275 if isinstance(step, ExprNodes.UnaryMinusNode) and isinstance(step.operand, ExprNodes.IntNode):
3276 step = ExprNodes.IntNode(pos = step.pos, value=str(-int(step.operand.value, 0)))
3277 if isinstance(step, ExprNodes.IntNode):
3278 step_value = int(step.value, 0)
3281 self.relation1 = '<='
3282 self.relation2 = '<'
3284 elif step_value < 0:
3285 self.step = ExprNodes.IntNode(pos = step.pos, value=str(-step_value))
3286 self.relation1 = '>='
3287 self.relation2 = '>'
3292 def analyse_expressions(self, env):
3294 self.target.analyse_target_types(env)
3295 if Options.convert_range and self.target.type.is_int:
3296 sequence = self.iterator.sequence
3297 if isinstance(sequence, ExprNodes.SimpleCallNode) \
3298 and sequence.self is None \
3299 and isinstance(sequence.function, ExprNodes.NameNode) \
3300 and (sequence.function.name == 'range' or sequence.function.name == 'xrange'):
3301 args = sequence.args
3302 # Make sure we can determine direction from step
3303 if self.analyse_range_step(args):
3304 # Mutate to ForFrom loop type
3305 self.__class__ = ForFromStatNode
3307 self.bound1 = ExprNodes.IntNode(pos = sequence.pos, value='0')
3308 self.bound2 = args[0]
3310 self.bound1 = args[0]
3311 self.bound2 = args[1]
3312 ForFromStatNode.analyse_expressions(self, env)
3315 self.iterator.analyse_expressions(env)
3316 self.item = ExprNodes.NextNode(self.iterator, env)
3317 self.item = self.item.coerce_to(self.target.type, env)
3318 self.item.allocate_temps(env)
3319 self.target.allocate_target_temps(env, self.item)
3320 #self.item.release_temp(env)
3321 #self.target.release_target_temp(env)
3322 self.body.analyse_expressions(env)
3323 if self.else_clause:
3324 self.else_clause.analyse_expressions(env)
3325 self.iterator.release_temp(env)
3327 def generate_execution_code(self, code):
3328 old_loop_labels = code.new_loop_labels()
3329 self.iterator.generate_evaluation_code(code)
3332 self.item.generate_evaluation_code(code)
3333 self.target.generate_assignment_code(self.item, code)
3334 self.body.generate_execution_code(code)
3335 code.put_label(code.continue_label)
3338 break_label = code.break_label
3339 code.set_loop_labels(old_loop_labels)
3340 if self.else_clause:
3341 code.putln("/*else*/ {")
3342 self.else_clause.generate_execution_code(code)
3344 code.put_label(break_label)
3345 self.iterator.generate_disposal_code(code)
3347 def annotate(self, code):
3348 self.target.annotate(code)
3349 self.iterator.annotate(code)
3350 self.body.annotate(code)
3351 if self.else_clause:
3352 self.else_clause.annotate(code)
3353 self.item.annotate(code)
3356 class ForFromStatNode(LoopNode, StatNode):
3357 # for name from expr rel name rel expr
3364 # step ExprNode or None
3366 # else_clause StatNode or None
3371 # loopvar_name string
3372 # py_loopvar_node PyTempNode or None
3373 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3375 def analyse_declarations(self, env):
3376 self.target.analyse_target_declaration(env)
3377 self.body.analyse_declarations(env)
3378 if self.else_clause:
3379 self.else_clause.analyse_declarations(env)
3381 def analyse_expressions(self, env):
3383 self.target.analyse_target_types(env)
3384 self.bound1.analyse_types(env)
3385 self.bound2.analyse_types(env)
3386 if self.target.type.is_numeric:
3387 self.bound1 = self.bound1.coerce_to(self.target.type, env)
3388 self.bound2 = self.bound2.coerce_to(self.target.type, env)
3390 self.bound1 = self.bound1.coerce_to_integer(env)
3391 self.bound2 = self.bound2.coerce_to_integer(env)
3392 if self.step is not None:
3393 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3394 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3395 self.step.analyse_types(env)
3396 self.step = self.step.coerce_to_integer(env)
3397 if not (self.bound2.is_name or self.bound2.is_literal):
3398 self.bound2 = self.bound2.coerce_to_temp(env)
3399 target_type = self.target.type
3400 if not (target_type.is_pyobject or target_type.is_numeric):
3401 error(self.target.pos,
3402 "Integer for-loop variable must be of type int or Python object")
3403 #if not (target_type.is_pyobject
3404 # or target_type.assignable_from(PyrexTypes.c_int_type)):
3405 # error(self.target.pos,
3406 # "Cannot assign integer to variable of type '%s'" % target_type)
3407 if target_type.is_numeric:
3408 self.is_py_target = 0
3409 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3410 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3411 self.loopvar_name = self.target.entry.cname
3412 self.py_loopvar_node = None
3414 self.is_py_target = 1
3415 c_loopvar_node = ExprNodes.TempNode(self.pos,
3416 PyrexTypes.c_long_type, env)
3417 c_loopvar_node.allocate_temps(env)
3418 self.loopvar_name = c_loopvar_node.result_code
3419 self.py_loopvar_node = \
3420 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3421 self.bound1.allocate_temps(env)
3422 self.bound2.allocate_temps(env)
3423 if self.step is not None:
3424 self.step.allocate_temps(env)
3425 if self.is_py_target:
3426 self.py_loopvar_node.allocate_temps(env)
3427 self.target.allocate_target_temps(env, self.py_loopvar_node)
3428 #self.target.release_target_temp(env)
3429 #self.py_loopvar_node.release_temp(env)
3430 self.body.analyse_expressions(env)
3431 if self.is_py_target:
3432 c_loopvar_node.release_temp(env)
3433 if self.else_clause:
3434 self.else_clause.analyse_expressions(env)
3435 self.bound1.release_temp(env)
3436 self.bound2.release_temp(env)
3437 if self.step is not None:
3438 self.step.release_temp(env)
3440 def generate_execution_code(self, code):
3441 old_loop_labels = code.new_loop_labels()
3442 self.bound1.generate_evaluation_code(code)
3443 self.bound2.generate_evaluation_code(code)
3444 offset, incop = self.relation_table[self.relation1]
3445 if self.step is not None:
3446 self.step.generate_evaluation_code(code)
3447 incop = "%s=%s" % (incop[0], self.step.result_code)
3449 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3451 self.bound1.result_code, offset,
3452 self.loopvar_name, self.relation2, self.bound2.result_code,
3453 self.loopvar_name, incop))
3454 if self.py_loopvar_node:
3455 self.py_loopvar_node.generate_evaluation_code(code)
3456 self.target.generate_assignment_code(self.py_loopvar_node, code)
3457 self.body.generate_execution_code(code)
3458 code.put_label(code.continue_label)
3460 break_label = code.break_label
3461 code.set_loop_labels(old_loop_labels)
3462 if self.else_clause:
3463 code.putln("/*else*/ {")
3464 self.else_clause.generate_execution_code(code)
3466 code.put_label(break_label)
3467 self.bound1.generate_disposal_code(code)
3468 self.bound2.generate_disposal_code(code)
3469 if self.step is not None:
3470 self.step.generate_disposal_code(code)
3473 # {relop : (initial offset, increment op)}
3480 def annotate(self, code):
3481 self.target.annotate(code)
3482 self.bound1.annotate(code)
3483 self.bound2.annotate(code)
3485 self.bound2.annotate(code)
3486 self.body.annotate(code)
3487 if self.else_clause:
3488 self.else_clause.annotate(code)
3491 class WithStatNode(StatNode):
3493 Represents a Python with statement.
3495 This is only used at parse tree level; and is not present in
3496 analysis or generation phases.
3498 # manager The with statement manager object
3499 # target Node (lhs expression)
3501 child_attrs = ["manager", "target", "body"]
3503 class TryExceptStatNode(StatNode):
3504 # try .. except statement
3507 # except_clauses [ExceptClauseNode]
3508 # else_clause StatNode or None
3509 # cleanup_list [Entry] temps to clean up on error
3511 child_attrs = ["body", "except_clauses", "else_clause"]
3513 def analyse_control_flow(self, env):
3514 env.start_branching(self.pos)
3515 self.body.analyse_control_flow(env)
3516 successful_try = env.control_flow # grab this for later
3517 env.next_branch(self.body.end_pos())
3518 env.finish_branching(self.body.end_pos())
3520 env.start_branching(self.except_clauses[0].pos)
3521 for except_clause in self.except_clauses:
3522 except_clause.analyse_control_flow(env)
3523 env.next_branch(except_clause.end_pos())
3525 # the else cause it executed only when the try clause finishes
3526 env.control_flow.incoming = successful_try
3527 if self.else_clause:
3528 self.else_clause.analyse_control_flow(env)
3529 env.finish_branching(self.end_pos())
3531 def analyse_declarations(self, env):
3532 self.body.analyse_declarations(env)
3533 for except_clause in self.except_clauses:
3534 except_clause.analyse_declarations(env)
3535 if self.else_clause:
3536 self.else_clause.analyse_declarations(env)
3539 def analyse_expressions(self, env):
3541 self.body.analyse_expressions(env)
3542 self.cleanup_list = env.free_temp_entries[:]
3543 for except_clause in self.except_clauses:
3544 except_clause.analyse_expressions(env)
3545 if self.else_clause:
3546 self.else_clause.analyse_expressions(env)
3549 gil_message = "Try-except statement"
3551 def generate_execution_code(self, code):
3552 old_error_label = code.new_error_label()
3553 our_error_label = code.error_label
3554 end_label = code.new_label()
3557 self.body.generate_execution_code(code)
3560 code.error_label = old_error_label
3561 if self.else_clause:
3564 self.else_clause.generate_execution_code(code)
3567 code.put_goto(end_label)
3568 code.put_label(our_error_label)
3569 code.put_var_xdecrefs_clear(self.cleanup_list)
3570 default_clause_seen = 0
3571 for except_clause in self.except_clauses:
3572 if not except_clause.pattern:
3573 default_clause_seen = 1
3575 if default_clause_seen:
3576 error(except_clause.pos, "Default except clause not last")
3577 except_clause.generate_handling_code(code, end_label)
3578 if not default_clause_seen:
3579 code.put_goto(code.error_label)
3580 code.put_label(end_label)
3582 def annotate(self, code):
3583 self.body.annotate(code)
3584 for except_node in self.except_clauses:
3585 except_node.annotate(code)
3586 if self.else_clause:
3587 self.else_clause.annotate(code)
3590 class ExceptClauseNode(Node):
3591 # Part of try ... except statement.
3594 # target ExprNode or None
3596 # excinfo_target NameNode or None optional target for exception info
3597 # match_flag string result of exception match
3598 # exc_value ExcValueNode used internally
3599 # function_name string qualified name of enclosing function
3600 # exc_vars (string * 3) local exception variables
3602 # excinfo_target is never set by the parser, but can be set by a transform
3603 # in order to extract more extensive information about the exception as a
3604 # sys.exc_info()-style tuple into a target variable
3606 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
3609 excinfo_target = None
3611 def analyse_declarations(self, env):
3613 self.target.analyse_target_declaration(env)
3614 if self.excinfo_target is not None:
3615 self.excinfo_target.analyse_target_declaration(env)
3616 self.body.analyse_declarations(env)
3618 def analyse_expressions(self, env):
3620 genv = env.global_scope()
3621 self.function_name = env.qualified_name
3623 self.pattern.analyse_expressions(env)
3624 self.pattern = self.pattern.coerce_to_pyobject(env)
3625 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
3626 self.pattern.release_temp(env)
3627 env.release_temp(self.match_flag)
3628 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
3630 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
3631 self.exc_value.allocate_temps(env)
3632 self.target.analyse_target_expression(env, self.exc_value)
3633 if self.excinfo_target is not None:
3635 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
3636 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
3637 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
3638 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
3640 self.excinfo_tuple.analyse_expressions(env)
3641 self.excinfo_tuple.allocate_temps(env)
3642 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
3644 self.body.analyse_expressions(env)
3645 for var in self.exc_vars:
3646 env.release_temp(var)
3647 env.use_utility_code(get_exception_utility_code)
3648 env.use_utility_code(restore_exception_utility_code)
3650 def generate_handling_code(self, code, end_label):
3651 code.mark_pos(self.pos)
3653 self.pattern.generate_evaluation_code(code)
3655 "%s = PyErr_ExceptionMatches(%s);" % (
3657 self.pattern.py_result()))
3658 self.pattern.generate_disposal_code(code)
3663 code.putln("/*except:*/ {")
3664 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
3665 # We always have to fetch the exception value even if
3666 # there is no target, because this also normalises the
3667 # exception and stores it in the thread state.
3668 exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
3669 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
3670 code.error_goto(self.pos)))
3672 self.exc_value.generate_evaluation_code(code)
3673 self.target.generate_assignment_code(self.exc_value, code)
3674 if self.excinfo_target is not None:
3675 self.excinfo_tuple.generate_evaluation_code(code)
3676 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
3678 old_exc_vars = code.funcstate.exc_vars
3679 code.funcstate.exc_vars = self.exc_vars
3680 self.body.generate_execution_code(code)
3681 code.funcstate.exc_vars = old_exc_vars
3682 for var in self.exc_vars:
3683 code.putln("Py_DECREF(%s); %s = 0;" % (var, var))
3684 code.put_goto(end_label)
3688 def annotate(self, code):
3690 self.pattern.annotate(code)
3692 self.target.annotate(code)
3693 self.body.annotate(code)
3696 class TryFinallyStatNode(StatNode):
3697 # try ... finally statement
3700 # finally_clause StatNode
3702 # cleanup_list [Entry] temps to clean up on error
3704 # The plan is that we funnel all continue, break
3705 # return and error gotos into the beginning of the
3706 # finally block, setting a variable to remember which
3707 # one we're doing. At the end of the finally block, we
3708 # switch on the variable to figure out where to go.
3709 # In addition, if we're doing an error, we save the
3710 # exception on entry to the finally block and restore
3713 child_attrs = ["body", "finally_clause"]
3715 preserve_exception = 1
3717 disallow_continue_in_try_finally = 0
3718 # There doesn't seem to be any point in disallowing
3719 # continue in the try block, since we have no problem
3722 def create_analysed(pos, env, body, finally_clause):
3723 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
3724 node.cleanup_list = []
3726 create_analysed = staticmethod(create_analysed)
3728 def analyse_control_flow(self, env):
3729 env.start_branching(self.pos)
3730 self.body.analyse_control_flow(env)
3731 env.next_branch(self.body.end_pos())
3732 env.finish_branching(self.body.end_pos())
3733 self.finally_clause.analyse_control_flow(env)
3735 def analyse_declarations(self, env):
3736 self.body.analyse_declarations(env)
3737 self.finally_clause.analyse_declarations(env)
3739 def analyse_expressions(self, env):
3740 self.body.analyse_expressions(env)
3741 self.cleanup_list = env.free_temp_entries[:]
3742 self.finally_clause.analyse_expressions(env)
3745 gil_message = "Try-finally statement"
3747 def generate_execution_code(self, code):
3748 old_error_label = code.error_label
3749 old_labels = code.all_new_labels()
3750 new_labels = code.get_all_labels()
3751 new_error_label = code.error_label
3752 catch_label = code.new_label()
3755 if self.disallow_continue_in_try_finally:
3756 was_in_try_finally = code.funcstate.in_try_finally
3757 code.funcstate.in_try_finally = 1
3758 self.body.generate_execution_code(code)
3759 if self.disallow_continue_in_try_finally:
3760 code.funcstate.in_try_finally = was_in_try_finally
3766 error_label_used = 0
3767 for i, new_label in enumerate(new_labels):
3768 if new_label in code.labels_used:
3769 cases_used.append(i)
3770 if new_label == new_error_label:
3771 error_label_used = 1
3772 error_label_case = i
3776 if error_label_used and self.preserve_exception:
3778 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
3780 "int %s;" % Naming.exc_lineno_name)
3781 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
3782 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
3783 code.putln(exc_var_init_zero)
3785 exc_var_init_zero = None
3786 code.use_label(catch_label)
3788 "__pyx_why = 0; goto %s;" % catch_label)
3789 for i in cases_used:
3790 new_label = new_labels[i]
3791 #if new_label and new_label != "<try>":
3792 if new_label == new_error_label and self.preserve_exception:
3793 self.put_error_catcher(code,
3794 new_error_label, i+1, catch_label)
3796 code.put('%s: ' % new_label)
3797 if exc_var_init_zero:
3798 code.putln(exc_var_init_zero)
3799 code.putln("__pyx_why = %s; goto %s;" % (
3802 code.put_label(catch_label)
3803 code.set_all_labels(old_labels)
3804 if error_label_used:
3805 code.new_error_label()
3806 finally_error_label = code.error_label
3807 self.finally_clause.generate_execution_code(code)
3808 if error_label_used:
3809 if finally_error_label in code.labels_used and self.preserve_exception:
3810 over_label = code.new_label()
3811 code.put_goto(over_label);
3812 code.put_label(finally_error_label)
3813 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
3814 for var in Naming.exc_vars:
3815 code.putln("Py_XDECREF(%s);" % var)
3817 code.put_goto(old_error_label)
3818 code.put_label(over_label)
3819 code.error_label = old_error_label
3822 "switch (__pyx_why) {")
3823 for i in cases_used:
3824 old_label = old_labels[i]
3825 if old_label == old_error_label and self.preserve_exception:
3826 self.put_error_uncatcher(code, i+1, old_error_label)
3828 code.use_label(old_label)
3830 "case %s: goto %s;" % (
3838 def put_error_catcher(self, code, error_label, i, catch_label):
3839 code.globalstate.use_utility_code(restore_exception_utility_code)
3846 code.put_var_xdecrefs_clear(self.cleanup_list)
3848 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
3852 Naming.exc_lineno_name, Naming.lineno_cname))
3856 code.put_goto(catch_label)
3860 def put_error_uncatcher(self, code, i, error_label):
3861 code.globalstate.use_utility_code(restore_exception_utility_code)
3866 "__Pyx_ErrRestore(%s, %s, %s);" %
3870 Naming.lineno_cname, Naming.exc_lineno_name))
3871 for var in Naming.exc_vars:
3875 code.put_goto(error_label)
3879 def annotate(self, code):
3880 self.body.annotate(code)
3881 self.finally_clause.annotate(code)
3884 class GILStatNode(TryFinallyStatNode):
3885 # 'with gil' or 'with nogil' statement
3887 # state string 'gil' or 'nogil'
3891 preserve_exception = 0
3893 def __init__(self, pos, state, body):
3895 TryFinallyStatNode.__init__(self, pos,
3897 finally_clause = GILExitNode(pos, state = state))
3899 def analyse_expressions(self, env):
3900 was_nogil = env.nogil
3902 TryFinallyStatNode.analyse_expressions(self, env)
3903 env.nogil = was_nogil
3905 def gil_check(self, env):
3908 def generate_execution_code(self, code):
3909 code.putln("/*with %s:*/ {" % self.state)
3910 if self.state == 'gil':
3911 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
3913 code.putln("PyThreadState *_save;")
3914 code.putln("Py_UNBLOCK_THREADS")
3915 TryFinallyStatNode.generate_execution_code(self, code)
3919 class GILExitNode(StatNode):
3920 # Used as the 'finally' block in a GILStatNode
3922 # state string 'gil' or 'nogil'
3926 def analyse_expressions(self, env):
3929 def generate_execution_code(self, code):
3930 if self.state == 'gil':
3931 code.putln("PyGILState_Release();")
3933 code.putln("Py_BLOCK_THREADS")
3936 class CImportStatNode(StatNode):
3939 # module_name string Qualified name of module being imported
3940 # as_name string or None Name specified in "as" clause, if any
3944 def analyse_declarations(self, env):
3945 if not env.is_module_scope:
3946 error(self.pos, "cimport only allowed at module level")
3948 module_scope = env.find_module(self.module_name, self.pos)
3949 if "." in self.module_name:
3950 names = [EncodedString(name) for name in self.module_name.split(".")]
3952 top_module_scope = env.context.find_submodule(top_name)
3953 module_scope = top_module_scope
3954 for name in names[1:]:
3955 submodule_scope = module_scope.find_submodule(name)
3956 module_scope.declare_module(name, submodule_scope, self.pos)
3957 module_scope = submodule_scope
3959 env.declare_module(self.as_name, module_scope, self.pos)
3961 env.declare_module(top_name, top_module_scope, self.pos)
3963 name = self.as_name or self.module_name
3964 env.declare_module(name, module_scope, self.pos)
3966 def analyse_expressions(self, env):
3969 def generate_execution_code(self, code):
3973 class FromCImportStatNode(StatNode):
3974 # from ... cimport statement
3976 # module_name string Qualified name of module
3977 # imported_names [(pos, name, as_name, kind)] Names to be imported
3981 def analyse_declarations(self, env):
3982 if not env.is_module_scope:
3983 error(self.pos, "cimport only allowed at module level")
3985 module_scope = env.find_module(self.module_name, self.pos)
3986 env.add_imported_module(module_scope)
3987 for pos, name, as_name, kind in self.imported_names:
3989 for local_name, entry in module_scope.entries.items():
3990 env.add_imported_entry(local_name, entry, pos)
3992 entry = module_scope.lookup(name)
3994 if kind and not self.declaration_matches(entry, kind):
3995 entry.redeclared(pos)
3997 if kind == 'struct' or kind == 'union':
3998 entry = module_scope.declare_struct_or_union(name,
3999 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4000 elif kind == 'class':
4001 entry = module_scope.declare_c_class(name, pos = pos,
4002 module_name = self.module_name)
4004 error(pos, "Name '%s' not declared in module '%s'"
4005 % (name, self.module_name))
4008 local_name = as_name or name
4009 env.add_imported_entry(local_name, entry, pos)
4011 def declaration_matches(self, entry, kind):
4012 if not entry.is_type:
4016 if not type.is_extension_type:
4019 if not type.is_struct_or_union:
4021 if kind <> type.kind:
4025 def analyse_expressions(self, env):
4028 def generate_execution_code(self, code):
4032 class FromImportStatNode(StatNode):
4033 # from ... import statement
4036 # items [(string, NameNode)]
4037 # interned_items [(string, NameNode)]
4038 # item PyTempNode used internally
4039 # import_star boolean used internally
4041 child_attrs = ["module"]
4044 def analyse_declarations(self, env):
4045 for name, target in self.items:
4047 if not env.is_module_scope:
4048 error(self.pos, "import * only allowed at module level")
4050 env.has_import_star = 1
4051 self.import_star = 1
4053 target.analyse_target_declaration(env)
4055 def analyse_expressions(self, env):
4057 self.module.analyse_expressions(env)
4058 self.item = ExprNodes.PyTempNode(self.pos, env)
4059 self.item.allocate_temp(env)
4060 self.interned_items = []
4061 for name, target in self.items:
4063 for _, entry in env.entries.items():
4064 if not entry.is_type and entry.type.is_extension_type:
4065 env.use_utility_code(ExprNodes.type_test_utility_code)
4068 self.interned_items.append(
4069 (env.intern_identifier(name), target))
4070 target.analyse_target_expression(env, None)
4071 #target.release_target_temp(env) # was release_temp ?!?
4072 self.module.release_temp(env)
4073 self.item.release_temp(env)
4075 def generate_execution_code(self, code):
4076 self.module.generate_evaluation_code(code)
4077 if self.import_star:
4079 'if (%s(%s) < 0) %s;' % (
4081 self.module.py_result(),
4082 code.error_goto(self.pos)))
4083 for cname, target in self.interned_items:
4085 '%s = PyObject_GetAttr(%s, %s); %s' % (
4086 self.item.result_code,
4087 self.module.py_result(),
4089 code.error_goto_if_null(self.item.result_code, self.pos)))
4090 target.generate_assignment_code(self.item, code)
4091 self.module.generate_disposal_code(code)
4094 #------------------------------------------------------------------------------------
4096 # Runtime support code
4098 #------------------------------------------------------------------------------------
4100 utility_function_predeclarations = \
4103 #define INLINE __inline__
4105 #define INLINE __inline
4110 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4114 static int %(skip_dispatch_cname)s = 0;
4116 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4118 if Options.gcc_branch_hints:
4119 branch_prediction_macros = \
4122 /* Test for GCC > 2.95 */
4123 #if __GNUC__ > 2 || \
4124 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4125 #define likely(x) __builtin_expect(!!(x), 1)
4126 #define unlikely(x) __builtin_expect(!!(x), 0)
4127 #else /* __GNUC__ > 2 ... */
4128 #define likely(x) (x)
4129 #define unlikely(x) (x)
4130 #endif /* __GNUC__ > 2 ... */
4131 #else /* __GNUC__ */
4132 #define likely(x) (x)
4133 #define unlikely(x) (x)
4134 #endif /* __GNUC__ */
4137 branch_prediction_macros = \
4139 #define likely(x) (x)
4140 #define unlikely(x) (x)
4143 #get_name_predeclaration = \
4144 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4146 #get_name_interned_predeclaration = \
4147 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4149 #------------------------------------------------------------------------------------
4151 printing_utility_code = [
4153 static int __Pyx_Print(PyObject *, int); /*proto*/
4154 #if PY_MAJOR_VERSION >= 3
4155 static PyObject* %s = 0;
4156 static PyObject* %s = 0;
4158 """ % (Naming.print_function, Naming.print_function_kwargs), r"""
4159 #if PY_MAJOR_VERSION < 3
4160 static PyObject *__Pyx_GetStdout(void) {
4161 PyObject *f = PySys_GetObject("stdout");
4163 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4168 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4173 if (!(f = __Pyx_GetStdout()))
4175 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4176 if (PyFile_SoftSpace(f, 1)) {
4177 if (PyFile_WriteString(" ", f) < 0)
4180 v = PyTuple_GET_ITEM(arg_tuple, i);
4181 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4183 if (PyString_Check(v)) {
4184 char *s = PyString_AsString(v);
4185 Py_ssize_t len = PyString_Size(v);
4187 isspace(Py_CHARMASK(s[len-1])) &&
4189 PyFile_SoftSpace(f, 0);
4193 if (PyFile_WriteString("\n", f) < 0)
4195 PyFile_SoftSpace(f, 0);
4200 #else /* Python 3 has a print function */
4201 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4202 PyObject* kwargs = 0;
4203 PyObject* result = 0;
4204 PyObject* end_string;
4205 if (!%(PRINT_FUNCTION)s) {
4206 %(PRINT_FUNCTION)s = PyObject_GetAttrString(%(BUILTINS)s, "print");
4207 if (!%(PRINT_FUNCTION)s)
4211 if (!%(PRINT_KWARGS)s) {
4212 %(PRINT_KWARGS)s = PyDict_New();
4213 if (!%(PRINT_KWARGS)s)
4215 end_string = PyUnicode_FromStringAndSize(" ", 1);
4218 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4219 Py_DECREF(end_string);
4222 Py_DECREF(end_string);
4224 kwargs = %(PRINT_KWARGS)s;
4226 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4233 """ % {'BUILTINS' : Naming.builtins_cname,
4234 'PRINT_FUNCTION' : Naming.print_function,
4235 'PRINT_KWARGS' : Naming.print_function_kwargs}
4238 #------------------------------------------------------------------------------------
4240 # The following function is based on do_raise() from ceval.c.
4242 raise_utility_code = [
4244 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4246 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4250 /* First, check the traceback argument, replacing None with NULL. */
4251 if (tb == Py_None) {
4255 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4256 PyErr_SetString(PyExc_TypeError,
4257 "raise: arg 3 must be a traceback or None");
4260 /* Next, replace a missing value with None */
4261 if (value == NULL) {
4265 #if PY_VERSION_HEX < 0x02050000
4266 if (!PyClass_Check(type))
4268 if (!PyType_Check(type))
4271 /* Raising an instance. The value should be a dummy. */
4272 if (value != Py_None) {
4273 PyErr_SetString(PyExc_TypeError,
4274 "instance exception may not have a separate value");
4277 /* Normalize to raise <class>, <instance> */
4280 #if PY_VERSION_HEX < 0x02050000
4281 if (PyInstance_Check(type)) {
4282 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4287 PyErr_SetString(PyExc_TypeError,
4288 "raise: exception must be an old-style class or instance");
4292 type = (PyObject*) Py_TYPE(type);
4294 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4295 PyErr_SetString(PyExc_TypeError,
4296 "raise: exception class must be a subclass of BaseException");
4301 __Pyx_ErrRestore(type, value, tb);
4311 #------------------------------------------------------------------------------------
4313 reraise_utility_code = [
4315 static void __Pyx_ReRaise(void); /*proto*/
4317 static void __Pyx_ReRaise(void) {
4318 PyThreadState *tstate = PyThreadState_Get();
4319 PyObject *type = tstate->exc_type;
4320 PyObject *value = tstate->exc_value;
4321 PyObject *tb = tstate->exc_traceback;
4325 __Pyx_ErrRestore(type, value, tb);
4329 #------------------------------------------------------------------------------------
4331 arg_type_test_utility_code = [
4333 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name, int exact); /*proto*/
4335 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed, char *name, int exact) {
4337 PyErr_Format(PyExc_SystemError, "Missing type object");
4340 if (none_allowed && obj == Py_None) return 1;
4342 if (Py_TYPE(obj) == type) return 1;
4345 if (PyObject_TypeCheck(obj, type)) return 1;
4347 PyErr_Format(PyExc_TypeError,
4348 "Argument '%s' has incorrect type (expected %s, got %s)",
4349 name, type->tp_name, Py_TYPE(obj)->tp_name);
4354 #------------------------------------------------------------------------------------
4356 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
4357 # many or too few positional arguments were found. This handles
4358 # Py_ssize_t formatting correctly.
4360 raise_argtuple_invalid_utility_code = [
4362 static INLINE void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
4363 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
4365 static INLINE void __Pyx_RaiseArgtupleInvalid(
4366 const char* func_name,
4370 Py_ssize_t num_found)
4372 Py_ssize_t num_expected;
4373 const char *number, *more_or_less;
4375 if (num_found < num_min) {
4376 num_expected = num_min;
4377 more_or_less = "at least";
4379 num_expected = num_max;
4380 more_or_less = "at most";
4383 more_or_less = "exactly";
4385 number = (num_expected == 1) ? "" : "s";
4386 PyErr_Format(PyExc_TypeError,
4387 #if PY_VERSION_HEX < 0x02050000
4388 "%s() takes %s %d positional argument%s (%d given)",
4390 "%s() takes %s %zd positional argument%s (%zd given)",
4392 func_name, more_or_less, num_expected, number, num_found);
4396 raise_keyword_required_utility_code = [
4398 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
4400 static INLINE void __Pyx_RaiseKeywordRequired(
4401 const char* func_name,
4404 PyErr_Format(PyExc_TypeError,
4405 #if PY_MAJOR_VERSION >= 3
4406 "%s() needs keyword-only argument %U", func_name, kw_name);
4408 "%s() needs keyword-only argument %s", func_name,
4409 PyString_AS_STRING(kw_name));
4414 raise_double_keywords_utility_code = [
4416 static INLINE void __Pyx_RaiseDoubleKeywordsError(
4417 const char* func_name, PyObject* kw_name); /*proto*/
4419 static INLINE void __Pyx_RaiseDoubleKeywordsError(
4420 const char* func_name,
4423 PyErr_Format(PyExc_TypeError,
4424 #if PY_MAJOR_VERSION >= 3
4425 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
4427 "%s() got multiple values for keyword argument '%s'", func_name,
4428 PyString_AS_STRING(kw_name));
4433 #------------------------------------------------------------------------------------
4435 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
4436 # were passed to a function, or if any keywords were passed to a
4437 # function that does not accept them.
4439 keyword_string_check_utility_code = [
4441 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
4442 const char* function_name, int kw_allowed); /*proto*/
4444 static INLINE int __Pyx_CheckKeywordStrings(
4446 const char* function_name,
4451 while (PyDict_Next(kwdict, &pos, &key, 0)) {
4452 #if PY_MAJOR_VERSION < 3
4453 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
4455 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
4457 goto invalid_keyword_type;
4459 if ((!kw_allowed) && unlikely(key))
4460 goto invalid_keyword;
4462 invalid_keyword_type:
4463 PyErr_Format(PyExc_TypeError,
4464 "%s() keywords must be strings", function_name);
4467 PyErr_Format(PyExc_TypeError,
4468 #if PY_MAJOR_VERSION < 3
4469 "%s() got an unexpected keyword argument '%s'",
4470 function_name, PyString_AsString(key));
4472 "%s() got an unexpected keyword argument '%U'",
4473 function_name, key);
4479 #------------------------------------------------------------------------------------
4481 # __Pyx_SplitKeywords copies the keyword arguments that are not named
4482 # in argnames[] from the kwds dict into kwds2. If kwds2 is NULL,
4483 # these keywords will raise an invalid keyword error.
4485 # Three kinds of errors are checked: 1) non-string keywords, 2)
4486 # unexpected keywords and 3) overlap with positional arguments.
4488 # If num_posargs is greater 0, it denotes the number of positional
4489 # arguments that were passed and that must therefore not appear
4490 # amongst the keywords as well.
4492 # This method does not check for required keyword arguments.
4495 split_keywords_utility_code = [
4497 static int __Pyx_SplitKeywords(PyObject *kwds, PyObject **argnames[], \
4498 PyObject *kwds2, Py_ssize_t num_pos_args, const char* function_name); /*proto*/
4500 static int __Pyx_SplitKeywords(
4502 PyObject **argnames[],
4504 Py_ssize_t num_pos_args,
4505 const char* function_name)
4507 PyObject *key = 0, *value = 0;
4511 while (PyDict_Next(kwds, &pos, &key, &value)) {
4512 #if PY_MAJOR_VERSION < 3
4513 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
4515 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
4517 goto invalid_keyword_type;
4520 while (*name && (**name != key)) name++;
4522 for (name = argnames; *name; name++) {
4523 #if PY_MAJOR_VERSION >= 3
4524 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
4525 PyUnicode_Compare(**name, key) == 0) break;
4527 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
4528 strcmp(PyString_AS_STRING(**name),
4529 PyString_AS_STRING(key)) == 0) break;
4534 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
4536 goto invalid_keyword;
4540 if (*name && ((name-argnames) < num_pos_args))
4541 goto arg_passed_twice;
4546 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
4548 invalid_keyword_type:
4549 PyErr_Format(PyExc_TypeError,
4550 "%s() keywords must be strings", function_name);
4553 PyErr_Format(PyExc_TypeError,
4554 #if PY_MAJOR_VERSION < 3
4555 "%s() got an unexpected keyword argument '%s'",
4556 function_name, PyString_AsString(key));
4558 "%s() got an unexpected keyword argument '%U'",
4559 function_name, key);
4566 #------------------------------------------------------------------------------------
4568 unraisable_exception_utility_code = [
4570 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
4572 static void __Pyx_WriteUnraisable(const char *name) {
4573 PyObject *old_exc, *old_val, *old_tb;
4575 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
4576 #if PY_MAJOR_VERSION < 3
4577 ctx = PyString_FromString(name);
4579 ctx = PyUnicode_FromString(name);
4581 __Pyx_ErrRestore(old_exc, old_val, old_tb);
4583 PyErr_WriteUnraisable(Py_None);
4585 PyErr_WriteUnraisable(ctx);
4591 #------------------------------------------------------------------------------------
4593 traceback_utility_code = [
4595 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
4597 #include "compile.h"
4598 #include "frameobject.h"
4599 #include "traceback.h"
4601 static void __Pyx_AddTraceback(const char *funcname) {
4602 PyObject *py_srcfile = 0;
4603 PyObject *py_funcname = 0;
4604 PyObject *py_globals = 0;
4605 PyObject *empty_string = 0;
4606 PyCodeObject *py_code = 0;
4607 PyFrameObject *py_frame = 0;
4609 #if PY_MAJOR_VERSION < 3
4610 py_srcfile = PyString_FromString(%(FILENAME)s);
4612 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
4614 if (!py_srcfile) goto bad;
4616 #if PY_MAJOR_VERSION < 3
4617 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
4619 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
4623 #if PY_MAJOR_VERSION < 3
4624 py_funcname = PyString_FromString(funcname);
4626 py_funcname = PyUnicode_FromString(funcname);
4629 if (!py_funcname) goto bad;
4630 py_globals = PyModule_GetDict(%(GLOBALS)s);
4631 if (!py_globals) goto bad;
4632 #if PY_MAJOR_VERSION < 3
4633 empty_string = PyString_FromStringAndSize("", 0);
4635 empty_string = PyBytes_FromStringAndSize("", 0);
4637 if (!empty_string) goto bad;
4638 py_code = PyCode_New(
4639 0, /*int argcount,*/
4640 #if PY_MAJOR_VERSION >= 3
4641 0, /*int kwonlyargcount,*/
4644 0, /*int stacksize,*/
4646 empty_string, /*PyObject *code,*/
4647 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
4648 %(EMPTY_TUPLE)s, /*PyObject *names,*/
4649 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
4650 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
4651 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
4652 py_srcfile, /*PyObject *filename,*/
4653 py_funcname, /*PyObject *name,*/
4654 %(LINENO)s, /*int firstlineno,*/
4655 empty_string /*PyObject *lnotab*/
4657 if (!py_code) goto bad;
4658 py_frame = PyFrame_New(
4659 PyThreadState_Get(), /*PyThreadState *tstate,*/
4660 py_code, /*PyCodeObject *code,*/
4661 py_globals, /*PyObject *globals,*/
4662 0 /*PyObject *locals*/
4664 if (!py_frame) goto bad;
4665 py_frame->f_lineno = %(LINENO)s;
4666 PyTraceBack_Here(py_frame);
4668 Py_XDECREF(py_srcfile);
4669 Py_XDECREF(py_funcname);
4670 Py_XDECREF(empty_string);
4671 Py_XDECREF(py_code);
4672 Py_XDECREF(py_frame);
4675 'FILENAME': Naming.filename_cname,
4676 'LINENO': Naming.lineno_cname,
4677 'CFILENAME': Naming.cfilenm_cname,
4678 'CLINENO': Naming.clineno_cname,
4679 'GLOBALS': Naming.module_cname,
4680 'EMPTY_TUPLE' : Naming.empty_tuple,
4683 restore_exception_utility_code = [
4685 void INLINE __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4686 void INLINE __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
4688 void INLINE __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
4689 PyObject *tmp_type, *tmp_value, *tmp_tb;
4690 PyThreadState *tstate = PyThreadState_GET();
4692 tmp_type = tstate->curexc_type;
4693 tmp_value = tstate->curexc_value;
4694 tmp_tb = tstate->curexc_traceback;
4695 tstate->curexc_type = type;
4696 tstate->curexc_value = value;
4697 tstate->curexc_traceback = tb;
4698 Py_XDECREF(tmp_type);
4699 Py_XDECREF(tmp_value);
4703 void INLINE __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
4704 PyThreadState *tstate = PyThreadState_GET();
4705 *type = tstate->curexc_type;
4706 *value = tstate->curexc_value;
4707 *tb = tstate->curexc_traceback;
4709 tstate->curexc_type = 0;
4710 tstate->curexc_value = 0;
4711 tstate->curexc_traceback = 0;
4716 #------------------------------------------------------------------------------------
4718 set_vtable_utility_code = [
4720 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
4722 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
4723 PyObject *pycobj = 0;
4726 pycobj = PyCObject_FromVoidPtr(vtable, 0);
4729 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
4742 #------------------------------------------------------------------------------------
4744 get_vtable_utility_code = [
4746 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
4748 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
4752 pycobj = PyMapping_GetItemString(dict, "__pyx_vtable__");
4755 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
4756 if (!*(void **)vtabptr)
4769 #------------------------------------------------------------------------------------
4771 init_string_tab_utility_code = [
4773 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
4775 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
4777 #if PY_MAJOR_VERSION < 3
4778 if (t->is_unicode && (!t->is_identifier)) {
4779 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
4780 } else if (t->intern) {
4781 *t->p = PyString_InternFromString(t->s);
4783 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
4785 #else /* Python 3+ has unicode identifiers */
4786 if (t->is_identifier || (t->is_unicode && t->intern)) {
4787 *t->p = PyUnicode_InternFromString(t->s);
4788 } else if (t->is_unicode) {
4789 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
4791 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
4802 #------------------------------------------------------------------------------------
4804 get_exception_utility_code = [
4806 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
4808 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
4809 PyObject *tmp_type, *tmp_value, *tmp_tb;
4810 PyThreadState *tstate = PyThreadState_GET();
4811 __Pyx_ErrFetch(type, value, tb);
4812 PyErr_NormalizeException(type, value, tb);
4813 if (PyErr_Occurred())
4818 tmp_type = tstate->exc_type;
4819 tmp_value = tstate->exc_value;
4820 tmp_tb = tstate->exc_traceback;
4821 tstate->exc_type = *type;
4822 tstate->exc_value = *value;
4823 tstate->exc_traceback = *tb;
4824 /* Make sure tstate is in a consistent state when we XDECREF
4825 these objects (XDECREF may run arbitrary code). */
4826 Py_XDECREF(tmp_type);
4827 Py_XDECREF(tmp_value);
4839 #------------------------------------------------------------------------------------