2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 from DebugFlags import debug_disposal_code
24 absolute_path_length = 0
26 def relative_position(pos):
28 We embed the relative filename in the generated C file, since we
29 don't want to have to regnerate and compile all the source code
30 whenever the Python install directory moves (which could happen,
31 e.g,. when distributing binaries.)
34 a position tuple -- (absolute filename, line number column position)
42 global absolute_path_length
43 if absolute_path_length==0:
44 absolute_path_length = len(os.path.abspath(os.getcwd()))
45 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
47 def embed_position(pos, docstring):
48 if not Options.embed_pos_in_docstring:
50 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
53 return EncodedString(pos_line)
55 # make sure we can encode the filename in the docstring encoding
56 # otherwise make the docstring a unicode string
57 encoding = docstring.encoding
58 if encoding is not None:
60 encoded_bytes = pos_line.encode(encoding)
61 except UnicodeEncodeError:
65 # reuse the string encoding of the original docstring
66 doc = EncodedString(pos_line)
68 doc = EncodedString(pos_line + u'\n' + docstring)
69 doc.encoding = encoding
73 from Code import CCodeWriter
74 from types import FunctionType
76 def write_func_call(func):
78 if len(args) > 1 and isinstance(args[1], CCodeWriter):
79 # here we annotate the code with this function call
80 # but only if new code is generated
82 marker = ' /* %s -> %s.%s %s */' % (
83 ' ' * code.call_level,
84 node.__class__.__name__,
87 pristine = code.buffer.stream.tell()
89 start = code.buffer.stream.tell()
91 res = func(*args, **kwds)
93 if start == code.buffer.stream.tell():
94 code.buffer.stream.seek(pristine)
96 marker = marker.replace('->', '<-')
100 return func(*args, **kwds)
103 class VerboseCodeWriter(type):
104 # Set this as a metaclass to trace function calls in code.
105 # This slows down code generation and makes much larger files.
106 def __new__(cls, name, bases, attrs):
108 for mname, m in attrs.items():
109 if isinstance(m, FunctionType):
110 attrs[mname] = write_func_call(m)
111 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
115 # pos (string, int, int) Source file position
116 # is_name boolean Is a NameNode
117 # is_literal boolean Is a ConstNode
119 if DebugFlags.debug_trace_code_generation:
120 __metaclass__ = VerboseCodeWriter
126 # All descandants should set child_attrs to a list of the attributes
127 # containing nodes considered "children" in the tree. Each such attribute
128 # can either contain a single node or a list of nodes. See Visitor.py.
131 def __init__(self, pos, **kw):
133 self.__dict__.update(kw)
135 gil_message = "Operation"
138 def _gil_check(self, env):
143 error(self.pos, "%s not allowed without gil" % self.gil_message)
145 def clone_node(self):
146 """Clone the node. This is defined as a shallow copy, except for member lists
147 amongst the child attributes (from get_child_accessors) which are also
148 copied. Lists containing child nodes are thus seen as a way for the node
149 to hold multiple children directly; the list is not treated as a seperate
150 level in the tree."""
151 result = copy.copy(self)
152 for attrname in result.child_attrs:
153 value = getattr(result, attrname)
154 if isinstance(value, list):
155 setattr(result, attrname, [x for x in value])
160 # There are 4 phases of parse tree processing, applied in order to
161 # all the statements in a given scope-block:
163 # (0) analyse_control_flow
164 # Create the control flow tree into which state can be asserted and
167 # (1) analyse_declarations
168 # Make symbol table entries for all declarations at the current
169 # level, both explicit (def, cdef, etc.) and implicit (assignment
170 # to an otherwise undeclared name).
172 # (2) analyse_expressions
173 # Determine the result types of expressions and fill in the
174 # 'type' attribute of each ExprNode. Insert coercion nodes into the
175 # tree where needed to convert to and from Python objects.
176 # Allocate temporary locals for intermediate results. Fill
177 # in the 'result_code' attribute of each ExprNode with a C code
181 # Emit C code for all declarations, statements and expressions.
182 # Recursively applies the 3 processing phases to the bodies of
186 def analyse_control_flow(self, env):
189 def analyse_declarations(self, env):
192 def analyse_expressions(self, env):
193 raise InternalError("analyse_expressions not implemented for %s" % \
194 self.__class__.__name__)
196 def generate_code(self, code):
197 raise InternalError("generate_code not implemented for %s" % \
198 self.__class__.__name__)
200 def annotate(self, code):
201 # mro does the wrong thing
202 if isinstance(self, BlockNode):
203 self.body.annotate(code)
208 except AttributeError:
210 if not self.child_attrs:
213 for attr in self.child_attrs:
214 child = getattr(self, attr)
215 # Sometimes lists, sometimes nodes
218 elif isinstance(child, list):
220 pos = max(pos, c.end_pos())
222 pos = max(pos, child.end_pos())
226 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
228 return "<...nesting level cutoff...>"
229 if encountered is None:
231 if id(self) in encountered:
232 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
233 encountered.add(id(self))
235 def dump_child(x, level):
236 if isinstance(x, Node):
237 return x.dump(level, filter_out, cutoff-1, encountered)
238 elif isinstance(x, list):
239 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
244 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
246 return "<%s (%d)>" % (self.__class__.__name__, id(self))
249 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
250 for key, value in attrs:
251 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
252 res += "%s>" % indent
255 class CompilerDirectivesNode(Node):
257 Sets compiler directives for the children nodes
259 # directives {string:value} A dictionary holding the right value for
260 # *all* possible directives.
262 child_attrs = ["body"]
264 def analyse_control_flow(self, env):
266 env.directives = self.directives
267 self.body.analyse_control_flow(env)
270 def analyse_declarations(self, env):
272 env.directives = self.directives
273 self.body.analyse_declarations(env)
276 def analyse_expressions(self, env):
278 env.directives = self.directives
279 self.body.analyse_expressions(env)
282 def generate_function_definitions(self, env, code):
283 env_old = env.directives
284 code_old = code.globalstate.directives
285 code.globalstate.directives = self.directives
286 self.body.generate_function_definitions(env, code)
287 env.directives = env_old
288 code.globalstate.directives = code_old
290 def generate_execution_code(self, code):
291 old = code.globalstate.directives
292 code.globalstate.directives = self.directives
293 self.body.generate_execution_code(code)
294 code.globalstate.directives = old
296 def annotate(self, code):
297 old = code.globalstate.directives
298 code.globalstate.directives = self.directives
299 self.body.annotate(code)
300 code.globalstate.directives = old
302 class BlockNode(object):
303 # Mixin class for nodes representing a declaration block.
305 def generate_cached_builtins_decls(self, env, code):
306 entries = env.global_scope().undeclared_cached_builtins
307 for entry in entries:
308 code.globalstate.add_cached_builtin_decl(entry)
312 class StatListNode(Node):
313 # stats a list of StatNode
315 child_attrs = ["stats"]
317 def create_analysed(pos, env, *args, **kw):
318 node = StatListNode(pos, *args, **kw)
319 return node # No node-specific analysis necesarry
320 create_analysed = staticmethod(create_analysed)
322 def analyse_control_flow(self, env):
323 for stat in self.stats:
324 stat.analyse_control_flow(env)
326 def analyse_declarations(self, env):
327 #print "StatListNode.analyse_declarations" ###
328 for stat in self.stats:
329 stat.analyse_declarations(env)
331 def analyse_expressions(self, env):
332 #print "StatListNode.analyse_expressions" ###
333 for stat in self.stats:
334 stat.analyse_expressions(env)
336 def generate_function_definitions(self, env, code):
337 #print "StatListNode.generate_function_definitions" ###
338 for stat in self.stats:
339 stat.generate_function_definitions(env, code)
341 def generate_execution_code(self, code):
342 #print "StatListNode.generate_execution_code" ###
343 for stat in self.stats:
344 code.mark_pos(stat.pos)
345 stat.generate_execution_code(code)
347 def annotate(self, code):
348 for stat in self.stats:
352 class StatNode(Node):
354 # Code generation for statements is split into the following subphases:
356 # (1) generate_function_definitions
357 # Emit C code for the definitions of any structs,
358 # unions, enums and functions defined in the current
361 # (2) generate_execution_code
362 # Emit C code for executable statements.
365 def generate_function_definitions(self, env, code):
368 def generate_execution_code(self, code):
369 raise InternalError("generate_execution_code not implemented for %s" % \
370 self.__class__.__name__)
373 class CDefExternNode(StatNode):
374 # include_file string or None
377 child_attrs = ["body"]
379 def analyse_declarations(self, env):
380 if self.include_file:
381 env.add_include_file(self.include_file)
382 old_cinclude_flag = env.in_cinclude
384 self.body.analyse_declarations(env)
385 env.in_cinclude = old_cinclude_flag
387 def analyse_expressions(self, env):
390 def generate_execution_code(self, code):
393 def annotate(self, code):
394 self.body.annotate(code)
397 class CDeclaratorNode(Node):
398 # Part of a C declaration.
400 # Processing during analyse_declarations phase:
403 # Returns (name, type) pair where name is the
404 # CNameDeclaratorNode of the name being declared
405 # and type is the type it is being declared as.
407 # calling_convention string Calling convention of CFuncDeclaratorNode
408 # for which this is a base
412 calling_convention = ""
415 class CNameDeclaratorNode(CDeclaratorNode):
416 # name string The Pyrex name being declared
417 # cname string or None C name, if specified
418 # default ExprNode or None the value assigned on declaration
420 child_attrs = ['default']
424 def analyse(self, base_type, env, nonempty = 0):
425 if nonempty and self.name == '':
426 # May have mistaken the name for the type.
427 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
428 error(self.pos, "Missing argument name")
429 elif base_type.is_void:
430 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
432 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
433 base_type = py_object_type
434 self.type = base_type
435 return self, base_type
437 class CPtrDeclaratorNode(CDeclaratorNode):
438 # base CDeclaratorNode
440 child_attrs = ["base"]
442 def analyse(self, base_type, env, nonempty = 0):
443 if base_type.is_pyobject:
445 "Pointer base type cannot be a Python object")
446 ptr_type = PyrexTypes.c_ptr_type(base_type)
447 return self.base.analyse(ptr_type, env, nonempty = nonempty)
449 class CArrayDeclaratorNode(CDeclaratorNode):
450 # base CDeclaratorNode
453 child_attrs = ["base", "dimension"]
455 def analyse(self, base_type, env, nonempty = 0):
457 self.dimension.analyse_const_expression(env)
458 if not self.dimension.type.is_int:
459 error(self.dimension.pos, "Array dimension not integer")
460 size = self.dimension.get_constant_result_code()
468 if not base_type.is_complete():
470 "Array element type '%s' is incomplete" % base_type)
471 if base_type.is_pyobject:
473 "Array element cannot be a Python object")
474 if base_type.is_cfunction:
476 "Array element cannot be a function")
477 array_type = PyrexTypes.c_array_type(base_type, size)
478 return self.base.analyse(array_type, env, nonempty = nonempty)
481 class CFuncDeclaratorNode(CDeclaratorNode):
482 # base CDeclaratorNode
483 # args [CArgDeclNode]
484 # has_varargs boolean
485 # exception_value ConstNode
486 # exception_check boolean True if PyErr_Occurred check needed
487 # nogil boolean Can be called without gil
488 # with_gil boolean Acquire gil around function body
490 child_attrs = ["base", "args", "exception_value"]
493 optional_arg_count = 0
495 def analyse(self, return_type, env, nonempty = 0):
499 for arg_node in self.args:
500 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
501 name = name_declarator.name
502 if name_declarator.cname:
504 "Function argument cannot have C name specification")
505 # Turn *[] argument into **
507 type = PyrexTypes.c_ptr_type(type.base_type)
508 # Catch attempted C-style func(void) decl
510 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
511 func_type_args.append(
512 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
514 self.optional_arg_count += 1
515 elif self.optional_arg_count:
516 error(self.pos, "Non-default argument follows default argument")
518 if self.optional_arg_count:
519 scope = StructOrUnionScope()
520 scope.declare_var('%sn' % Naming.pyrex_prefix, PyrexTypes.c_int_type, self.pos)
521 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
522 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
523 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
524 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
529 cname = struct_cname)
530 self.op_args_struct.defined_in_pxd = 1
531 self.op_args_struct.used = 1
535 if return_type.is_pyobject \
536 and (self.exception_value or self.exception_check) \
537 and self.exception_check != '+':
539 "Exception clause not allowed for function returning Python object")
541 if self.exception_value:
542 self.exception_value.analyse_const_expression(env)
543 exc_val = self.exception_value.get_constant_result_code()
544 if self.exception_check == '+':
545 exc_val_type = self.exception_value.type
546 if not exc_val_type.is_error and \
547 not exc_val_type.is_pyobject and \
548 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
549 error(self.exception_value.pos,
550 "Exception value must be a Python exception or cdef function with no arguments.")
552 if not return_type.assignable_from(self.exception_value.type):
553 error(self.exception_value.pos,
554 "Exception value incompatible with function return type")
555 exc_check = self.exception_check
556 if return_type.is_array:
558 "Function cannot return an array")
559 if return_type.is_cfunction:
561 "Function cannot return a function")
562 func_type = PyrexTypes.CFuncType(
563 return_type, func_type_args, self.has_varargs,
564 optional_arg_count = self.optional_arg_count,
565 exception_value = exc_val, exception_check = exc_check,
566 calling_convention = self.base.calling_convention,
567 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
568 if self.optional_arg_count:
569 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
570 return self.base.analyse(func_type, env)
573 class CArgDeclNode(Node):
574 # Item in a function declaration argument list.
576 # base_type CBaseTypeNode
577 # declarator CDeclaratorNode
578 # not_none boolean Tagged with 'not None'
579 # default ExprNode or None
580 # default_value PyObjectConst constant for default value
581 # is_self_arg boolean Is the "self" arg of an extension type method
582 # is_kw_only boolean Is a keyword-only argument
584 child_attrs = ["base_type", "declarator", "default"]
589 name_declarator = None
592 def analyse(self, env, nonempty = 0):
593 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
594 if self.type is None:
595 # The parser may missinterpret names as types...
597 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
599 self.declarator.name = self.base_type.name
600 self.base_type.name = None
601 self.base_type.is_basic_c_type = False
604 could_be_name = False
605 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
606 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
607 self.declarator.name = self.base_type.arg_name
608 return self.declarator.analyse(base_type, env, nonempty = nonempty)
610 return self.name_declarator, self.type
612 def calculate_default_value_code(self, code):
613 if self.default_value is None:
615 if self.default.is_literal:
616 # will not output any code, just assign the result_code
617 self.default.generate_evaluation_code(code)
618 return self.type.cast_code(self.default.result())
619 self.default_value = code.get_argument_default_const(self.type)
620 return self.default_value
622 def annotate(self, code):
624 self.default.annotate(code)
627 class CBaseTypeNode(Node):
628 # Abstract base class for C base type nodes.
630 # Processing during analyse_declarations phase:
637 class CAnalysedBaseTypeNode(Node):
642 def analyse(self, env, could_be_name = False):
645 class CSimpleBaseTypeNode(CBaseTypeNode):
647 # module_path [string] Qualifying name components
648 # is_basic_c_type boolean
651 # is_self_arg boolean Is self argument of C method
654 arg_name = None # in case the argument name was interpreted as a type
656 def analyse(self, env, could_be_name = False):
657 # Return type descriptor.
658 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
660 if self.is_basic_c_type:
661 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
663 error(self.pos, "Unrecognised type modifier combination")
664 elif self.name == "object" and not self.module_path:
665 type = py_object_type
666 elif self.name is None:
667 if self.is_self_arg and env.is_c_class_scope:
668 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
669 type = env.parent_type
671 type = py_object_type
674 scope = env.find_imported_module(self.module_path, self.pos)
678 if scope.is_c_class_scope:
679 scope = scope.global_scope()
680 entry = scope.lookup(self.name)
681 if entry and entry.is_type:
684 if self.is_self_arg and env.is_c_class_scope:
685 type = env.parent_type
687 type = py_object_type
688 self.arg_name = self.name
690 error(self.pos, "'%s' is not a type identifier" % self.name)
694 return PyrexTypes.error_type
696 class CBufferAccessTypeNode(CBaseTypeNode):
698 # positional_args [ExprNode] List of positional arguments
699 # keyword_args DictNode Keyword arguments
700 # base_type_node CBaseTypeNode
703 # type PyrexType.BufferType ...containing the right options
706 child_attrs = ["base_type_node", "positional_args",
707 "keyword_args", "dtype_node"]
713 def analyse(self, env, could_be_name = False):
714 base_type = self.base_type_node.analyse(env)
715 if base_type.is_error: return base_type
718 options = Buffer.analyse_buffer_options(
721 self.positional_args,
723 base_type.buffer_defaults)
725 self.type = PyrexTypes.BufferType(base_type, **options)
728 class CComplexBaseTypeNode(CBaseTypeNode):
729 # base_type CBaseTypeNode
730 # declarator CDeclaratorNode
732 child_attrs = ["base_type", "declarator"]
734 def analyse(self, env, could_be_name = False):
735 base = self.base_type.analyse(env, could_be_name)
736 _, type = self.declarator.analyse(base, env)
740 class CVarDefNode(StatNode):
741 # C variable definition or forward/extern function declaration.
743 # visibility 'private' or 'public' or 'extern'
744 # base_type CBaseTypeNode
745 # declarators [CDeclaratorNode]
748 # need_properties [entry]
750 # decorators [cython.locals(...)] or None
751 # directive_locals { string : NameNode } locals defined by cython.locals(...)
753 child_attrs = ["base_type", "declarators"]
757 directive_locals = {}
759 def analyse_declarations(self, env, dest_scope = None):
762 self.dest_scope = dest_scope
763 base_type = self.base_type.analyse(env)
764 if (dest_scope.is_c_class_scope
765 and self.visibility == 'public'
766 and base_type.is_pyobject
767 and (base_type.is_builtin_type or base_type.is_extension_type)):
768 self.need_properties = []
770 visibility = 'private'
772 need_property = False
773 visibility = self.visibility
775 for declarator in self.declarators:
776 name_declarator, type = declarator.analyse(base_type, env)
777 if not type.is_complete():
778 if not (self.visibility == 'extern' and type.is_array):
779 error(declarator.pos,
780 "Variable type '%s' is incomplete" % type)
781 if self.visibility == 'extern' and type.is_pyobject:
782 error(declarator.pos,
783 "Python object cannot be declared extern")
784 name = name_declarator.name
785 cname = name_declarator.cname
787 error(declarator.pos, "Missing name in declaration.")
789 if type.is_cfunction:
790 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
791 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
793 if entry is not None:
794 entry.directive_locals = self.directive_locals
796 if self.directive_locals:
797 s.error("Decorators can only be followed by functions")
798 if self.in_pxd and self.visibility != 'extern':
800 "Only 'extern' C variable declaration allowed in .pxd file")
801 entry = dest_scope.declare_var(name, type, declarator.pos,
802 cname = cname, visibility = visibility, is_cdef = 1)
804 self.need_properties.append(entry)
805 entry.needs_property = 1
808 class CStructOrUnionDefNode(StatNode):
810 # cname string or None
811 # kind "struct" or "union"
812 # typedef_flag boolean
813 # visibility "public" or "private"
815 # attributes [CVarDefNode] or None
818 child_attrs = ["attributes"]
820 def analyse_declarations(self, env):
822 if self.attributes is not None:
823 scope = StructOrUnionScope(self.name)
824 self.entry = env.declare_struct_or_union(
825 self.name, self.kind, scope, self.typedef_flag, self.pos,
826 self.cname, visibility = self.visibility)
827 if self.attributes is not None:
828 if self.in_pxd and not env.in_cinclude:
829 self.entry.defined_in_pxd = 1
830 for attr in self.attributes:
831 attr.analyse_declarations(env, scope)
832 if self.visibility != 'extern':
833 need_typedef_indirection = False
834 for attr in scope.var_entries:
837 type = type.base_type
838 if type == self.entry.type:
839 error(attr.pos, "Struct cannot contain itself as a member.")
840 if self.typedef_flag:
842 type = type.base_type
843 if type == self.entry.type:
844 need_typedef_indirection = True
845 if need_typedef_indirection:
846 # C can't handle typedef structs that refer to themselves.
847 struct_entry = self.entry
848 self.entry = env.declare_typedef(
849 self.name, struct_entry.type, self.pos,
850 cname = self.cname, visibility='ignore')
851 struct_entry.type.typedef_flag = False
852 # FIXME: this might be considered a hack ;-)
853 struct_entry.cname = struct_entry.type.cname = '_' + self.cname
855 def analyse_expressions(self, env):
858 def generate_execution_code(self, code):
862 class CEnumDefNode(StatNode):
863 # name string or None
864 # cname string or None
865 # items [CEnumDefItemNode]
866 # typedef_flag boolean
867 # visibility "public" or "private"
871 child_attrs = ["items"]
873 def analyse_declarations(self, env):
874 self.entry = env.declare_enum(self.name, self.pos,
875 cname = self.cname, typedef_flag = self.typedef_flag,
876 visibility = self.visibility)
877 if self.items is not None:
878 if self.in_pxd and not env.in_cinclude:
879 self.entry.defined_in_pxd = 1
880 for item in self.items:
881 item.analyse_declarations(env, self.entry)
883 def analyse_expressions(self, env):
884 if self.visibility == 'public':
885 self.temp = env.allocate_temp_pyobject()
886 env.release_temp(self.temp)
888 def generate_execution_code(self, code):
889 if self.visibility == 'public':
890 for item in self.entry.enum_values:
891 code.putln("%s = PyInt_FromLong(%s); %s" % (
894 code.error_goto_if_null(self.temp, item.pos)))
895 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
899 code.error_goto(item.pos)))
900 code.putln("%s = 0;" % self.temp)
903 class CEnumDefItemNode(StatNode):
905 # cname string or None
906 # value ExprNode or None
908 child_attrs = ["value"]
910 def analyse_declarations(self, env, enum_entry):
912 self.value.analyse_const_expression(env)
913 if not self.value.type.is_int:
914 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
915 self.value.analyse_const_expression(env)
916 entry = env.declare_const(self.name, enum_entry.type,
917 self.value, self.pos, cname = self.cname,
918 visibility = enum_entry.visibility)
919 enum_entry.enum_values.append(entry)
922 class CTypeDefNode(StatNode):
923 # base_type CBaseTypeNode
924 # declarator CDeclaratorNode
925 # visibility "public" or "private"
928 child_attrs = ["base_type", "declarator"]
930 def analyse_declarations(self, env):
931 base = self.base_type.analyse(env)
932 name_declarator, type = self.declarator.analyse(base, env)
933 name = name_declarator.name
934 cname = name_declarator.cname
935 entry = env.declare_typedef(name, type, self.pos,
936 cname = cname, visibility = self.visibility)
937 if self.in_pxd and not env.in_cinclude:
938 entry.defined_in_pxd = 1
940 def analyse_expressions(self, env):
942 def generate_execution_code(self, code):
946 class FuncDefNode(StatNode, BlockNode):
947 # Base class for function definition nodes.
949 # return_type PyrexType
950 # #filename string C name of filename string const
952 # needs_closure boolean Whether or not this function has inner functions/classes/yield
953 # directive_locals { string : NameNode } locals defined by cython.locals(...)
957 needs_closure = False
959 def analyse_default_values(self, env):
960 genv = env.global_scope()
961 for arg in self.args:
964 arg.default.analyse_types(env)
965 arg.default = arg.default.coerce_to(arg.type, genv)
966 arg.default.allocate_temps(genv)
969 "This argument cannot have a default value")
972 def need_gil_acquisition(self, lenv):
975 def create_local_scope(self, env):
977 while env.is_py_class_scope or env.is_c_class_scope:
978 env = env.outer_scope
979 if self.needs_closure:
980 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
982 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
983 lenv.return_type = self.return_type
984 type = self.entry.type
985 if type.is_cfunction:
986 lenv.nogil = type.nogil and not type.with_gil
987 self.local_scope = lenv
990 def generate_function_definitions(self, env, code):
993 lenv = self.local_scope
995 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
996 self.entry.scope.is_c_class_scope)
998 # Generate C code for header and body of function
999 code.enter_cfunc_scope()
1000 code.return_from_error_cleanup_label = code.new_label()
1002 # ----- Top-level constants used by this function
1003 code.mark_pos(self.pos)
1004 self.generate_cached_builtins_decls(lenv, code)
1005 # ----- Function header
1008 self.py_func.generate_function_header(code,
1009 with_pymethdef = env.is_py_class_scope,
1011 self.generate_function_header(code,
1012 with_pymethdef = env.is_py_class_scope)
1013 # ----- Local variable declarations
1014 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1015 self.generate_argument_declarations(lenv, code)
1016 if self.needs_closure:
1017 code.putln("/* TODO: declare and create scope object */")
1018 code.put_var_declarations(lenv.var_entries)
1020 if not self.return_type.is_void:
1021 if self.return_type.is_pyobject:
1025 (self.return_type.declaration_code(
1026 Naming.retval_cname),
1028 tempvardecl_code = code.insertion_point()
1029 self.generate_keyword_list(code)
1030 # ----- Extern library function declarations
1031 lenv.generate_library_function_declarations(code)
1032 # ----- GIL acquisition
1033 acquire_gil = self.need_gil_acquisition(lenv)
1035 env.use_utility_code(force_init_threads_utility_code)
1036 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1037 # ----- Automatic lead-ins for certain special functions
1039 code.put_setup_refcount_context(self.entry.name)
1040 if is_getbuffer_slot:
1041 self.getbuffer_init(code)
1042 # ----- Fetch arguments
1043 self.generate_argument_parsing_code(env, code)
1044 # If an argument is assigned to in the body, we must
1045 # incref it to properly keep track of refcounts.
1046 for entry in lenv.arg_entries:
1047 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1048 code.put_var_incref(entry)
1049 # ----- Initialise local variables
1050 for entry in lenv.var_entries:
1051 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1052 code.put_init_var_to_py_none(entry)
1053 # ----- Initialise local buffer auxiliary variables
1054 for entry in lenv.var_entries + lenv.arg_entries:
1055 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1056 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1057 # ----- Check and convert arguments
1058 self.generate_argument_type_tests(code)
1059 # ----- Acquire buffer arguments
1060 for entry in lenv.arg_entries:
1061 if entry.type.is_buffer:
1062 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1063 # ----- Function body
1064 self.body.generate_execution_code(code)
1065 # ----- Default return value
1067 if self.return_type.is_pyobject:
1068 #if self.return_type.is_extension_type:
1069 # lhs = "(PyObject *)%s" % Naming.retval_cname
1071 lhs = Naming.retval_cname
1072 code.put_init_to_py_none(lhs, self.return_type)
1074 val = self.return_type.default_value
1076 code.putln("%s = %s;" % (Naming.retval_cname, val))
1077 # ----- Error cleanup
1078 if code.error_label in code.labels_used:
1079 code.put_goto(code.return_label)
1080 code.put_label(code.error_label)
1081 # cleanup temps the old way
1082 code.put_var_xdecrefs(lenv.temp_entries)
1083 # cleanup temps the new way
1084 for cname, type in code.funcstate.all_managed_temps():
1085 code.put_xdecref(cname, type)
1087 # Clean up buffers -- this calls a Python function
1088 # so need to save and restore error state
1089 buffers_present = len(lenv.buffer_entries) > 0
1091 code.globalstate.use_utility_code(restore_exception_utility_code)
1092 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1093 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1094 for entry in lenv.buffer_entries:
1095 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1096 #code.putln("%s = 0;" % entry.cname)
1097 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1099 err_val = self.error_value()
1100 exc_check = self.caller_will_check_exceptions()
1101 if err_val is not None or exc_check:
1102 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1104 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1105 % self.entry.qualified_name, 0)
1107 '__Pyx_WriteUnraisable("%s");' %
1108 self.entry.qualified_name)
1109 env.use_utility_code(unraisable_exception_utility_code)
1110 env.use_utility_code(restore_exception_utility_code)
1111 default_retval = self.return_type.default_value
1112 if err_val is None and default_retval:
1113 err_val = default_retval
1114 if err_val is not None:
1117 Naming.retval_cname,
1120 if is_getbuffer_slot:
1121 self.getbuffer_error_cleanup(code)
1123 # If we are using the non-error cleanup section we should
1124 # jump past it if we have an error. The if-test below determine
1125 # whether this section is used.
1126 if buffers_present or is_getbuffer_slot:
1127 code.put_goto(code.return_from_error_cleanup_label)
1130 # ----- Non-error return cleanup
1131 # If you add anything here, remember to add a condition to the
1132 # if-test above in the error block (so that it can jump past this
1134 code.put_label(code.return_label)
1135 for entry in lenv.buffer_entries:
1137 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1138 if is_getbuffer_slot:
1139 self.getbuffer_normal_cleanup(code)
1140 # ----- Return cleanup for both error and no-error return
1141 code.put_label(code.return_from_error_cleanup_label)
1142 if not Options.init_local_none:
1143 for entry in lenv.var_entries:
1144 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1145 entry.xdecref_cleanup = 1
1146 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1147 # Decref any increfed args
1148 for entry in lenv.arg_entries:
1149 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1150 code.put_var_decref(entry)
1152 # code.putln("/* TODO: decref scope object */")
1154 # This code is duplicated in ModuleNode.generate_module_init_func
1156 default_retval = self.return_type.default_value
1157 err_val = self.error_value()
1158 if err_val is None and default_retval:
1159 err_val = default_retval
1160 if self.return_type.is_pyobject:
1161 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1163 code.put_finish_refcount_context()
1166 code.putln("PyGILState_Release(_save);")
1168 if not self.return_type.is_void:
1169 code.putln("return %s;" % Naming.retval_cname)
1172 # ----- Go back and insert temp variable declarations
1173 tempvardecl_code.put_var_declarations(lenv.temp_entries)
1174 tempvardecl_code.put_temp_declarations(code.funcstate)
1175 # ----- Python version
1176 code.exit_cfunc_scope()
1178 self.py_func.generate_function_definitions(env, code)
1179 self.generate_wrapper_functions(code)
1181 def declare_argument(self, env, arg):
1182 if arg.type.is_void:
1183 error(arg.pos, "Invalid use of 'void'")
1184 elif not arg.type.is_complete() and not arg.type.is_array:
1186 "Argument type '%s' is incomplete" % arg.type)
1187 return env.declare_arg(arg.name, arg.type, arg.pos)
1189 def generate_wrapper_functions(self, code):
1192 def generate_execution_code(self, code):
1193 # Evaluate and store argument default values
1194 for arg in self.args:
1195 default = arg.default
1197 if not default.is_literal:
1198 default.generate_evaluation_code(code)
1199 default.make_owned_reference(code)
1200 result = default.result_as(arg.type)
1203 arg.calculate_default_value_code(code),
1205 if arg.type.is_pyobject:
1206 code.put_giveref(default.result())
1207 default.generate_post_assignment_code(code)
1208 default.free_temps(code)
1209 # For Python class methods, create and store function object
1211 self.assmt.generate_execution_code(code)
1214 # Special code for the __getbuffer__ function
1216 def getbuffer_init(self, code):
1217 info = self.local_scope.arg_entries[1].cname
1218 # Python 3.0 betas have a bug in memoryview which makes it call
1219 # getbuffer with a NULL parameter. For now we work around this;
1220 # the following line should be removed when this bug is fixed.
1221 code.putln("if (%s == NULL) return 0;" % info)
1222 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1223 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1225 def getbuffer_error_cleanup(self, code):
1226 info = self.local_scope.arg_entries[1].cname
1227 code.put_gotref("%s->obj" % info)
1228 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1231 def getbuffer_normal_cleanup(self, code):
1232 info = self.local_scope.arg_entries[1].cname
1233 code.putln("if (%s->obj == Py_None) {" % info)
1234 code.put_gotref("Py_None")
1235 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1238 class CFuncDefNode(FuncDefNode):
1239 # C function definition.
1241 # modifiers ['inline']
1242 # visibility 'private' or 'public' or 'extern'
1243 # base_type CBaseTypeNode
1244 # declarator CDeclaratorNode
1247 # decorators [DecoratorNode] list of decorators
1249 # with_gil boolean Acquire GIL around body
1251 # py_func wrapper for calling from Python
1252 # overridable whether or not this is a cpdef function
1253 # inline_in_pxd whether this is an inline function in a pxd file
1255 child_attrs = ["base_type", "declarator", "body", "py_func"]
1257 inline_in_pxd = False
1259 directive_locals = {}
1261 def unqualified_name(self):
1262 return self.entry.name
1264 def analyse_declarations(self, env):
1265 if 'locals' in env.directives and env.directives['locals']:
1266 self.directive_locals = env.directives['locals']
1267 directive_locals = self.directive_locals
1268 base_type = self.base_type.analyse(env)
1269 # The 2 here is because we need both function and argument names.
1270 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1271 if not type.is_cfunction:
1273 "Suite attached to non-function declaration")
1274 # Remember the actual type according to the function header
1275 # written here, because the type in the symbol table entry
1276 # may be different if we're overriding a C method inherited
1277 # from the base type of an extension type.
1279 type.is_overridable = self.overridable
1280 declarator = self.declarator
1281 while not hasattr(declarator, 'args'):
1282 declarator = declarator.base
1283 self.args = declarator.args
1284 for formal_arg, type_arg in zip(self.args, type.args):
1285 formal_arg.type = type_arg.type
1286 formal_arg.name = type_arg.name
1287 formal_arg.cname = type_arg.cname
1288 name = name_declarator.name
1289 cname = name_declarator.cname
1290 self.entry = env.declare_cfunction(
1291 name, type, self.pos,
1292 cname = cname, visibility = self.visibility,
1293 defining = self.body is not None,
1294 api = self.api, modifiers = self.modifiers)
1295 self.entry.inline_func_in_pxd = self.inline_in_pxd
1296 self.return_type = type.return_type
1298 if self.overridable and len(self.args) > 0:
1300 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1301 self.py_func = DefNode(pos = self.pos,
1302 name = self.entry.name,
1305 starstar_arg = None,
1307 body = py_func_body,
1309 self.py_func.is_module_scope = env.is_module_scope
1310 self.py_func.analyse_declarations(env)
1311 self.entry.as_variable = self.py_func.entry
1312 # Reset scope entry the above cfunction
1313 env.entries[name] = self.entry
1314 if not env.is_module_scope or Options.lookup_module_cpdef:
1315 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1316 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1318 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1320 args = self.type.args
1321 if omit_optional_args:
1322 args = args[:len(args) - self.type.optional_arg_count]
1323 arg_names = [arg.name for arg in args]
1325 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1327 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1328 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1329 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1330 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)
1331 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1333 def declare_arguments(self, env):
1334 for arg in self.type.args:
1336 error(arg.pos, "Missing argument name")
1337 self.declare_argument(env, arg)
1339 def need_gil_acquisition(self, lenv):
1340 return self.type.with_gil
1342 def gil_check(self, env):
1344 with_gil = type.with_gil
1345 if type.nogil and not with_gil:
1346 if type.return_type.is_pyobject:
1348 "Function with Python return type cannot be declared nogil")
1349 for entry in env.var_entries + env.temp_entries:
1350 if entry.type.is_pyobject:
1351 error(self.pos, "Function declared nogil has Python locals or temporaries")
1353 def analyse_expressions(self, env):
1354 if self.py_func is not None:
1355 # this will also analyse the default values
1356 self.py_func.analyse_expressions(env)
1358 self.analyse_default_values(env)
1360 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1363 visibility = self.entry.visibility
1364 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1365 arg_decls.append(arg.declaration_code())
1366 if with_dispatch and self.overridable:
1367 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1368 if type.optional_arg_count and with_opt_args:
1369 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1370 if type.has_varargs:
1371 arg_decls.append("...")
1373 arg_decls = ["void"]
1375 cname = self.entry.func_cname
1376 entity = type.function_header_code(cname, ', '.join(arg_decls))
1377 if visibility == 'public':
1378 dll_linkage = "DL_EXPORT"
1381 header = self.return_type.declaration_code(entity,
1382 dll_linkage = dll_linkage)
1383 if visibility == 'extern':
1384 storage_class = "%s " % Naming.extern_c_macro
1385 elif visibility == 'public':
1388 storage_class = "static "
1389 code.putln("%s%s %s {" % (
1391 ' '.join(self.modifiers).upper(), # macro forms
1394 def generate_argument_declarations(self, env, code):
1395 for arg in self.args:
1397 result = arg.calculate_default_value_code(code)
1398 code.putln('%s = %s;' % (
1399 arg.type.declaration_code(arg.cname), result))
1401 def generate_keyword_list(self, code):
1404 def generate_argument_parsing_code(self, env, code):
1406 if self.type.optional_arg_count:
1407 code.putln('if (%s) {' % Naming.optional_args_cname)
1408 for arg in self.args:
1410 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1411 declarator = arg.declarator
1412 while not hasattr(declarator, 'name'):
1413 declarator = declarator.base
1414 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1416 for _ in range(self.type.optional_arg_count):
1420 def generate_argument_conversion_code(self, code):
1423 def generate_argument_type_tests(self, code):
1424 # Generate type tests for args whose type in a parent
1425 # class is a supertype of the declared type.
1426 for arg in self.type.args:
1427 if arg.needs_type_test:
1428 self.generate_arg_type_test(arg, code)
1430 def generate_arg_type_test(self, arg, code):
1431 # Generate type test for one argument.
1432 if arg.type.typeobj_is_available():
1433 typeptr_cname = arg.type.typeptr_cname
1434 arg_code = "((PyObject *)%s)" % arg.cname
1436 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1441 type.is_builtin_type,
1442 code.error_goto(arg.pos)))
1444 error(arg.pos, "Cannot test type of extern C class "
1445 "without type object name specification")
1447 def error_value(self):
1448 if self.return_type.is_pyobject:
1452 return self.entry.type.exception_value
1454 def caller_will_check_exceptions(self):
1455 return self.entry.type.exception_check
1457 def generate_wrapper_functions(self, code):
1458 # If the C signature of a function has changed, we need to generate
1459 # wrappers to put in the slots here.
1462 func_type = entry.type
1463 while entry.prev_entry is not None:
1465 entry = entry.prev_entry
1466 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1468 self.generate_function_header(code,
1470 with_dispatch = entry.type.is_overridable,
1471 with_opt_args = entry.type.optional_arg_count,
1472 cname = entry.func_cname)
1473 if not self.return_type.is_void:
1475 args = self.type.args
1476 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1477 if entry.type.is_overridable:
1478 arglist.append(Naming.skip_dispatch_cname)
1479 elif func_type.is_overridable:
1481 if entry.type.optional_arg_count:
1482 arglist.append(Naming.optional_args_cname)
1483 elif func_type.optional_arg_count:
1484 arglist.append('NULL')
1485 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1489 class PyArgDeclNode(Node):
1490 # Argument which must be a Python object (used
1491 # for * and ** arguments).
1494 # entry Symtab.Entry
1498 class DecoratorNode(Node):
1501 # decorator NameNode or CallNode
1502 child_attrs = ['decorator']
1505 class DefNode(FuncDefNode):
1506 # A Python function definition.
1508 # name string the Python name of the function
1509 # decorators [DecoratorNode] list of decorators
1510 # args [CArgDeclNode] formal arguments
1511 # star_arg PyArgDeclNode or None * argument
1512 # starstar_arg PyArgDeclNode or None ** argument
1513 # doc EncodedString or None
1516 # The following subnode is constructed internally
1517 # when the def statement is inside a Python class definition.
1519 # assmt AssignmentNode Function construction/assignment
1521 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1525 num_required_kw_args = 0
1526 reqd_kw_flags_cname = "0"
1532 def __init__(self, pos, **kwds):
1533 FuncDefNode.__init__(self, pos, **kwds)
1535 for arg in self.args:
1542 self.num_kwonly_args = k
1543 self.num_required_kw_args = rk
1544 self.num_required_args = r
1546 def as_cfunction(self, cfunc=None, scope=None):
1548 error(self.star_arg.pos, "cdef function cannot have star argument")
1549 if self.starstar_arg:
1550 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1553 for formal_arg in self.args:
1554 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1555 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1557 type = py_object_type,
1558 pos = formal_arg.pos))
1559 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1561 has_varargs = False,
1562 exception_value = None,
1563 exception_check = False,
1566 is_overridable = True)
1567 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1569 cfunc_type = cfunc.type
1570 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1571 error(self.pos, "wrong number of arguments")
1572 error(declarator.pos, "previous declaration here")
1573 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1574 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1575 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1576 formal_arg.type = type_arg.type
1577 formal_arg.name_declarator = name_declarator
1579 if cfunc_type.exception_value is None:
1580 exception_value = None
1582 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1583 declarator = CFuncDeclaratorNode(self.pos,
1584 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1586 has_varargs = False,
1587 exception_check = cfunc_type.exception_check,
1588 exception_value = exception_value,
1589 with_gil = cfunc_type.with_gil,
1590 nogil = cfunc_type.nogil)
1591 return CFuncDefNode(self.pos,
1593 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1594 declarator = declarator,
1597 overridable = cfunc_type.is_overridable,
1599 with_gil = cfunc_type.with_gil,
1600 nogil = cfunc_type.nogil,
1601 visibility = 'private',
1603 directive_locals = cfunc.directive_locals)
1605 def analyse_declarations(self, env):
1606 if 'locals' in env.directives:
1607 directive_locals = env.directives['locals']
1609 directive_locals = {}
1610 self.directive_locals = directive_locals
1611 for arg in self.args:
1612 if hasattr(arg, 'name'):
1614 name_declarator = None
1616 base_type = arg.base_type.analyse(env)
1617 name_declarator, type = \
1618 arg.declarator.analyse(base_type, env)
1619 arg.name = name_declarator.name
1620 if arg.name in directive_locals:
1621 type_node = directive_locals[arg.name]
1622 other_type = type_node.analyse_as_type(env)
1623 if other_type is None:
1624 error(type_node.pos, "Not a type")
1625 elif (type is not PyrexTypes.py_object_type
1626 and not type.same_as(other_type)):
1627 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1628 error(type_node.pos, "Previous declaration here")
1631 if name_declarator and name_declarator.cname:
1633 "Python function argument cannot have C name specification")
1634 arg.type = type.as_argument_type()
1636 arg.needs_conversion = 0
1637 arg.needs_type_test = 0
1639 if arg.not_none and not arg.type.is_extension_type:
1641 "Only extension type arguments can have 'not None'")
1642 self.declare_pyfunction(env)
1643 self.analyse_signature(env)
1644 self.return_type = self.entry.signature.return_type()
1646 def analyse_signature(self, env):
1647 any_type_tests_needed = 0
1648 # Use the simpler calling signature for zero- and one-argument functions.
1649 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1650 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1651 if len(self.args) == 0:
1652 self.entry.signature = TypeSlots.pyfunction_noargs
1653 elif len(self.args) == 1:
1654 if self.args[0].default is None and not self.args[0].kw_only:
1655 self.entry.signature = TypeSlots.pyfunction_onearg
1656 elif self.entry.signature is TypeSlots.pymethod_signature:
1657 if len(self.args) == 1:
1658 self.entry.signature = TypeSlots.unaryfunc
1659 elif len(self.args) == 2:
1660 if self.args[1].default is None and not self.args[1].kw_only:
1661 self.entry.signature = TypeSlots.ibinaryfunc
1662 elif self.entry.is_special:
1663 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1664 sig = self.entry.signature
1665 nfixed = sig.num_fixed_args()
1666 for i in range(nfixed):
1667 if i < len(self.args):
1670 if sig.is_self_arg(i):
1672 arg.hdr_type = arg.type = env.parent_type
1673 arg.needs_conversion = 0
1675 arg.hdr_type = sig.fixed_arg_type(i)
1676 if not arg.type.same_as(arg.hdr_type):
1677 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1678 arg.needs_type_test = 1
1679 any_type_tests_needed = 1
1681 arg.needs_conversion = 1
1682 if arg.needs_conversion:
1683 arg.hdr_cname = Naming.arg_prefix + arg.name
1685 arg.hdr_cname = Naming.var_prefix + arg.name
1687 self.bad_signature()
1689 if nfixed < len(self.args):
1690 if not sig.has_generic_args:
1691 self.bad_signature()
1692 for arg in self.args:
1693 if arg.is_generic and \
1694 (arg.type.is_extension_type or arg.type.is_builtin_type):
1695 arg.needs_type_test = 1
1696 any_type_tests_needed = 1
1697 if any_type_tests_needed:
1698 env.use_utility_code(arg_type_test_utility_code)
1700 def bad_signature(self):
1701 sig = self.entry.signature
1702 expected_str = "%d" % sig.num_fixed_args()
1703 if sig.has_generic_args:
1704 expected_str = expected_str + " or more"
1706 if name.startswith("__") and name.endswith("__"):
1707 desc = "Special method"
1711 "%s %s has wrong number of arguments "
1712 "(%d declared, %s expected)" % (
1713 desc, self.name, len(self.args), expected_str))
1715 def signature_has_nongeneric_args(self):
1716 argcount = len(self.args)
1717 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1721 def signature_has_generic_args(self):
1722 return self.entry.signature.has_generic_args
1724 def declare_pyfunction(self, env):
1725 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1727 entry = env.lookup_here(self.name)
1728 if entry and entry.type.is_cfunction and not self.is_wrapper:
1729 warning(self.pos, "Overriding cdef method with def method.", 5)
1730 entry = env.declare_pyfunction(self.name, self.pos)
1732 prefix = env.scope_prefix
1733 entry.func_cname = \
1734 Naming.pyfunc_prefix + prefix + name
1735 entry.pymethdef_cname = \
1736 Naming.pymethdef_prefix + prefix + name
1737 if Options.docstrings:
1738 entry.doc = embed_position(self.pos, self.doc)
1740 Naming.funcdoc_prefix + prefix + name
1744 def declare_arguments(self, env):
1745 for arg in self.args:
1747 error(arg.pos, "Missing argument name")
1748 if arg.needs_conversion:
1749 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1750 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1751 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1752 if arg.type.is_pyobject:
1753 arg.entry.init = "0"
1754 arg.entry.init_to_none = 0
1756 arg.entry = self.declare_argument(env, arg)
1758 arg.entry.is_self_arg = arg.is_self_arg
1760 if arg.is_self_arg or \
1761 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1762 arg.entry.is_declared_generic = 1
1763 self.declare_python_arg(env, self.star_arg)
1764 self.declare_python_arg(env, self.starstar_arg)
1766 def declare_python_arg(self, env, arg):
1768 entry = env.declare_var(arg.name,
1769 PyrexTypes.py_object_type, arg.pos)
1772 entry.init_to_none = 0
1773 entry.xdecref_cleanup = 1
1775 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1777 def analyse_expressions(self, env):
1778 self.analyse_default_values(env)
1779 if env.is_py_class_scope:
1780 self.synthesize_assignment_node(env)
1782 def synthesize_assignment_node(self, env):
1784 self.assmt = SingleAssignmentNode(self.pos,
1785 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1786 rhs = ExprNodes.UnboundMethodNode(self.pos,
1787 class_cname = env.class_obj_cname,
1788 function = ExprNodes.PyCFunctionNode(self.pos,
1789 pymethdef_cname = self.entry.pymethdef_cname)))
1790 self.assmt.analyse_declarations(env)
1791 self.assmt.analyse_expressions(env)
1793 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1795 sig = self.entry.signature
1796 if sig.has_dummy_arg:
1797 arg_code_list.append(
1798 "PyObject *%s" % Naming.self_cname)
1799 for arg in self.args:
1800 if not arg.is_generic:
1802 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1804 arg_code_list.append(
1805 arg.hdr_type.declaration_code(arg.hdr_cname))
1806 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1807 arg_code_list.append("PyObject *unused")
1808 if sig.has_generic_args:
1809 arg_code_list.append(
1810 "PyObject *%s, PyObject *%s"
1811 % (Naming.args_cname, Naming.kwds_cname))
1812 arg_code = ", ".join(arg_code_list)
1813 dc = self.return_type.declaration_code(self.entry.func_cname)
1814 header = "static %s(%s)" % (dc, arg_code)
1815 code.putln("%s; /*proto*/" % header)
1818 if self.entry.doc and Options.docstrings:
1819 docstr = self.entry.doc
1820 if not isinstance(docstr, str):
1821 docstr = docstr.utf8encode()
1823 'static char %s[] = "%s";' % (
1824 self.entry.doc_cname,
1825 split_docstring(escape_byte_string(docstr))))
1828 "static PyMethodDef %s = " %
1829 self.entry.pymethdef_cname)
1830 code.put_pymethoddef(self.entry, ";")
1831 code.putln("%s {" % header)
1833 def generate_argument_declarations(self, env, code):
1834 for arg in self.args:
1835 if arg.is_generic: # or arg.needs_conversion:
1836 if arg.needs_conversion:
1837 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1839 code.put_var_declaration(arg.entry)
1841 def generate_keyword_list(self, code):
1842 if self.signature_has_generic_args() and \
1843 self.signature_has_nongeneric_args():
1845 "static PyObject **%s[] = {" %
1846 Naming.pykwdlist_cname)
1847 for arg in self.args:
1849 pystring_cname = code.intern_identifier(arg.name)
1850 code.put('&%s,' % pystring_cname)
1853 def generate_argument_parsing_code(self, env, code):
1854 # Generate PyArg_ParseTuple call for generic
1855 # arguments, if any.
1856 if self.entry.signature.has_dummy_arg:
1857 # get rid of unused argument warning
1858 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1860 old_error_label = code.new_error_label()
1861 our_error_label = code.error_label
1862 end_label = code.new_label("argument_unpacking_done")
1864 has_kwonly_args = self.num_kwonly_args > 0
1865 has_star_or_kw_args = self.star_arg is not None \
1866 or self.starstar_arg is not None or has_kwonly_args
1868 if not self.signature_has_generic_args():
1869 if has_star_or_kw_args:
1870 error(self.pos, "This method cannot have * or keyword arguments")
1871 self.generate_argument_conversion_code(code)
1873 elif not self.signature_has_nongeneric_args():
1874 # func(*args) or func(**kw) or func(*args, **kw)
1875 self.generate_stararg_copy_code(code)
1878 positional_args = []
1881 for arg in self.args:
1882 arg_entry = arg.entry
1886 if not arg.is_self_arg:
1888 kw_only_args.append(arg)
1890 positional_args.append(arg)
1892 kw_only_args.append(arg)
1895 error(arg.pos, "Non-default argument following default argument")
1896 elif not arg.is_self_arg:
1897 positional_args.append(arg)
1899 self.generate_tuple_and_keyword_parsing_code(
1900 positional_args, kw_only_args, end_label, code)
1902 code.error_label = old_error_label
1903 if code.label_used(our_error_label):
1904 if not code.label_used(end_label):
1905 code.put_goto(end_label)
1906 code.put_label(our_error_label)
1907 if has_star_or_kw_args:
1908 self.generate_arg_decref(self.star_arg, code)
1909 if self.starstar_arg:
1910 if self.starstar_arg.entry.xdecref_cleanup:
1911 code.put_var_xdecref(self.starstar_arg.entry)
1913 code.put_var_decref(self.starstar_arg.entry)
1914 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1915 code.putln("return %s;" % self.error_value())
1916 if code.label_used(end_label):
1917 code.put_label(end_label)
1919 def generate_arg_assignment(self, arg, item, code):
1920 if arg.type.is_pyobject:
1922 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1923 code.putln("%s = %s;" % (arg.entry.cname, item))
1925 func = arg.type.from_py_function
1927 code.putln("%s = %s(%s); %s" % (
1931 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1933 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1935 def generate_arg_xdecref(self, arg, code):
1937 code.put_var_xdecref(arg.entry)
1939 def generate_arg_decref(self, arg, code):
1941 code.put_var_decref(arg.entry)
1943 def generate_stararg_copy_code(self, code):
1944 if not self.star_arg:
1945 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1946 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1948 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1949 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1952 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1954 if self.starstar_arg:
1956 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1958 kwarg_check = "%s" % Naming.kwds_cname
1960 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1961 Naming.kwds_cname, Naming.kwds_cname)
1963 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1964 kwarg_check, Naming.kwds_cname, self.name,
1965 bool(self.starstar_arg), self.error_value()))
1967 if self.starstar_arg:
1968 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1969 self.starstar_arg.entry.cname,
1972 code.putln("if (unlikely(!%s)) return %s;" % (
1973 self.starstar_arg.entry.cname, self.error_value()))
1974 self.starstar_arg.entry.xdecref_cleanup = 0
1975 code.put_gotref(self.starstar_arg.entry.cname)
1979 code.put_incref(Naming.args_cname, py_object_type)
1980 code.putln("%s = %s;" % (
1981 self.star_arg.entry.cname,
1983 self.star_arg.entry.xdecref_cleanup = 0
1985 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1986 kw_only_args, success_label, code):
1987 argtuple_error_label = code.new_label("argtuple_error")
1989 min_positional_args = self.num_required_args - self.num_required_kw_args
1990 if len(self.args) > 0 and self.args[0].is_self_arg:
1991 min_positional_args -= 1
1992 max_positional_args = len(positional_args)
1993 has_fixed_positional_count = not self.star_arg and \
1994 min_positional_args == max_positional_args
1996 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
1997 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1998 if self.num_required_kw_args:
1999 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2001 if self.starstar_arg or self.star_arg:
2002 self.generate_stararg_init_code(max_positional_args, code)
2004 # --- optimised code when we receive keyword arguments
2005 if self.num_required_kw_args:
2006 likely_hint = "likely"
2008 likely_hint = "unlikely"
2009 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2010 self.generate_keyword_unpacking_code(
2011 min_positional_args, max_positional_args,
2012 has_fixed_positional_count,
2013 positional_args, kw_only_args, argtuple_error_label, code)
2015 # --- optimised code when we do not receive any keyword arguments
2016 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2017 # Python raises arg tuple related errors first, so we must
2018 # check the length here
2019 if min_positional_args == max_positional_args and not self.star_arg:
2023 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2024 Naming.args_cname, compare, min_positional_args))
2025 code.put_goto(argtuple_error_label)
2027 if self.num_required_kw_args:
2028 # pure error case: keywords required but not passed
2029 if max_positional_args > min_positional_args and not self.star_arg:
2030 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2031 Naming.args_cname, max_positional_args))
2032 code.put_goto(argtuple_error_label)
2033 code.putln('} else {')
2034 for i, arg in enumerate(kw_only_args):
2036 pystring_cname = code.intern_identifier(arg.name)
2037 # required keyword-only argument missing
2038 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2039 self.name.utf8encode(),
2041 code.putln(code.error_goto(self.pos))
2044 elif min_positional_args == max_positional_args:
2045 # parse the exact number of positional arguments from the
2047 code.putln('} else {')
2048 for i, arg in enumerate(positional_args):
2049 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2050 self.generate_arg_assignment(arg, item, code)
2051 self.generate_arg_default_assignments(code)
2054 # parse the positional arguments from the variable length
2056 code.putln('} else {')
2057 self.generate_arg_default_assignments(code)
2058 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2060 code.putln('default:')
2061 reversed_args = list(enumerate(positional_args))[::-1]
2062 for i, arg in reversed_args:
2063 if i >= min_positional_args-1:
2064 if min_positional_args > 1:
2065 code.putln('case %2d:' % (i+1)) # pure code beautification
2067 code.put('case %2d: ' % (i+1))
2068 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2069 self.generate_arg_assignment(arg, item, code)
2070 if min_positional_args == 0:
2071 code.put('case 0: ')
2072 code.putln('break;')
2074 if min_positional_args:
2075 for i in range(min_positional_args-1, -1, -1):
2076 code.putln('case %2d:' % i)
2077 code.put_goto(argtuple_error_label)
2079 code.put('default: ')
2080 code.put_goto(argtuple_error_label)
2085 if code.label_used(argtuple_error_label):
2086 code.put_goto(success_label)
2087 code.put_label(argtuple_error_label)
2088 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2089 self.name.utf8encode(), has_fixed_positional_count,
2090 min_positional_args, max_positional_args,
2092 code.putln(code.error_goto(self.pos))
2094 def generate_arg_default_assignments(self, code):
2095 for arg in self.args:
2096 if arg.is_generic and arg.default:
2100 arg.calculate_default_value_code(code)))
2102 def generate_stararg_init_code(self, max_positional_args, code):
2103 if self.starstar_arg:
2104 self.starstar_arg.entry.xdecref_cleanup = 0
2105 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2106 self.starstar_arg.entry.cname,
2107 self.starstar_arg.entry.cname,
2108 self.error_value()))
2109 code.put_gotref(self.starstar_arg.entry.cname)
2111 self.star_arg.entry.xdecref_cleanup = 0
2112 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2114 max_positional_args))
2115 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2116 self.star_arg.entry.cname, Naming.args_cname,
2117 max_positional_args, Naming.args_cname))
2118 code.put_gotref(self.star_arg.entry.cname)
2119 if self.starstar_arg:
2121 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2122 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2123 code.putln('return %s;' % self.error_value())
2126 code.putln("if (unlikely(!%s)) return %s;" % (
2127 self.star_arg.entry.cname, self.error_value()))
2128 code.putln('} else {')
2129 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2130 code.put_incref(Naming.empty_tuple, py_object_type)
2133 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2134 has_fixed_positional_count, positional_args,
2135 kw_only_args, argtuple_error_label, code):
2136 all_args = tuple(positional_args) + tuple(kw_only_args)
2137 max_args = len(all_args)
2140 for i, arg in enumerate(all_args):
2141 if arg.default and arg.type.is_pyobject:
2142 default_value = arg.calculate_default_value_code(code)
2143 if arg.type is not PyrexTypes.py_object_type:
2144 default_value = "(PyObject*)"+default_value
2145 default_args.append((i, default_value))
2147 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2149 # it looks funny to separate the init-to-0 from setting the
2150 # default value, but C89 needs this
2151 code.putln("PyObject* values[%d] = {%s};" % (
2152 max_args, ','.join(['0']*max_args)))
2153 for i, default_value in default_args:
2154 code.putln('values[%d] = %s;' % (i, default_value))
2156 # parse the tuple and check that it's not too long
2157 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2159 code.putln('default:')
2160 for i in range(max_positional_args-1, -1, -1):
2161 code.put('case %2d: ' % (i+1))
2162 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2163 i, Naming.args_cname, i))
2164 code.putln('case 0: break;')
2165 if not self.star_arg:
2166 code.put('default: ') # more arguments than allowed
2167 code.put_goto(argtuple_error_label)
2170 # now fill up the positional/required arguments with values
2172 if self.num_required_args or max_positional_args > 0:
2173 last_required_arg = -1
2174 for i, arg in enumerate(all_args):
2176 last_required_arg = i
2177 if last_required_arg < max_positional_args:
2178 last_required_arg = max_positional_args-1
2179 num_required_args = self.num_required_args
2180 if max_positional_args > 0:
2181 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2182 for i, arg in enumerate(all_args[:last_required_arg+1]):
2183 if max_positional_args > 0 and i <= max_positional_args:
2184 if self.star_arg and i == max_positional_args:
2185 code.putln('default:')
2187 code.putln('case %2d:' % i)
2188 pystring_cname = code.intern_identifier(arg.name)
2191 # handled separately below
2193 code.putln('if (kw_args > %d) {' % num_required_args)
2194 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2195 Naming.kwds_cname, pystring_cname))
2196 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2199 num_required_args -= 1
2200 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2201 i, Naming.kwds_cname, pystring_cname))
2202 code.putln('if (likely(values[%d])) kw_args--;' % i);
2203 if i < min_positional_args:
2205 # special case: we know arg 0 is missing
2207 code.put_goto(argtuple_error_label)
2209 # print the correct number of values (args or
2210 # kwargs) that were passed into positional
2211 # arguments up to this point
2212 code.putln('else {')
2213 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2214 self.name.utf8encode(), has_fixed_positional_count,
2215 min_positional_args, max_positional_args, i))
2216 code.putln(code.error_goto(self.pos))
2219 code.putln('else {')
2220 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2221 self.name.utf8encode(), pystring_cname))
2222 code.putln(code.error_goto(self.pos))
2224 if max_positional_args > 0:
2227 if kw_only_args and not self.starstar_arg:
2228 # unpack optional keyword-only arguments
2229 # checking for interned strings in a dict is faster than iterating
2230 # but it's too likely that we must iterate if we expect **kwargs
2232 for i, arg in enumerate(all_args[max_positional_args:]):
2233 if not arg.kw_only or not arg.default:
2235 optional_args.append((i+max_positional_args, arg))
2237 # this mimics an unrolled loop so that we can "break" out of it
2238 code.putln('while (kw_args > 0) {')
2239 code.putln('PyObject* value;')
2240 for i, arg in optional_args:
2241 pystring_cname = code.intern_identifier(arg.name)
2243 'value = PyDict_GetItem(%s, %s);' % (
2244 Naming.kwds_cname, pystring_cname))
2246 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2247 code.putln('break;')
2250 code.putln('if (unlikely(kw_args > 0)) {')
2251 # non-positional/-required kw args left in dict: default args,
2252 # kw-only args, **kwargs or error
2254 # This is sort of a catch-all: except for checking required
2255 # arguments, this will always do the right thing for unpacking
2256 # keyword arguments, so that we can concentrate on optimising
2257 # common cases above.
2258 if max_positional_args == 0:
2261 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2262 Naming.args_cname, max_positional_args,
2263 Naming.args_cname, max_positional_args))
2264 pos_arg_count = "used_pos_args"
2266 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2267 code.globalstate.use_utility_code(parse_keywords_utility_code)
2269 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2271 Naming.pykwdlist_cname,
2272 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2274 self.name.utf8encode()))
2275 code.putln(code.error_goto(self.pos))
2278 # convert arg values to their final type and assign them
2279 for i, arg in enumerate(all_args):
2280 if arg.default and not arg.type.is_pyobject:
2281 code.putln("if (values[%d]) {" % i)
2282 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2283 if arg.default and not arg.type.is_pyobject:
2284 code.putln('} else {')
2288 arg.calculate_default_value_code(code)))
2291 def generate_argument_conversion_code(self, code):
2292 # Generate code to convert arguments from
2293 # signature type to declared type, if needed.
2294 for arg in self.args:
2295 if arg.needs_conversion:
2296 self.generate_arg_conversion(arg, code)
2298 def generate_arg_conversion(self, arg, code):
2299 # Generate conversion code for one argument.
2300 old_type = arg.hdr_type
2302 if old_type.is_pyobject:
2304 code.putln("if (%s) {" % arg.hdr_cname)
2306 code.putln("assert(%s); {" % arg.hdr_cname)
2307 self.generate_arg_conversion_from_pyobject(arg, code)
2309 elif new_type.is_pyobject:
2310 self.generate_arg_conversion_to_pyobject(arg, code)
2312 if new_type.assignable_from(old_type):
2314 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2317 "Cannot convert 1 argument from '%s' to '%s'" %
2318 (old_type, new_type))
2320 def generate_arg_conversion_from_pyobject(self, arg, code):
2322 func = new_type.from_py_function
2323 # copied from CoerceFromPyTypeNode
2325 code.putln("%s = %s(%s); %s" % (
2329 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2332 "Cannot convert Python object argument to type '%s'"
2335 def generate_arg_conversion_to_pyobject(self, arg, code):
2336 old_type = arg.hdr_type
2337 func = old_type.to_py_function
2339 code.putln("%s = %s(%s); %s" % (
2343 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2344 code.put_var_gotref(arg.entry)
2347 "Cannot convert argument of type '%s' to Python object"
2350 def generate_argument_type_tests(self, code):
2351 # Generate type tests for args whose signature
2352 # type is PyObject * and whose declared type is
2353 # a subtype thereof.
2354 for arg in self.args:
2355 if arg.needs_type_test:
2356 self.generate_arg_type_test(arg, code)
2358 def generate_arg_type_test(self, arg, code):
2359 # Generate type test for one argument.
2360 if arg.type.typeobj_is_available():
2361 typeptr_cname = arg.type.typeptr_cname
2362 arg_code = "((PyObject *)%s)" % arg.entry.cname
2364 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2369 arg.type.is_builtin_type,
2370 code.error_goto(arg.pos)))
2372 error(arg.pos, "Cannot test type of extern C class "
2373 "without type object name specification")
2375 def error_value(self):
2376 return self.entry.signature.error_value
2378 def caller_will_check_exceptions(self):
2381 class OverrideCheckNode(StatNode):
2382 # A Node for dispatching to the def method if it
2391 child_attrs = ['body']
2395 def analyse_expressions(self, env):
2396 self.args = env.arg_entries
2397 if self.py_func.is_module_scope:
2402 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2403 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2404 call_node = ExprNodes.SimpleCallNode(self.pos,
2405 function=self.func_node,
2406 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2407 self.body = ReturnStatNode(self.pos, value=call_node)
2408 self.body.analyse_expressions(env)
2410 def generate_execution_code(self, code):
2411 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2412 # Check to see if we are an extension type
2413 if self.py_func.is_module_scope:
2414 self_arg = "((PyObject *)%s)" % Naming.module_cname
2416 self_arg = "((PyObject *)%s)" % self.args[0].cname
2417 code.putln("/* Check if called by wrapper */")
2418 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2419 code.putln("/* Check if overriden in Python */")
2420 if self.py_func.is_module_scope:
2421 code.putln("else {")
2423 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2424 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2425 # need to get attribute manually--scope would return cdef method
2426 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2427 self.func_node.result(), self_arg, interned_attr_cname, err))
2428 code.put_gotref(self.func_node.py_result())
2429 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2430 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2431 self.func_node.result(), self.py_func.entry.func_cname)
2432 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2433 self.body.generate_execution_code(code)
2435 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2438 class ClassDefNode(StatNode, BlockNode):
2441 class PyClassDefNode(ClassDefNode):
2442 # A Python class definition.
2444 # name EncodedString Name of the class
2445 # doc string or None
2446 # body StatNode Attribute definition code
2447 # entry Symtab.Entry
2448 # scope PyClassScope
2450 # The following subnodes are constructed internally:
2452 # dict DictNode Class dictionary
2453 # classobj ClassNode Class object
2454 # target NameNode Variable to assign class object to
2456 child_attrs = ["body", "dict", "classobj", "target"]
2458 def __init__(self, pos, name, bases, doc, body):
2459 StatNode.__init__(self, pos)
2464 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2465 if self.doc and Options.docstrings:
2466 doc = embed_position(self.pos, self.doc)
2467 doc_node = ExprNodes.StringNode(pos, value = doc)
2470 self.classobj = ExprNodes.ClassNode(pos, name = name,
2471 bases = bases, dict = self.dict, doc = doc_node)
2472 self.target = ExprNodes.NameNode(pos, name = name)
2474 def as_cclass(self):
2476 Return this node as if it were declared as an extension class
2478 bases = self.classobj.bases.args
2480 base_class_name = None
2481 base_class_module = None
2482 elif len(bases) == 1:
2485 from ExprNodes import AttributeNode, NameNode
2486 while isinstance(base, AttributeNode):
2487 path.insert(0, base.attribute)
2489 if isinstance(base, NameNode):
2490 path.insert(0, base.name)
2491 base_class_name = path[-1]
2493 base_class_module = u'.'.join(path[:-1])
2495 base_class_module = None
2497 error(self.classobj.bases.args.pos, "Invalid base class")
2499 error(self.classobj.bases.args.pos, "C class may only have one base class")
2502 return CClassDefNode(self.pos,
2503 visibility = 'private',
2505 class_name = self.name,
2506 base_class_module = base_class_module,
2507 base_class_name = base_class_name,
2512 def create_scope(self, env):
2514 while env.is_py_class_scope or env.is_c_class_scope:
2515 env = env.outer_scope
2516 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2519 def analyse_declarations(self, env):
2520 self.target.analyse_target_declaration(env)
2521 cenv = self.create_scope(env)
2522 cenv.class_obj_cname = self.target.entry.cname
2523 self.body.analyse_declarations(cenv)
2525 def analyse_expressions(self, env):
2526 self.dict.analyse_expressions(env)
2527 self.classobj.analyse_expressions(env)
2528 genv = env.global_scope()
2530 cenv.class_dict_cname = self.dict.result()
2531 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2532 self.body.analyse_expressions(cenv)
2533 self.target.analyse_target_expression(env, self.classobj)
2534 self.dict.release_temp(env)
2535 #self.classobj.release_temp(env)
2536 #self.target.release_target_temp(env)
2538 def generate_function_definitions(self, env, code):
2539 self.body.generate_function_definitions(self.scope, code)
2541 def generate_execution_code(self, code):
2542 self.dict.generate_evaluation_code(code)
2543 self.classobj.generate_evaluation_code(code)
2544 self.body.generate_execution_code(code)
2545 self.target.generate_assignment_code(self.classobj, code)
2546 self.dict.generate_disposal_code(code)
2547 self.dict.free_temps(code)
2550 class CClassDefNode(ClassDefNode):
2551 # An extension type definition.
2553 # visibility 'private' or 'public' or 'extern'
2554 # typedef_flag boolean
2556 # module_name string or None For import of extern type objects
2557 # class_name string Unqualified name of class
2558 # as_name string or None Name to declare as in this scope
2559 # base_class_module string or None Module containing the base class
2560 # base_class_name string or None Name of the base class
2561 # objstruct_name string or None Specified C name of object struct
2562 # typeobj_name string or None Specified C name of type object
2563 # in_pxd boolean Is in a .pxd file
2564 # doc string or None
2565 # body StatNode or None
2566 # entry Symtab.Entry
2567 # base_type PyExtensionType or None
2568 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2569 # buffer_defaults_pos
2571 child_attrs = ["body"]
2572 buffer_defaults_node = None
2573 buffer_defaults_pos = None
2574 typedef_flag = False
2576 objstruct_name = None
2579 def analyse_declarations(self, env):
2580 #print "CClassDefNode.analyse_declarations:", self.class_name
2581 #print "...visibility =", self.visibility
2582 #print "...module_name =", self.module_name
2585 if self.buffer_defaults_node:
2586 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2587 env, [], self.buffer_defaults_node,
2588 need_complete=False)
2590 buffer_defaults = None
2592 if env.in_cinclude and not self.objstruct_name:
2593 error(self.pos, "Object struct name specification required for "
2594 "C class defined in 'extern from' block")
2595 self.base_type = None
2596 # Now that module imports are cached, we need to
2597 # import the modules for extern classes.
2598 if self.module_name:
2600 for module in env.cimported_modules:
2601 if module.name == self.module_name:
2602 self.module = module
2603 if self.module is None:
2604 self.module = ModuleScope(self.module_name, None, env.context)
2605 self.module.has_extern_class = 1
2606 env.add_imported_module(self.module)
2608 if self.base_class_name:
2609 if self.base_class_module:
2610 base_class_scope = env.find_module(self.base_class_module, self.pos)
2612 base_class_scope = env
2613 if self.base_class_name == 'object':
2614 # extension classes are special and don't need to inherit from object
2615 if base_class_scope is None or base_class_scope.lookup('object') is None:
2616 self.base_class_name = None
2617 self.base_class_module = None
2618 base_class_scope = None
2619 if base_class_scope:
2620 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2621 if base_class_entry:
2622 if not base_class_entry.is_type:
2623 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2624 elif not base_class_entry.type.is_extension_type:
2625 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2626 elif not base_class_entry.type.is_complete():
2627 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2629 self.base_type = base_class_entry.type
2630 has_body = self.body is not None
2631 if self.module_name and self.visibility != 'extern':
2632 module_path = self.module_name.split(".")
2633 home_scope = env.find_imported_module(module_path, self.pos)
2638 self.entry = home_scope.declare_c_class(
2639 name = self.class_name,
2641 defining = has_body and self.in_pxd,
2642 implementing = has_body and not self.in_pxd,
2643 module_name = self.module_name,
2644 base_type = self.base_type,
2645 objstruct_cname = self.objstruct_name,
2646 typeobj_cname = self.typeobj_name,
2647 visibility = self.visibility,
2648 typedef_flag = self.typedef_flag,
2650 buffer_defaults = buffer_defaults)
2651 if home_scope is not env and self.visibility == 'extern':
2652 env.add_imported_entry(self.class_name, self.entry, pos)
2653 scope = self.entry.type.scope
2655 if self.doc and Options.docstrings:
2656 scope.doc = embed_position(self.pos, self.doc)
2659 self.body.analyse_declarations(scope)
2663 scope.implemented = 1
2664 env.allocate_vtable_names(self.entry)
2666 def analyse_expressions(self, env):
2668 scope = self.entry.type.scope
2669 self.body.analyse_expressions(scope)
2671 def generate_function_definitions(self, env, code):
2673 self.body.generate_function_definitions(
2674 self.entry.type.scope, code)
2676 def generate_execution_code(self, code):
2677 # This is needed to generate evaluation code for
2678 # default values of method arguments.
2680 self.body.generate_execution_code(code)
2682 def annotate(self, code):
2684 self.body.annotate(code)
2687 class PropertyNode(StatNode):
2688 # Definition of a property in an extension type.
2691 # doc EncodedString or None Doc string
2694 child_attrs = ["body"]
2696 def analyse_declarations(self, env):
2697 entry = env.declare_property(self.name, self.doc, self.pos)
2699 self.body.analyse_declarations(entry.scope)
2701 def analyse_expressions(self, env):
2702 self.body.analyse_expressions(env)
2704 def generate_function_definitions(self, env, code):
2705 self.body.generate_function_definitions(env, code)
2707 def generate_execution_code(self, code):
2710 def annotate(self, code):
2711 self.body.annotate(code)
2714 class GlobalNode(StatNode):
2715 # Global variable declaration.
2721 def analyse_declarations(self, env):
2722 for name in self.names:
2723 env.declare_global(name, self.pos)
2725 def analyse_expressions(self, env):
2728 def generate_execution_code(self, code):
2732 class ExprStatNode(StatNode):
2733 # Expression used as a statement.
2737 child_attrs = ["expr"]
2739 def analyse_declarations(self, env):
2741 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2742 func = self.expr.function.as_cython_attribute()
2743 if func == u'declare':
2744 args, kwds = self.expr.explicit_args_kwds()
2746 error(self.expr.pos, "Variable names must be specified.")
2747 for var, type_node in kwds.key_value_pairs:
2748 type = type_node.analyse_as_type(env)
2750 error(type_node.pos, "Unknown type")
2752 env.declare_var(var.value, type, var.pos, is_cdef = True)
2753 self.__class__ = PassStatNode
2755 def analyse_expressions(self, env):
2756 self.expr.analyse_expressions(env)
2757 self.expr.release_temp(env)
2759 def generate_execution_code(self, code):
2760 self.expr.generate_evaluation_code(code)
2761 if not self.expr.is_temp and self.expr.result():
2762 code.putln("%s;" % self.expr.result())
2763 self.expr.generate_disposal_code(code)
2764 self.expr.free_temps(code)
2766 def annotate(self, code):
2767 self.expr.annotate(code)
2770 class AssignmentNode(StatNode):
2771 # Abstract base class for assignment nodes.
2773 # The analyse_expressions and generate_execution_code
2774 # phases of assignments are split into two sub-phases
2775 # each, to enable all the right hand sides of a
2776 # parallel assignment to be evaluated before assigning
2777 # to any of the left hand sides.
2779 def analyse_expressions(self, env):
2780 self.analyse_types(env)
2781 self.allocate_rhs_temps(env)
2782 self.allocate_lhs_temps(env)
2784 # def analyse_expressions(self, env):
2785 # self.analyse_expressions_1(env)
2786 # self.analyse_expressions_2(env)
2788 def generate_execution_code(self, code):
2789 self.generate_rhs_evaluation_code(code)
2790 self.generate_assignment_code(code)
2793 class SingleAssignmentNode(AssignmentNode):
2794 # The simplest case:
2798 # lhs ExprNode Left hand side
2799 # rhs ExprNode Right hand side
2800 # first bool Is this guaranteed the first assignment to lhs?
2802 child_attrs = ["lhs", "rhs"]
2804 declaration_only = False
2806 def analyse_declarations(self, env):
2809 # handle declarations of the form x = cython.foo()
2810 if isinstance(self.rhs, ExprNodes.CallNode):
2811 func_name = self.rhs.function.as_cython_attribute()
2813 args, kwds = self.rhs.explicit_args_kwds()
2815 if func_name in ['declare', 'typedef']:
2816 if len(args) > 2 or kwds is not None:
2817 error(rhs.pos, "Can only declare one type at a time.")
2819 type = args[0].analyse_as_type(env)
2821 error(args[0].pos, "Unknown type")
2824 if func_name == 'declare':
2825 if isinstance(lhs, ExprNodes.NameNode):
2826 vars = [(lhs.name, lhs.pos)]
2827 elif isinstance(lhs, ExprNodes.TupleNode):
2828 vars = [(var.name, var.pos) for var in lhs.args]
2830 error(lhs.pos, "Invalid declaration")
2832 for var, pos in vars:
2833 env.declare_var(var, type, pos, is_cdef = True)
2838 self.declaration_only = True
2840 self.declaration_only = True
2841 if not isinstance(lhs, ExprNodes.NameNode):
2842 error(lhs.pos, "Invalid declaration.")
2843 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2845 elif func_name in ['struct', 'union']:
2846 self.declaration_only = True
2847 if len(args) > 0 or kwds is None:
2848 error(rhs.pos, "Struct or union members must be given by name.")
2851 for member, type_node in kwds.key_value_pairs:
2852 type = type_node.analyse_as_type(env)
2854 error(type_node.pos, "Unknown type")
2856 members.append((member.value, type, member.pos))
2857 if len(members) < len(kwds.key_value_pairs):
2859 if not isinstance(self.lhs, ExprNodes.NameNode):
2860 error(self.lhs.pos, "Invalid declaration.")
2861 name = self.lhs.name
2862 scope = StructOrUnionScope(name)
2863 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2864 for member, type, pos in members:
2865 scope.declare_var(member, type, pos)
2867 if self.declaration_only:
2870 self.lhs.analyse_target_declaration(env)
2872 def analyse_types(self, env, use_temp = 0):
2873 self.rhs.analyse_types(env)
2874 self.lhs.analyse_target_types(env)
2875 self.lhs.gil_assignment_check(env)
2876 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2878 self.rhs = self.rhs.coerce_to_temp(env)
2880 def allocate_rhs_temps(self, env):
2881 self.rhs.allocate_temps(env)
2883 def allocate_lhs_temps(self, env):
2884 self.lhs.allocate_target_temps(env, self.rhs)
2885 #self.lhs.release_target_temp(env)
2886 #self.rhs.release_temp(env)
2888 def generate_rhs_evaluation_code(self, code):
2889 self.rhs.generate_evaluation_code(code)
2891 def generate_assignment_code(self, code):
2892 self.lhs.generate_assignment_code(self.rhs, code)
2894 def annotate(self, code):
2895 self.lhs.annotate(code)
2896 self.rhs.annotate(code)
2899 class CascadedAssignmentNode(AssignmentNode):
2900 # An assignment with multiple left hand sides:
2904 # lhs_list [ExprNode] Left hand sides
2905 # rhs ExprNode Right hand sides
2909 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2911 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2912 coerced_rhs_list = None
2914 def analyse_declarations(self, env):
2915 for lhs in self.lhs_list:
2916 lhs.analyse_target_declaration(env)
2918 def analyse_types(self, env, use_temp = 0):
2919 self.rhs.analyse_types(env)
2921 self.rhs = self.rhs.coerce_to_temp(env)
2923 self.rhs = self.rhs.coerce_to_simple(env)
2924 from ExprNodes import CloneNode
2925 self.coerced_rhs_list = []
2926 for lhs in self.lhs_list:
2927 lhs.analyse_target_types(env)
2928 lhs.gil_assignment_check(env)
2929 rhs = CloneNode(self.rhs)
2930 rhs = rhs.coerce_to(lhs.type, env)
2931 self.coerced_rhs_list.append(rhs)
2933 def allocate_rhs_temps(self, env):
2934 self.rhs.allocate_temps(env)
2936 def allocate_lhs_temps(self, env):
2937 for lhs, rhs in zip(self.lhs_list, self.coerced_rhs_list):
2938 rhs.allocate_temps(env)
2939 lhs.allocate_target_temps(env, rhs)
2940 #lhs.release_target_temp(env)
2941 #rhs.release_temp(env)
2942 self.rhs.release_temp(env)
2944 def generate_rhs_evaluation_code(self, code):
2945 self.rhs.generate_evaluation_code(code)
2947 def generate_assignment_code(self, code):
2948 for i in range(len(self.lhs_list)):
2949 lhs = self.lhs_list[i]
2950 rhs = self.coerced_rhs_list[i]
2951 rhs.generate_evaluation_code(code)
2952 lhs.generate_assignment_code(rhs, code)
2953 # Assignment has disposed of the cloned RHS
2954 self.rhs.generate_disposal_code(code)
2955 self.rhs.free_temps(code)
2957 def annotate(self, code):
2958 for i in range(len(self.lhs_list)):
2959 lhs = self.lhs_list[i].annotate(code)
2960 rhs = self.coerced_rhs_list[i].annotate(code)
2961 self.rhs.annotate(code)
2964 class ParallelAssignmentNode(AssignmentNode):
2965 # A combined packing/unpacking assignment:
2969 # This has been rearranged by the parser into
2971 # a = d ; b = e ; c = f
2973 # but we must evaluate all the right hand sides
2974 # before assigning to any of the left hand sides.
2976 # stats [AssignmentNode] The constituent assignments
2978 child_attrs = ["stats"]
2980 def analyse_declarations(self, env):
2981 for stat in self.stats:
2982 stat.analyse_declarations(env)
2984 def analyse_expressions(self, env):
2985 for stat in self.stats:
2986 stat.analyse_types(env, use_temp = 1)
2987 stat.allocate_rhs_temps(env)
2988 for stat in self.stats:
2989 stat.allocate_lhs_temps(env)
2991 # def analyse_expressions(self, env):
2992 # for stat in self.stats:
2993 # stat.analyse_expressions_1(env, use_temp = 1)
2994 # for stat in self.stats:
2995 # stat.analyse_expressions_2(env)
2997 def generate_execution_code(self, code):
2998 for stat in self.stats:
2999 stat.generate_rhs_evaluation_code(code)
3000 for stat in self.stats:
3001 stat.generate_assignment_code(code)
3003 def annotate(self, code):
3004 for stat in self.stats:
3008 class InPlaceAssignmentNode(AssignmentNode):
3009 # An in place arithmatic operand:
3015 # lhs ExprNode Left hand side
3016 # rhs ExprNode Right hand side
3017 # op char one of "+-*/%^&|"
3018 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3020 # This code is a bit tricky because in order to obey Python
3021 # semantics the sub-expressions (e.g. indices) of the lhs must
3022 # not be evaluated twice. So we must re-use the values calculated
3023 # in evaluation phase for the assignment phase as well.
3024 # Fortunately, the type of the lhs node is fairly constrained
3025 # (it must be a NameNode, AttributeNode, or IndexNode).
3027 child_attrs = ["lhs", "rhs"]
3030 def analyse_declarations(self, env):
3031 self.lhs.analyse_target_declaration(env)
3033 def analyse_types(self, env):
3034 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3035 self.rhs.analyse_types(env)
3036 self.lhs.analyse_target_types(env)
3037 if Options.incref_local_binop and self.dup.type.is_pyobject:
3038 self.dup = self.dup.coerce_to_temp(env)
3040 def allocate_rhs_temps(self, env):
3042 if self.lhs.type.is_pyobject:
3043 self.rhs = self.rhs.coerce_to_pyobject(env)
3044 elif self.rhs.type.is_pyobject:
3045 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3046 if self.lhs.type.is_pyobject:
3047 self.result_value = ExprNodes.PyTempNode(self.pos, env).coerce_to(self.lhs.type, env)
3048 self.result_value.allocate_temps(env)
3050 # self.rhs = self.rhs.coerce_to_temp(env)
3051 self.rhs.allocate_temps(env)
3052 self.dup.allocate_subexpr_temps(env)
3053 self.dup.allocate_temp(env)
3055 def allocate_lhs_temps(self, env):
3056 self.lhs.allocate_target_temps(env, self.rhs)
3057 # self.lhs.release_target_temp(env)
3058 self.dup.release_temp(env)
3059 if self.dup.is_temp:
3060 self.dup.release_subexpr_temps(env)
3061 # self.rhs.release_temp(env)
3062 if self.lhs.type.is_pyobject:
3063 self.result_value.release_temp(env)
3065 def generate_execution_code(self, code):
3067 self.rhs.generate_evaluation_code(code)
3068 self.dup.generate_subexpr_evaluation_code(code)
3069 if isinstance(self.dup, ExprNodes.NewTempExprNode):
3070 # This is because we're manually messing with subexpr nodes
3071 if self.dup.is_temp:
3072 self.dup.allocate_temp_result(code)
3073 # self.dup.generate_result_code is run only if it is not buffer access
3074 if self.operator == "**":
3078 if self.lhs.type.is_pyobject:
3079 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3080 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3081 self.dup.generate_result_code(code)
3083 "%s = %s(%s, %s%s); %s" % (
3084 self.result_value.result(),
3085 self.py_operation_function(),
3086 self.dup.py_result(),
3087 self.rhs.py_result(),
3089 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3090 code.put_gotref(self.result_value.py_result())
3091 self.result_value.generate_evaluation_code(code) # May be a type check...
3092 self.rhs.generate_disposal_code(code)
3093 self.rhs.free_temps(code)
3094 self.dup.generate_disposal_code(code)
3095 self.dup.free_temps(code)
3096 self.lhs.generate_assignment_code(self.result_value, code)
3098 c_op = self.operator
3102 if self.lhs.type.is_int and self.rhs.type.is_int:
3103 error(self.pos, "** with two C int types is ambiguous")
3105 error(self.pos, "No C inplace power operator")
3106 # have to do assignment directly to avoid side-effects
3107 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3108 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3110 self.dup.generate_result_code(code)
3111 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3112 self.rhs.generate_disposal_code(code)
3113 self.rhs.free_temps(code)
3114 if self.dup.is_temp:
3115 self.dup.generate_subexpr_disposal_code(code)
3116 self.dup.free_subexpr_temps(code)
3118 def create_dup_node(self, env):
3121 self.dup.analyse_types(env)
3122 if isinstance(self.lhs, ExprNodes.NameNode):
3123 target_lhs = ExprNodes.NameNode(self.dup.pos,
3124 name = self.dup.name,
3125 is_temp = self.dup.is_temp,
3126 entry = self.dup.entry)
3127 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3128 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3129 obj = ExprNodes.CloneNode(self.lhs.obj),
3130 attribute = self.dup.attribute,
3131 is_temp = self.dup.is_temp)
3132 elif isinstance(self.lhs, ExprNodes.IndexNode):
3134 index = ExprNodes.CloneNode(self.lhs.index)
3137 if self.lhs.indices:
3138 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3141 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3142 base = ExprNodes.CloneNode(self.dup.base),
3145 is_temp = self.dup.is_temp)
3148 self.lhs = target_lhs
3151 def py_operation_function(self):
3152 return self.py_functions[self.operator]
3155 "|": "PyNumber_InPlaceOr",
3156 "^": "PyNumber_InPlaceXor",
3157 "&": "PyNumber_InPlaceAnd",
3158 "+": "PyNumber_InPlaceAdd",
3159 "-": "PyNumber_InPlaceSubtract",
3160 "*": "PyNumber_InPlaceMultiply",
3161 "/": "PyNumber_InPlaceDivide",
3162 "%": "PyNumber_InPlaceRemainder",
3163 "<<": "PyNumber_InPlaceLshift",
3164 ">>": "PyNumber_InPlaceRshift",
3165 "**": "PyNumber_InPlacePower",
3166 "//": "PyNumber_InPlaceFloorDivide",
3169 def annotate(self, code):
3170 self.lhs.annotate(code)
3171 self.rhs.annotate(code)
3172 self.dup.annotate(code)
3175 class PrintStatNode(StatNode):
3178 # arg_tuple TupleNode
3179 # append_newline boolean
3181 child_attrs = ["arg_tuple"]
3183 def analyse_expressions(self, env):
3184 self.arg_tuple.analyse_expressions(env)
3185 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3186 self.arg_tuple.release_temp(env)
3187 env.use_utility_code(printing_utility_code)
3188 if len(self.arg_tuple.args) == 1 and self.append_newline:
3189 env.use_utility_code(printing_one_utility_code)
3191 gil_check = StatNode._gil_check
3192 gil_message = "Python print statement"
3194 def generate_execution_code(self, code):
3195 if len(self.arg_tuple.args) == 1 and self.append_newline:
3196 arg = self.arg_tuple.args[0]
3197 arg.generate_evaluation_code(code)
3200 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3202 code.error_goto(self.pos)))
3203 arg.generate_disposal_code(code)
3204 arg.free_temps(code)
3206 self.arg_tuple.generate_evaluation_code(code)
3208 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3209 self.arg_tuple.py_result(),
3210 self.append_newline,
3211 code.error_goto(self.pos)))
3212 self.arg_tuple.generate_disposal_code(code)
3213 self.arg_tuple.free_temps(code)
3215 def annotate(self, code):
3216 self.arg_tuple.annotate(code)
3219 class ExecStatNode(StatNode):
3224 child_attrs = ["args"]
3226 def analyse_expressions(self, env):
3227 for i, arg in enumerate(self.args):
3228 arg.analyse_expressions(env)
3229 arg = arg.coerce_to_pyobject(env)
3230 arg.release_temp(env)
3232 self.temp_result = env.allocate_temp_pyobject()
3233 env.release_temp(self.temp_result)
3234 env.use_utility_code(Builtin.pyexec_utility_code)
3236 gil_check = StatNode._gil_check
3237 gil_message = "Python exec statement"
3239 def generate_execution_code(self, code):
3241 for arg in self.args:
3242 arg.generate_evaluation_code(code)
3243 args.append( arg.py_result() )
3244 args = tuple(args + ['0', '0'][:3-len(args)])
3245 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3246 (self.temp_result,) + args))
3247 for arg in self.args:
3248 arg.generate_disposal_code(code)
3249 arg.free_temps(code)
3251 code.error_goto_if_null(self.temp_result, self.pos))
3252 code.put_gotref(self.temp_result)
3253 code.put_decref_clear(self.temp_result, py_object_type)
3255 def annotate(self, code):
3256 for arg in self.args:
3260 class DelStatNode(StatNode):
3265 child_attrs = ["args"]
3267 def analyse_declarations(self, env):
3268 for arg in self.args:
3269 arg.analyse_target_declaration(env)
3271 def analyse_expressions(self, env):
3272 for arg in self.args:
3273 arg.analyse_target_expression(env, None)
3274 if not arg.type.is_pyobject:
3275 error(arg.pos, "Deletion of non-Python object")
3276 #arg.release_target_temp(env)
3278 def gil_check(self, env):
3279 for arg in self.args:
3280 if arg.type.is_pyobject:
3281 self._gil_check(env)
3283 gil_message = "Deleting Python object"
3285 def generate_execution_code(self, code):
3286 for arg in self.args:
3287 if arg.type.is_pyobject:
3288 arg.generate_deletion_code(code)
3289 # else error reported earlier
3291 def annotate(self, code):
3292 for arg in self.args:
3296 class PassStatNode(StatNode):
3301 def analyse_expressions(self, env):
3304 def generate_execution_code(self, code):
3308 class BreakStatNode(StatNode):
3312 def analyse_expressions(self, env):
3315 def generate_execution_code(self, code):
3316 if not code.break_label:
3317 error(self.pos, "break statement not inside loop")
3319 code.put_goto(code.break_label)
3322 class ContinueStatNode(StatNode):
3326 def analyse_expressions(self, env):
3329 def generate_execution_code(self, code):
3330 if code.funcstate.in_try_finally:
3331 error(self.pos, "continue statement inside try of try...finally")
3332 elif not code.continue_label:
3333 error(self.pos, "continue statement not inside loop")
3335 code.put_goto(code.continue_label)
3338 class ReturnStatNode(StatNode):
3341 # value ExprNode or None
3342 # return_type PyrexType
3343 # temps_in_use [Entry] Temps in use at time of return
3345 child_attrs = ["value"]
3347 def analyse_expressions(self, env):
3348 return_type = env.return_type
3349 self.return_type = return_type
3350 self.temps_in_use = env.temps_in_use()
3352 error(self.pos, "Return not inside a function body")
3355 self.value.analyse_types(env)
3356 if return_type.is_void or return_type.is_returncode:
3357 error(self.value.pos,
3358 "Return with value in void function")
3360 self.value = self.value.coerce_to(env.return_type, env)
3361 self.value.allocate_temps(env)
3362 self.value.release_temp(env)
3364 if (not return_type.is_void
3365 and not return_type.is_pyobject
3366 and not return_type.is_returncode):
3367 error(self.pos, "Return value required")
3369 def gil_check(self, env):
3370 if self.return_type.is_pyobject:
3371 self._gil_check(env)
3373 gil_message = "Returning Python object"
3375 def generate_execution_code(self, code):
3376 code.mark_pos(self.pos)
3377 if not self.return_type:
3378 # error reported earlier
3380 if self.return_type.is_pyobject:
3381 code.put_xdecref(Naming.retval_cname,
3384 self.value.generate_evaluation_code(code)
3385 self.value.make_owned_reference(code)
3388 Naming.retval_cname,
3389 self.value.result_as(self.return_type)))
3390 self.value.generate_post_assignment_code(code)
3391 self.value.free_temps(code)
3393 if self.return_type.is_pyobject:
3394 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3395 elif self.return_type.is_returncode:
3398 Naming.retval_cname,
3399 self.return_type.default_value))
3400 # free temps the old way
3401 for entry in self.temps_in_use:
3402 code.put_var_decref_clear(entry)
3403 # free temps the new way
3404 for cname, type in code.funcstate.temps_holding_reference():
3405 code.put_decref_clear(cname, type)
3408 # code.return_label)
3409 code.put_goto(code.return_label)
3411 def annotate(self, code):
3413 self.value.annotate(code)
3416 class RaiseStatNode(StatNode):
3419 # exc_type ExprNode or None
3420 # exc_value ExprNode or None
3421 # exc_tb ExprNode or None
3423 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3425 def analyse_expressions(self, env):
3427 self.exc_type.analyse_types(env)
3428 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3429 self.exc_type.allocate_temps(env)
3431 self.exc_value.analyse_types(env)
3432 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3433 self.exc_value.allocate_temps(env)
3435 self.exc_tb.analyse_types(env)
3436 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3437 self.exc_tb.allocate_temps(env)
3439 self.exc_type.release_temp(env)
3441 self.exc_value.release_temp(env)
3443 self.exc_tb.release_temp(env)
3444 env.use_utility_code(raise_utility_code)
3445 env.use_utility_code(restore_exception_utility_code)
3447 gil_check = StatNode._gil_check
3448 gil_message = "Raising exception"
3450 def generate_execution_code(self, code):
3452 self.exc_type.generate_evaluation_code(code)
3453 type_code = self.exc_type.py_result()
3457 self.exc_value.generate_evaluation_code(code)
3458 value_code = self.exc_value.py_result()
3462 self.exc_tb.generate_evaluation_code(code)
3463 tb_code = self.exc_tb.py_result()
3466 if self.exc_type or self.exc_value or self.exc_tb:
3468 "__Pyx_Raise(%s, %s, %s);" % (
3475 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3477 obj.generate_disposal_code(code)
3478 obj.free_temps(code)
3480 code.error_goto(self.pos))
3482 def annotate(self, code):
3484 self.exc_type.annotate(code)
3486 self.exc_value.annotate(code)
3488 self.exc_tb.annotate(code)
3491 class ReraiseStatNode(StatNode):
3495 def analyse_expressions(self, env):
3496 env.use_utility_code(raise_utility_code)
3497 env.use_utility_code(restore_exception_utility_code)
3499 gil_check = StatNode._gil_check
3500 gil_message = "Raising exception"
3502 def generate_execution_code(self, code):
3503 vars = code.funcstate.exc_vars
3505 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3506 code.putln(code.error_goto(self.pos))
3508 error(self.pos, "Reraise not inside except clause")
3511 class AssertStatNode(StatNode):
3515 # value ExprNode or None
3517 child_attrs = ["cond", "value"]
3519 def analyse_expressions(self, env):
3520 self.cond = self.cond.analyse_boolean_expression(env)
3522 self.value.analyse_types(env)
3523 self.value = self.value.coerce_to_pyobject(env)
3524 self.value.allocate_temps(env)
3525 self.cond.release_temp(env)
3527 self.value.release_temp(env)
3528 #env.recycle_pending_temps() # TEMPORARY
3530 gil_check = StatNode._gil_check
3531 gil_message = "Raising exception"
3533 def generate_execution_code(self, code):
3534 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3535 self.cond.generate_evaluation_code(code)
3537 "if (unlikely(!%s)) {" %
3540 self.value.generate_evaluation_code(code)
3542 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3543 self.value.py_result())
3544 self.value.generate_disposal_code(code)
3545 self.value.free_temps(code)
3548 "PyErr_SetNone(PyExc_AssertionError);")
3550 code.error_goto(self.pos))
3553 self.cond.generate_disposal_code(code)
3554 self.cond.free_temps(code)
3555 code.putln("#endif")
3557 def annotate(self, code):
3558 self.cond.annotate(code)
3560 self.value.annotate(code)
3563 class IfStatNode(StatNode):
3566 # if_clauses [IfClauseNode]
3567 # else_clause StatNode or None
3569 child_attrs = ["if_clauses", "else_clause"]
3571 def analyse_control_flow(self, env):
3572 env.start_branching(self.pos)
3573 for if_clause in self.if_clauses:
3574 if_clause.analyse_control_flow(env)
3575 env.next_branch(if_clause.end_pos())
3576 if self.else_clause:
3577 self.else_clause.analyse_control_flow(env)
3578 env.finish_branching(self.end_pos())
3580 def analyse_declarations(self, env):
3581 for if_clause in self.if_clauses:
3582 if_clause.analyse_declarations(env)
3583 if self.else_clause:
3584 self.else_clause.analyse_declarations(env)
3586 def analyse_expressions(self, env):
3587 for if_clause in self.if_clauses:
3588 if_clause.analyse_expressions(env)
3589 if self.else_clause:
3590 self.else_clause.analyse_expressions(env)
3592 def generate_execution_code(self, code):
3593 code.mark_pos(self.pos)
3594 end_label = code.new_label()
3595 for if_clause in self.if_clauses:
3596 if_clause.generate_execution_code(code, end_label)
3597 if self.else_clause:
3598 code.putln("/*else*/ {")
3599 self.else_clause.generate_execution_code(code)
3601 code.put_label(end_label)
3603 def annotate(self, code):
3604 for if_clause in self.if_clauses:
3605 if_clause.annotate(code)
3606 if self.else_clause:
3607 self.else_clause.annotate(code)
3610 class IfClauseNode(Node):
3611 # if or elif clause in an if statement
3613 # condition ExprNode
3616 child_attrs = ["condition", "body"]
3618 def analyse_control_flow(self, env):
3619 self.body.analyse_control_flow(env)
3621 def analyse_declarations(self, env):
3622 self.condition.analyse_declarations(env)
3623 self.body.analyse_declarations(env)
3625 def analyse_expressions(self, env):
3627 self.condition.analyse_temp_boolean_expression(env)
3628 self.condition.release_temp(env)
3629 self.body.analyse_expressions(env)
3631 def generate_execution_code(self, code, end_label):
3632 self.condition.generate_evaluation_code(code)
3635 self.condition.result())
3636 self.condition.generate_disposal_code(code)
3637 self.condition.free_temps(code)
3638 self.body.generate_execution_code(code)
3642 code.put_goto(end_label)
3645 def annotate(self, code):
3646 self.condition.annotate(code)
3647 self.body.annotate(code)
3650 class SwitchCaseNode(StatNode):
3651 # Generated in the optimization of an if-elif-else node
3653 # conditions [ExprNode]
3656 child_attrs = ['conditions', 'body']
3658 def generate_execution_code(self, code):
3659 for cond in self.conditions:
3660 code.mark_pos(cond.pos)
3661 cond.generate_evaluation_code(code)
3662 code.putln("case %s:" % cond.result())
3663 self.body.generate_execution_code(code)
3664 code.putln("break;")
3666 def annotate(self, code):
3667 for cond in self.conditions:
3669 self.body.annotate(code)
3671 class SwitchStatNode(StatNode):
3672 # Generated in the optimization of an if-elif-else node
3675 # cases [SwitchCaseNode]
3676 # else_clause StatNode or None
3678 child_attrs = ['test', 'cases', 'else_clause']
3680 def generate_execution_code(self, code):
3681 code.putln("switch (%s) {" % self.test.result())
3682 for case in self.cases:
3683 case.generate_execution_code(code)
3684 if self.else_clause is not None:
3685 code.putln("default:")
3686 self.else_clause.generate_execution_code(code)
3687 code.putln("break;")
3690 def annotate(self, code):
3691 self.test.annotate(code)
3692 for case in self.cases:
3694 if self.else_clause is not None:
3695 self.else_clause.annotate(code)
3697 class LoopNode(object):
3699 def analyse_control_flow(self, env):
3700 env.start_branching(self.pos)
3701 self.body.analyse_control_flow(env)
3702 env.next_branch(self.body.end_pos())
3703 if self.else_clause:
3704 self.else_clause.analyse_control_flow(env)
3705 env.finish_branching(self.end_pos())
3708 class WhileStatNode(LoopNode, StatNode):
3711 # condition ExprNode
3713 # else_clause StatNode
3715 child_attrs = ["condition", "body", "else_clause"]
3717 def analyse_declarations(self, env):
3718 self.body.analyse_declarations(env)
3719 if self.else_clause:
3720 self.else_clause.analyse_declarations(env)
3722 def analyse_expressions(self, env):
3724 self.condition.analyse_temp_boolean_expression(env)
3725 self.condition.release_temp(env)
3726 #env.recycle_pending_temps() # TEMPORARY
3727 self.body.analyse_expressions(env)
3728 if self.else_clause:
3729 self.else_clause.analyse_expressions(env)
3731 def generate_execution_code(self, code):
3732 old_loop_labels = code.new_loop_labels()
3735 self.condition.generate_evaluation_code(code)
3736 self.condition.generate_disposal_code(code)
3739 self.condition.result())
3740 self.condition.free_temps(code)
3741 self.body.generate_execution_code(code)
3742 code.put_label(code.continue_label)
3744 break_label = code.break_label
3745 code.set_loop_labels(old_loop_labels)
3746 if self.else_clause:
3747 code.putln("/*else*/ {")
3748 self.else_clause.generate_execution_code(code)
3750 code.put_label(break_label)
3752 def annotate(self, code):
3753 self.condition.annotate(code)
3754 self.body.annotate(code)
3755 if self.else_clause:
3756 self.else_clause.annotate(code)
3759 def ForStatNode(pos, **kw):
3760 if 'iterator' in kw:
3761 return ForInStatNode(pos, **kw)
3763 return ForFromStatNode(pos, **kw)
3765 class ForInStatNode(LoopNode, StatNode):
3769 # iterator IteratorNode
3771 # else_clause StatNode
3772 # item NextNode used internally
3774 child_attrs = ["target", "iterator", "body", "else_clause"]
3777 def analyse_declarations(self, env):
3778 self.target.analyse_target_declaration(env)
3779 self.body.analyse_declarations(env)
3780 if self.else_clause:
3781 self.else_clause.analyse_declarations(env)
3783 def analyse_expressions(self, env):
3785 self.target.analyse_target_types(env)
3786 self.iterator.analyse_expressions(env)
3787 self.item = ExprNodes.NextNode(self.iterator, env)
3788 self.item = self.item.coerce_to(self.target.type, env)
3789 self.item.allocate_temps(env)
3790 self.target.allocate_target_temps(env, self.item)
3791 #self.item.release_temp(env)
3792 #self.target.release_target_temp(env)
3793 self.body.analyse_expressions(env)
3794 if self.else_clause:
3795 self.else_clause.analyse_expressions(env)
3796 self.iterator.release_temp(env)
3798 def generate_execution_code(self, code):
3799 old_loop_labels = code.new_loop_labels()
3800 self.iterator.allocate_counter_temp(code)
3801 self.iterator.generate_evaluation_code(code)
3804 self.item.generate_evaluation_code(code)
3805 self.target.generate_assignment_code(self.item, code)
3806 self.body.generate_execution_code(code)
3807 code.put_label(code.continue_label)
3810 break_label = code.break_label
3811 code.set_loop_labels(old_loop_labels)
3812 if self.else_clause:
3813 code.putln("/*else*/ {")
3814 self.else_clause.generate_execution_code(code)
3816 code.put_label(break_label)
3817 self.iterator.release_counter_temp(code)
3818 self.iterator.generate_disposal_code(code)
3819 self.iterator.free_temps(code)
3821 def annotate(self, code):
3822 self.target.annotate(code)
3823 self.iterator.annotate(code)
3824 self.body.annotate(code)
3825 if self.else_clause:
3826 self.else_clause.annotate(code)
3827 self.item.annotate(code)
3830 class ForFromStatNode(LoopNode, StatNode):
3831 # for name from expr rel name rel expr
3838 # step ExprNode or None
3840 # else_clause StatNode or None
3845 # loopvar_node ExprNode (usually a NameNode or temp node)
3846 # py_loopvar_node PyTempNode or None
3847 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3849 is_py_target = False
3851 py_loopvar_node = None
3853 def analyse_declarations(self, env):
3854 self.target.analyse_target_declaration(env)
3855 self.body.analyse_declarations(env)
3856 if self.else_clause:
3857 self.else_clause.analyse_declarations(env)
3859 def analyse_expressions(self, env):
3861 self.target.analyse_target_types(env)
3862 self.bound1.analyse_types(env)
3863 self.bound2.analyse_types(env)
3864 if self.target.type.is_numeric:
3865 self.bound1 = self.bound1.coerce_to(self.target.type, env)
3866 self.bound2 = self.bound2.coerce_to(self.target.type, env)
3868 self.bound1 = self.bound1.coerce_to_integer(env)
3869 self.bound2 = self.bound2.coerce_to_integer(env)
3870 if self.step is not None:
3871 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3872 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3873 self.step.analyse_types(env)
3874 self.step = self.step.coerce_to_integer(env)
3875 if not (self.bound2.is_name or self.bound2.is_literal):
3876 self.bound2 = self.bound2.coerce_to_temp(env)
3877 target_type = self.target.type
3878 if not (target_type.is_pyobject or target_type.is_numeric):
3879 error(self.target.pos,
3880 "Integer for-loop variable must be of type int or Python object")
3881 #if not (target_type.is_pyobject
3882 # or target_type.assignable_from(PyrexTypes.c_int_type)):
3883 # error(self.target.pos,
3884 # "Cannot assign integer to variable of type '%s'" % target_type)
3885 if target_type.is_numeric:
3886 self.is_py_target = 0
3887 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3888 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3889 self.loopvar_node = self.target
3890 self.py_loopvar_node = None
3892 self.is_py_target = 1
3893 c_loopvar_node = ExprNodes.TempNode(self.pos,
3894 PyrexTypes.c_long_type, env)
3895 c_loopvar_node.allocate_temps(env)
3896 self.loopvar_node = c_loopvar_node
3897 self.py_loopvar_node = \
3898 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3899 self.bound1.allocate_temps(env)
3900 self.bound2.allocate_temps(env)
3901 if self.step is not None:
3902 self.step.allocate_temps(env)
3903 if self.is_py_target:
3904 self.py_loopvar_node.allocate_temps(env)
3905 self.target.allocate_target_temps(env, self.py_loopvar_node)
3906 #self.target.release_target_temp(env)
3907 #self.py_loopvar_node.release_temp(env)
3908 self.body.analyse_expressions(env)
3909 if self.is_py_target:
3910 c_loopvar_node.release_temp(env)
3911 if self.else_clause:
3912 self.else_clause.analyse_expressions(env)
3913 self.bound1.release_temp(env)
3914 self.bound2.release_temp(env)
3915 if self.step is not None:
3916 self.step.release_temp(env)
3918 def generate_execution_code(self, code):
3919 old_loop_labels = code.new_loop_labels()
3920 from_range = getattr(self, "from_range", False)
3921 self.bound1.generate_evaluation_code(code)
3922 self.bound2.generate_evaluation_code(code)
3923 offset, incop = self.relation_table[self.relation1]
3928 if self.step is not None:
3929 self.step.generate_evaluation_code(code)
3930 step = self.step.result()
3931 incop = "%s=%s" % (incop[0], step)
3932 decop = "%s=%s" % (decop[0], step)
3933 loopvar_name = self.loopvar_node.result()
3935 range_bound = code.funcstate.allocate_temp(self.bound2.type, manage_ref=False)
3936 code.putln("%s = %s;" % (range_bound, self.bound2.result()))
3937 # Skip the loop entirely (and avoid assigning to the loopvar) if
3938 # the loop is empty:
3939 code.putln("if (%s%s %s %s) {" % (
3940 self.bound1.result(), offset, self.relation2, range_bound
3943 range_bound = self.bound2.result()
3945 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3947 self.bound1.result(), offset,
3948 loopvar_name, self.relation2, range_bound,
3949 loopvar_name, incop))
3950 if self.py_loopvar_node:
3951 self.py_loopvar_node.generate_evaluation_code(code)
3952 self.target.generate_assignment_code(self.py_loopvar_node, code)
3953 self.body.generate_execution_code(code)
3954 code.put_label(code.continue_label)
3956 # Undo last increment to maintain Python semantics:
3957 code.putln("} %s%s;" % (loopvar_name, decop))
3958 # End the outer if statement:
3959 code.putln("} /* end if */")
3960 code.funcstate.release_temp(range_bound)
3963 break_label = code.break_label
3964 code.set_loop_labels(old_loop_labels)
3965 if self.else_clause:
3966 code.putln("/*else*/ {")
3967 self.else_clause.generate_execution_code(code)
3969 code.put_label(break_label)
3970 self.bound1.generate_disposal_code(code)
3971 self.bound1.free_temps(code)
3972 self.bound2.generate_disposal_code(code)
3973 self.bound2.free_temps(code)
3974 if self.step is not None:
3975 self.step.generate_disposal_code(code)
3976 self.step.free_temps(code)
3979 # {relop : (initial offset, increment op)}
3986 def annotate(self, code):
3987 self.target.annotate(code)
3988 self.bound1.annotate(code)
3989 self.bound2.annotate(code)
3991 self.bound2.annotate(code)
3992 self.body.annotate(code)
3993 if self.else_clause:
3994 self.else_clause.annotate(code)
3997 class WithStatNode(StatNode):
3999 Represents a Python with statement.
4001 This is only used at parse tree level; and is not present in
4002 analysis or generation phases.
4004 # manager The with statement manager object
4005 # target Node (lhs expression)
4007 child_attrs = ["manager", "target", "body"]
4009 class TryExceptStatNode(StatNode):
4010 # try .. except statement
4013 # except_clauses [ExceptClauseNode]
4014 # else_clause StatNode or None
4015 # cleanup_list [Entry] old style temps to clean up on error
4017 child_attrs = ["body", "except_clauses", "else_clause"]
4019 def analyse_control_flow(self, env):
4020 env.start_branching(self.pos)
4021 self.body.analyse_control_flow(env)
4022 successful_try = env.control_flow # grab this for later
4023 env.next_branch(self.body.end_pos())
4024 env.finish_branching(self.body.end_pos())
4026 env.start_branching(self.except_clauses[0].pos)
4027 for except_clause in self.except_clauses:
4028 except_clause.analyse_control_flow(env)
4029 env.next_branch(except_clause.end_pos())
4031 # the else cause it executed only when the try clause finishes
4032 env.control_flow.incoming = successful_try
4033 if self.else_clause:
4034 self.else_clause.analyse_control_flow(env)
4035 env.finish_branching(self.end_pos())
4037 def analyse_declarations(self, env):
4038 self.body.analyse_declarations(env)
4039 for except_clause in self.except_clauses:
4040 except_clause.analyse_declarations(env)
4041 if self.else_clause:
4042 self.else_clause.analyse_declarations(env)
4043 env.use_utility_code(reset_exception_utility_code)
4045 def analyse_expressions(self, env):
4046 self.body.analyse_expressions(env)
4047 self.cleanup_list = env.free_temp_entries[:]
4048 default_clause_seen = 0
4049 for except_clause in self.except_clauses:
4050 except_clause.analyse_expressions(env)
4051 if default_clause_seen:
4052 error(except_clause.pos, "default 'except:' must be last")
4053 if not except_clause.pattern:
4054 default_clause_seen = 1
4055 self.has_default_clause = default_clause_seen
4056 if self.else_clause:
4057 self.else_clause.analyse_expressions(env)
4059 gil_check = StatNode._gil_check
4060 gil_message = "Try-except statement"
4062 def generate_execution_code(self, code):
4063 old_return_label = code.return_label
4064 old_break_label = code.break_label
4065 old_continue_label = code.continue_label
4066 old_error_label = code.new_error_label()
4067 our_error_label = code.error_label
4068 except_end_label = code.new_label('exception_handled')
4069 except_error_label = code.new_label('except_error')
4070 except_return_label = code.new_label('except_return')
4071 try_return_label = code.new_label('try_return')
4072 try_break_label = code.new_label('try_break')
4073 try_continue_label = code.new_label('try_continue')
4074 try_end_label = code.new_label('try_end')
4077 code.putln("PyObject %s;" %
4078 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4079 code.putln("__Pyx_ExceptionSave(%s);" %
4080 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4081 for var in Naming.exc_save_vars:
4082 code.put_xgotref(var)
4085 code.return_label = try_return_label
4086 code.break_label = try_break_label
4087 code.continue_label = try_continue_label
4088 self.body.generate_execution_code(code)
4091 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4092 code.error_label = except_error_label
4093 code.return_label = except_return_label
4094 if self.else_clause:
4097 self.else_clause.generate_execution_code(code)
4100 for var in Naming.exc_save_vars:
4101 code.put_xdecref_clear(var, py_object_type)
4102 code.put_goto(try_end_label)
4103 if code.label_used(try_return_label):
4104 code.put_label(try_return_label)
4105 for var in Naming.exc_save_vars:
4106 code.put_xdecref_clear(var, py_object_type)
4107 code.put_goto(old_return_label)
4108 code.put_label(our_error_label)
4109 code.put_var_xdecrefs_clear(self.cleanup_list)
4110 for temp_name, type in temps_to_clean_up:
4111 code.put_xdecref_clear(temp_name, type)
4112 for except_clause in self.except_clauses:
4113 except_clause.generate_handling_code(code, except_end_label)
4115 error_label_used = code.label_used(except_error_label)
4116 if error_label_used or not self.has_default_clause:
4117 if error_label_used:
4118 code.put_label(except_error_label)
4119 for var in Naming.exc_save_vars:
4120 code.put_xdecref(var, py_object_type)
4121 code.put_goto(old_error_label)
4123 if code.label_used(try_break_label):
4124 code.put_label(try_break_label)
4125 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4126 code.putln("__Pyx_ExceptionReset(%s);" %
4127 ', '.join(Naming.exc_save_vars))
4128 code.put_goto(old_break_label)
4130 if code.label_used(try_continue_label):
4131 code.put_label(try_continue_label)
4132 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4133 code.putln("__Pyx_ExceptionReset(%s);" %
4134 ', '.join(Naming.exc_save_vars))
4135 code.put_goto(old_continue_label)
4137 if code.label_used(except_return_label):
4138 code.put_label(except_return_label)
4139 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4140 code.putln("__Pyx_ExceptionReset(%s);" %
4141 ', '.join(Naming.exc_save_vars))
4142 code.put_goto(old_return_label)
4144 if code.label_used(except_end_label):
4145 code.put_label(except_end_label)
4146 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4147 code.putln("__Pyx_ExceptionReset(%s);" %
4148 ', '.join(Naming.exc_save_vars))
4149 code.put_label(try_end_label)
4152 code.return_label = old_return_label
4153 code.break_label = old_break_label
4154 code.continue_label = old_continue_label
4155 code.error_label = old_error_label
4157 def annotate(self, code):
4158 self.body.annotate(code)
4159 for except_node in self.except_clauses:
4160 except_node.annotate(code)
4161 if self.else_clause:
4162 self.else_clause.annotate(code)
4165 class ExceptClauseNode(Node):
4166 # Part of try ... except statement.
4169 # target ExprNode or None
4171 # excinfo_target NameNode or None optional target for exception info
4172 # match_flag string result of exception match
4173 # exc_value ExcValueNode used internally
4174 # function_name string qualified name of enclosing function
4175 # exc_vars (string * 3) local exception variables
4177 # excinfo_target is never set by the parser, but can be set by a transform
4178 # in order to extract more extensive information about the exception as a
4179 # sys.exc_info()-style tuple into a target variable
4181 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4184 excinfo_target = None
4186 def analyse_declarations(self, env):
4188 self.target.analyse_target_declaration(env)
4189 if self.excinfo_target is not None:
4190 self.excinfo_target.analyse_target_declaration(env)
4191 self.body.analyse_declarations(env)
4193 def analyse_expressions(self, env):
4195 genv = env.global_scope()
4196 self.function_name = env.qualified_name
4198 self.pattern.analyse_expressions(env)
4199 self.pattern = self.pattern.coerce_to_pyobject(env)
4200 self.match_flag = env.allocate_temp(PyrexTypes.c_int_type)
4201 self.pattern.release_temp(env)
4202 env.release_temp(self.match_flag)
4203 self.exc_vars = [env.allocate_temp(py_object_type) for i in xrange(3)]
4205 self.exc_value = ExprNodes.ExcValueNode(self.pos, env, self.exc_vars[1])
4206 self.exc_value.allocate_temps(env)
4207 self.target.analyse_target_expression(env, self.exc_value)
4208 if self.excinfo_target is not None:
4210 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4211 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[0]),
4212 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[1]),
4213 ExprNodes.ExcValueNode(pos=self.pos, env=env, var=self.exc_vars[2])
4215 self.excinfo_tuple.analyse_expressions(env)
4216 self.excinfo_tuple.allocate_temps(env)
4217 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4219 self.body.analyse_expressions(env)
4220 for var in self.exc_vars:
4221 env.release_temp(var)
4222 env.use_utility_code(get_exception_utility_code)
4223 env.use_utility_code(restore_exception_utility_code)
4225 def generate_handling_code(self, code, end_label):
4226 code.mark_pos(self.pos)
4228 self.pattern.generate_evaluation_code(code)
4230 "%s = PyErr_ExceptionMatches(%s);" % (
4232 self.pattern.py_result()))
4233 self.pattern.generate_disposal_code(code)
4234 self.pattern.free_temps(code)
4239 code.putln("/*except:*/ {")
4240 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4241 # We always have to fetch the exception value even if
4242 # there is no target, because this also normalises the
4243 # exception and stores it in the thread state.
4244 exc_args = "&%s, &%s, &%s" % tuple(self.exc_vars)
4245 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4246 code.error_goto(self.pos)))
4247 for x in self.exc_vars:
4250 self.exc_value.generate_evaluation_code(code)
4251 self.target.generate_assignment_code(self.exc_value, code)
4252 if self.excinfo_target is not None:
4253 self.excinfo_tuple.generate_evaluation_code(code)
4254 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4257 old_break_label, old_continue_label = code.break_label, code.continue_label
4258 code.break_label = code.new_label('except_break')
4259 code.continue_label = code.new_label('except_continue')
4261 old_exc_vars = code.funcstate.exc_vars
4262 code.funcstate.exc_vars = self.exc_vars
4263 self.body.generate_execution_code(code)
4264 code.funcstate.exc_vars = old_exc_vars
4265 for var in self.exc_vars:
4266 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4267 code.put_goto(end_label)
4269 if code.label_used(code.break_label):
4270 code.put_label(code.break_label)
4271 for var in self.exc_vars:
4272 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4273 code.put_goto(old_break_label)
4274 code.break_label = old_break_label
4276 if code.label_used(code.continue_label):
4277 code.put_label(code.continue_label)
4278 for var in self.exc_vars:
4279 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4280 code.put_goto(old_continue_label)
4281 code.continue_label = old_continue_label
4286 def annotate(self, code):
4288 self.pattern.annotate(code)
4290 self.target.annotate(code)
4291 self.body.annotate(code)
4294 class TryFinallyStatNode(StatNode):
4295 # try ... finally statement
4298 # finally_clause StatNode
4300 # cleanup_list [Entry] old_style temps to clean up on error
4302 # The plan is that we funnel all continue, break
4303 # return and error gotos into the beginning of the
4304 # finally block, setting a variable to remember which
4305 # one we're doing. At the end of the finally block, we
4306 # switch on the variable to figure out where to go.
4307 # In addition, if we're doing an error, we save the
4308 # exception on entry to the finally block and restore
4311 child_attrs = ["body", "finally_clause"]
4313 preserve_exception = 1
4315 disallow_continue_in_try_finally = 0
4316 # There doesn't seem to be any point in disallowing
4317 # continue in the try block, since we have no problem
4320 def create_analysed(pos, env, body, finally_clause):
4321 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4322 node.cleanup_list = []
4324 create_analysed = staticmethod(create_analysed)
4326 def analyse_control_flow(self, env):
4327 env.start_branching(self.pos)
4328 self.body.analyse_control_flow(env)
4329 env.next_branch(self.body.end_pos())
4330 env.finish_branching(self.body.end_pos())
4331 self.finally_clause.analyse_control_flow(env)
4333 def analyse_declarations(self, env):
4334 self.body.analyse_declarations(env)
4335 self.finally_clause.analyse_declarations(env)
4337 def analyse_expressions(self, env):
4338 self.body.analyse_expressions(env)
4339 self.cleanup_list = env.free_temp_entries[:]
4340 self.finally_clause.analyse_expressions(env)
4342 gil_check = StatNode._gil_check
4343 gil_message = "Try-finally statement"
4345 def generate_execution_code(self, code):
4346 old_error_label = code.error_label
4347 old_labels = code.all_new_labels()
4348 new_labels = code.get_all_labels()
4349 new_error_label = code.error_label
4350 catch_label = code.new_label()
4353 if self.disallow_continue_in_try_finally:
4354 was_in_try_finally = code.funcstate.in_try_finally
4355 code.funcstate.in_try_finally = 1
4356 self.body.generate_execution_code(code)
4357 if self.disallow_continue_in_try_finally:
4358 code.funcstate.in_try_finally = was_in_try_finally
4361 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4365 error_label_used = 0
4366 for i, new_label in enumerate(new_labels):
4367 if new_label in code.labels_used:
4368 cases_used.append(i)
4369 if new_label == new_error_label:
4370 error_label_used = 1
4371 error_label_case = i
4375 if error_label_used and self.preserve_exception:
4377 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4379 "int %s;" % Naming.exc_lineno_name)
4380 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4381 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4382 code.putln(exc_var_init_zero)
4384 exc_var_init_zero = None
4385 code.use_label(catch_label)
4387 "__pyx_why = 0; goto %s;" % catch_label)
4388 for i in cases_used:
4389 new_label = new_labels[i]
4390 #if new_label and new_label != "<try>":
4391 if new_label == new_error_label and self.preserve_exception:
4392 self.put_error_catcher(code,
4393 new_error_label, i+1, catch_label, temps_to_clean_up)
4395 code.put('%s: ' % new_label)
4396 if exc_var_init_zero:
4397 code.putln(exc_var_init_zero)
4398 code.putln("__pyx_why = %s; goto %s;" % (
4401 code.put_label(catch_label)
4402 code.set_all_labels(old_labels)
4403 if error_label_used:
4404 code.new_error_label()
4405 finally_error_label = code.error_label
4406 self.finally_clause.generate_execution_code(code)
4407 if error_label_used:
4408 if finally_error_label in code.labels_used and self.preserve_exception:
4409 over_label = code.new_label()
4410 code.put_goto(over_label);
4411 code.put_label(finally_error_label)
4412 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4413 for var in Naming.exc_vars:
4414 code.putln("Py_XDECREF(%s);" % var)
4416 code.put_goto(old_error_label)
4417 code.put_label(over_label)
4418 code.error_label = old_error_label
4421 "switch (__pyx_why) {")
4422 for i in cases_used:
4423 old_label = old_labels[i]
4424 if old_label == old_error_label and self.preserve_exception:
4425 self.put_error_uncatcher(code, i+1, old_error_label)
4427 code.use_label(old_label)
4429 "case %s: goto %s;" % (
4437 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4438 code.globalstate.use_utility_code(restore_exception_utility_code)
4445 code.put_var_xdecrefs_clear(self.cleanup_list)
4446 for temp_name, type in temps_to_clean_up:
4447 code.put_xdecref_clear(temp_name, type)
4449 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4453 Naming.exc_lineno_name, Naming.lineno_cname))
4457 code.put_goto(catch_label)
4461 def put_error_uncatcher(self, code, i, error_label):
4462 code.globalstate.use_utility_code(restore_exception_utility_code)
4467 "__Pyx_ErrRestore(%s, %s, %s);" %
4471 Naming.lineno_cname, Naming.exc_lineno_name))
4472 for var in Naming.exc_vars:
4476 code.put_goto(error_label)
4480 def annotate(self, code):
4481 self.body.annotate(code)
4482 self.finally_clause.annotate(code)
4485 class GILStatNode(TryFinallyStatNode):
4486 # 'with gil' or 'with nogil' statement
4488 # state string 'gil' or 'nogil'
4492 preserve_exception = 0
4494 def __init__(self, pos, state, body):
4496 TryFinallyStatNode.__init__(self, pos,
4498 finally_clause = GILExitNode(pos, state = state))
4500 def analyse_expressions(self, env):
4501 env.use_utility_code(force_init_threads_utility_code)
4502 was_nogil = env.nogil
4504 TryFinallyStatNode.analyse_expressions(self, env)
4505 env.nogil = was_nogil
4507 def gil_check(self, env):
4510 def generate_execution_code(self, code):
4511 code.mark_pos(self.pos)
4512 if self.state == 'gil':
4513 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4515 code.putln("{ PyThreadState *_save;")
4516 code.putln("Py_UNBLOCK_THREADS")
4517 TryFinallyStatNode.generate_execution_code(self, code)
4521 class GILExitNode(StatNode):
4522 # Used as the 'finally' block in a GILStatNode
4524 # state string 'gil' or 'nogil'
4528 def analyse_expressions(self, env):
4531 def generate_execution_code(self, code):
4532 if self.state == 'gil':
4533 code.putln("PyGILState_Release();")
4535 code.putln("Py_BLOCK_THREADS")
4538 class CImportStatNode(StatNode):
4541 # module_name string Qualified name of module being imported
4542 # as_name string or None Name specified in "as" clause, if any
4546 def analyse_declarations(self, env):
4547 if not env.is_module_scope:
4548 error(self.pos, "cimport only allowed at module level")
4550 module_scope = env.find_module(self.module_name, self.pos)
4551 if "." in self.module_name:
4552 names = [EncodedString(name) for name in self.module_name.split(".")]
4554 top_module_scope = env.context.find_submodule(top_name)
4555 module_scope = top_module_scope
4556 for name in names[1:]:
4557 submodule_scope = module_scope.find_submodule(name)
4558 module_scope.declare_module(name, submodule_scope, self.pos)
4559 module_scope = submodule_scope
4561 env.declare_module(self.as_name, module_scope, self.pos)
4563 env.declare_module(top_name, top_module_scope, self.pos)
4565 name = self.as_name or self.module_name
4566 env.declare_module(name, module_scope, self.pos)
4568 def analyse_expressions(self, env):
4571 def generate_execution_code(self, code):
4575 class FromCImportStatNode(StatNode):
4576 # from ... cimport statement
4578 # module_name string Qualified name of module
4579 # imported_names [(pos, name, as_name, kind)] Names to be imported
4583 def analyse_declarations(self, env):
4584 if not env.is_module_scope:
4585 error(self.pos, "cimport only allowed at module level")
4587 module_scope = env.find_module(self.module_name, self.pos)
4588 env.add_imported_module(module_scope)
4589 for pos, name, as_name, kind in self.imported_names:
4591 for local_name, entry in module_scope.entries.items():
4592 env.add_imported_entry(local_name, entry, pos)
4594 entry = module_scope.lookup(name)
4596 if kind and not self.declaration_matches(entry, kind):
4597 entry.redeclared(pos)
4599 if kind == 'struct' or kind == 'union':
4600 entry = module_scope.declare_struct_or_union(name,
4601 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4602 elif kind == 'class':
4603 entry = module_scope.declare_c_class(name, pos = pos,
4604 module_name = self.module_name)
4606 error(pos, "Name '%s' not declared in module '%s'"
4607 % (name, self.module_name))
4610 local_name = as_name or name
4611 env.add_imported_entry(local_name, entry, pos)
4613 def declaration_matches(self, entry, kind):
4614 if not entry.is_type:
4618 if not type.is_extension_type:
4621 if not type.is_struct_or_union:
4623 if kind != type.kind:
4627 def analyse_expressions(self, env):
4630 def generate_execution_code(self, code):
4634 class FromImportStatNode(StatNode):
4635 # from ... import statement
4638 # items [(string, NameNode)]
4639 # interned_items [(string, NameNode, ExprNode)]
4640 # item PyTempNode used internally
4641 # import_star boolean used internally
4643 child_attrs = ["module"]
4646 def analyse_declarations(self, env):
4647 for name, target in self.items:
4649 if not env.is_module_scope:
4650 error(self.pos, "import * only allowed at module level")
4652 env.has_import_star = 1
4653 self.import_star = 1
4655 target.analyse_target_declaration(env)
4657 def analyse_expressions(self, env):
4659 self.module.analyse_expressions(env)
4660 self.item = ExprNodes.PyTempNode(self.pos, env)
4661 self.item.allocate_temp(env)
4662 self.interned_items = []
4663 for name, target in self.items:
4665 for _, entry in env.entries.items():
4666 if not entry.is_type and entry.type.is_extension_type:
4667 env.use_utility_code(ExprNodes.type_test_utility_code)
4670 entry = env.lookup(target.name)
4671 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4672 continue # already cimported
4673 target.analyse_target_expression(env, None)
4674 if target.type is py_object_type:
4677 coerced_item = self.item.coerce_to(target.type, env)
4678 self.interned_items.append(
4679 (name, target, coerced_item))
4680 #target.release_target_temp(env) # was release_temp ?!?
4681 self.module.release_temp(env)
4682 self.item.release_temp(env)
4684 def generate_execution_code(self, code):
4685 self.module.generate_evaluation_code(code)
4686 if self.import_star:
4688 'if (%s(%s) < 0) %s;' % (
4690 self.module.py_result(),
4691 code.error_goto(self.pos)))
4692 for name, target, coerced_item in self.interned_items:
4693 cname = code.intern_identifier(name)
4695 '%s = PyObject_GetAttr(%s, %s); %s' % (
4697 self.module.py_result(),
4699 code.error_goto_if_null(self.item.result(), self.pos)))
4700 code.put_gotref(self.item.py_result())
4701 if coerced_item is None:
4702 target.generate_assignment_code(self.item, code)
4704 coerced_item.allocate_temp_result(code)
4705 coerced_item.generate_result_code(code)
4706 target.generate_assignment_code(coerced_item, code)
4707 if self.item.result() != coerced_item.result():
4708 code.put_decref_clear(self.item.result(), self.item.type)
4709 self.module.generate_disposal_code(code)
4710 self.module.free_temps(code)
4714 #------------------------------------------------------------------------------------
4716 # Runtime support code
4718 #------------------------------------------------------------------------------------
4720 utility_function_predeclarations = \
4723 #define INLINE __inline__
4725 #define INLINE __inline
4730 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4734 static int %(skip_dispatch_cname)s = 0;
4736 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4738 if Options.gcc_branch_hints:
4739 branch_prediction_macros = \
4742 /* Test for GCC > 2.95 */
4743 #if __GNUC__ > 2 || \
4744 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4745 #define likely(x) __builtin_expect(!!(x), 1)
4746 #define unlikely(x) __builtin_expect(!!(x), 0)
4747 #else /* __GNUC__ > 2 ... */
4748 #define likely(x) (x)
4749 #define unlikely(x) (x)
4750 #endif /* __GNUC__ > 2 ... */
4751 #else /* __GNUC__ */
4752 #define likely(x) (x)
4753 #define unlikely(x) (x)
4754 #endif /* __GNUC__ */
4757 branch_prediction_macros = \
4759 #define likely(x) (x)
4760 #define unlikely(x) (x)
4763 #get_name_predeclaration = \
4764 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4766 #get_name_interned_predeclaration = \
4767 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4769 #------------------------------------------------------------------------------------
4771 printing_utility_code = UtilityCode(
4773 static int __Pyx_Print(PyObject *, int); /*proto*/
4774 #if PY_MAJOR_VERSION >= 3
4775 static PyObject* %s = 0;
4776 static PyObject* %s = 0;
4778 """ % (Naming.print_function, Naming.print_function_kwargs),
4780 #if PY_MAJOR_VERSION < 3
4781 static PyObject *__Pyx_GetStdout(void) {
4782 PyObject *f = PySys_GetObject((char *)"stdout");
4784 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4789 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4794 if (!(f = __Pyx_GetStdout()))
4796 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4797 if (PyFile_SoftSpace(f, 1)) {
4798 if (PyFile_WriteString(" ", f) < 0)
4801 v = PyTuple_GET_ITEM(arg_tuple, i);
4802 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4804 if (PyString_Check(v)) {
4805 char *s = PyString_AsString(v);
4806 Py_ssize_t len = PyString_Size(v);
4808 isspace(Py_CHARMASK(s[len-1])) &&
4810 PyFile_SoftSpace(f, 0);
4814 if (PyFile_WriteString("\n", f) < 0)
4816 PyFile_SoftSpace(f, 0);
4821 #else /* Python 3 has a print function */
4823 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4824 PyObject* kwargs = 0;
4825 PyObject* result = 0;
4826 PyObject* end_string;
4827 if (!%(PRINT_FUNCTION)s) {
4828 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4829 if (!%(PRINT_FUNCTION)s)
4833 if (!%(PRINT_KWARGS)s) {
4834 %(PRINT_KWARGS)s = PyDict_New();
4835 if (!%(PRINT_KWARGS)s)
4837 end_string = PyUnicode_FromStringAndSize(" ", 1);
4840 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4841 Py_DECREF(end_string);
4844 Py_DECREF(end_string);
4846 kwargs = %(PRINT_KWARGS)s;
4848 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4856 """ % {'BUILTINS' : Naming.builtins_cname,
4857 'PRINT_FUNCTION' : Naming.print_function,
4858 'PRINT_KWARGS' : Naming.print_function_kwargs}
4862 printing_one_utility_code = UtilityCode(
4864 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4867 #if PY_MAJOR_VERSION < 3
4869 static int __Pyx_PrintOne(PyObject *o) {
4871 if (!(f = __Pyx_GetStdout()))
4873 if (PyFile_SoftSpace(f, 0)) {
4874 if (PyFile_WriteString(" ", f) < 0)
4877 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4879 if (PyFile_WriteString("\n", f) < 0)
4882 /* the line below is just to avoid compiler
4883 * compiler warnings about unused functions */
4884 return __Pyx_Print(NULL, 0);
4887 #else /* Python 3 has a print function */
4889 static int __Pyx_PrintOne(PyObject *o) {
4891 PyObject* arg_tuple = PyTuple_New(1);
4892 if (unlikely(!arg_tuple))
4895 PyTuple_SET_ITEM(arg_tuple, 0, o);
4896 res = __Pyx_Print(arg_tuple, 1);
4897 Py_DECREF(arg_tuple);
4906 #------------------------------------------------------------------------------------
4908 # The following function is based on do_raise() from ceval.c.
4910 raise_utility_code = UtilityCode(
4912 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4915 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4919 /* First, check the traceback argument, replacing None with NULL. */
4920 if (tb == Py_None) {
4924 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4925 PyErr_SetString(PyExc_TypeError,
4926 "raise: arg 3 must be a traceback or None");
4929 /* Next, replace a missing value with None */
4930 if (value == NULL) {
4934 #if PY_VERSION_HEX < 0x02050000
4935 if (!PyClass_Check(type))
4937 if (!PyType_Check(type))
4940 /* Raising an instance. The value should be a dummy. */
4941 if (value != Py_None) {
4942 PyErr_SetString(PyExc_TypeError,
4943 "instance exception may not have a separate value");
4946 /* Normalize to raise <class>, <instance> */
4949 #if PY_VERSION_HEX < 0x02050000
4950 if (PyInstance_Check(type)) {
4951 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4956 PyErr_SetString(PyExc_TypeError,
4957 "raise: exception must be an old-style class or instance");
4961 type = (PyObject*) Py_TYPE(type);
4963 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4964 PyErr_SetString(PyExc_TypeError,
4965 "raise: exception class must be a subclass of BaseException");
4970 __Pyx_ErrRestore(type, value, tb);
4980 #------------------------------------------------------------------------------------
4982 reraise_utility_code = UtilityCode(
4984 static void __Pyx_ReRaise(void); /*proto*/
4987 static void __Pyx_ReRaise(void) {
4988 PyThreadState *tstate = PyThreadState_GET();
4989 PyObject* tmp_type = tstate->curexc_type;
4990 PyObject* tmp_value = tstate->curexc_value;
4991 PyObject* tmp_tb = tstate->curexc_traceback;
4992 tstate->curexc_type = tstate->exc_type;
4993 tstate->curexc_value = tstate->exc_value;
4994 tstate->curexc_traceback = tstate->exc_traceback;
4995 tstate->exc_type = 0;
4996 tstate->exc_value = 0;
4997 tstate->exc_traceback = 0;
4998 Py_XDECREF(tmp_type);
4999 Py_XDECREF(tmp_value);
5004 #------------------------------------------------------------------------------------
5006 arg_type_test_utility_code = UtilityCode(
5008 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5009 const char *name, int exact); /*proto*/
5012 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5013 const char *name, int exact)
5016 PyErr_Format(PyExc_SystemError, "Missing type object");
5019 if (none_allowed && obj == Py_None) return 1;
5021 if (Py_TYPE(obj) == type) return 1;
5024 if (PyObject_TypeCheck(obj, type)) return 1;
5026 PyErr_Format(PyExc_TypeError,
5027 "Argument '%s' has incorrect type (expected %s, got %s)",
5028 name, type->tp_name, Py_TYPE(obj)->tp_name);
5033 #------------------------------------------------------------------------------------
5035 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5036 # many or too few positional arguments were found. This handles
5037 # Py_ssize_t formatting correctly.
5039 raise_argtuple_invalid_utility_code = UtilityCode(
5041 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5042 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5045 static void __Pyx_RaiseArgtupleInvalid(
5046 const char* func_name,
5050 Py_ssize_t num_found)
5052 Py_ssize_t num_expected;
5053 const char *number, *more_or_less;
5055 if (num_found < num_min) {
5056 num_expected = num_min;
5057 more_or_less = "at least";
5059 num_expected = num_max;
5060 more_or_less = "at most";
5063 more_or_less = "exactly";
5065 number = (num_expected == 1) ? "" : "s";
5066 PyErr_Format(PyExc_TypeError,
5067 #if PY_VERSION_HEX < 0x02050000
5068 "%s() takes %s %d positional argument%s (%d given)",
5070 "%s() takes %s %zd positional argument%s (%zd given)",
5072 func_name, more_or_less, num_expected, number, num_found);
5076 raise_keyword_required_utility_code = UtilityCode(
5078 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5081 static INLINE void __Pyx_RaiseKeywordRequired(
5082 const char* func_name,
5085 PyErr_Format(PyExc_TypeError,
5086 #if PY_MAJOR_VERSION >= 3
5087 "%s() needs keyword-only argument %U", func_name, kw_name);
5089 "%s() needs keyword-only argument %s", func_name,
5090 PyString_AS_STRING(kw_name));
5095 raise_double_keywords_utility_code = UtilityCode(
5097 static void __Pyx_RaiseDoubleKeywordsError(
5098 const char* func_name, PyObject* kw_name); /*proto*/
5101 static void __Pyx_RaiseDoubleKeywordsError(
5102 const char* func_name,
5105 PyErr_Format(PyExc_TypeError,
5106 #if PY_MAJOR_VERSION >= 3
5107 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5109 "%s() got multiple values for keyword argument '%s'", func_name,
5110 PyString_AS_STRING(kw_name));
5115 #------------------------------------------------------------------------------------
5117 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5118 # were passed to a function, or if any keywords were passed to a
5119 # function that does not accept them.
5121 keyword_string_check_utility_code = UtilityCode(
5123 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5124 const char* function_name, int kw_allowed); /*proto*/
5127 static INLINE int __Pyx_CheckKeywordStrings(
5129 const char* function_name,
5134 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5135 #if PY_MAJOR_VERSION < 3
5136 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5138 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5140 goto invalid_keyword_type;
5142 if ((!kw_allowed) && unlikely(key))
5143 goto invalid_keyword;
5145 invalid_keyword_type:
5146 PyErr_Format(PyExc_TypeError,
5147 "%s() keywords must be strings", function_name);
5150 PyErr_Format(PyExc_TypeError,
5151 #if PY_MAJOR_VERSION < 3
5152 "%s() got an unexpected keyword argument '%s'",
5153 function_name, PyString_AsString(key));
5155 "%s() got an unexpected keyword argument '%U'",
5156 function_name, key);
5162 #------------------------------------------------------------------------------------
5164 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5165 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5166 # keywords will raise an invalid keyword error.
5168 # Three kinds of errors are checked: 1) non-string keywords, 2)
5169 # unexpected keywords and 3) overlap with positional arguments.
5171 # If num_posargs is greater 0, it denotes the number of positional
5172 # arguments that were passed and that must therefore not appear
5173 # amongst the keywords as well.
5175 # This method does not check for required keyword arguments.
5178 parse_keywords_utility_code = UtilityCode(
5180 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5181 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5182 const char* function_name); /*proto*/
5185 static int __Pyx_ParseOptionalKeywords(
5187 PyObject **argnames[],
5190 Py_ssize_t num_pos_args,
5191 const char* function_name)
5193 PyObject *key = 0, *value = 0;
5196 PyObject*** first_kw_arg = argnames + num_pos_args;
5198 while (PyDict_Next(kwds, &pos, &key, &value)) {
5199 name = first_kw_arg;
5200 while (*name && (**name != key)) name++;
5202 values[name-argnames] = value;
5204 #if PY_MAJOR_VERSION < 3
5205 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5207 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5209 goto invalid_keyword_type;
5211 for (name = first_kw_arg; *name; name++) {
5212 #if PY_MAJOR_VERSION >= 3
5213 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5214 PyUnicode_Compare(**name, key) == 0) break;
5216 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5217 _PyString_Eq(**name, key)) break;
5221 values[name-argnames] = value;
5223 /* unexpected keyword found */
5224 for (name=argnames; name != first_kw_arg; name++) {
5225 if (**name == key) goto arg_passed_twice;
5226 #if PY_MAJOR_VERSION >= 3
5227 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5228 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5230 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5231 _PyString_Eq(**name, key)) goto arg_passed_twice;
5235 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5237 goto invalid_keyword;
5245 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5247 invalid_keyword_type:
5248 PyErr_Format(PyExc_TypeError,
5249 "%s() keywords must be strings", function_name);
5252 PyErr_Format(PyExc_TypeError,
5253 #if PY_MAJOR_VERSION < 3
5254 "%s() got an unexpected keyword argument '%s'",
5255 function_name, PyString_AsString(key));
5257 "%s() got an unexpected keyword argument '%U'",
5258 function_name, key);
5265 #------------------------------------------------------------------------------------
5267 unraisable_exception_utility_code = UtilityCode(
5269 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5272 static void __Pyx_WriteUnraisable(const char *name) {
5273 PyObject *old_exc, *old_val, *old_tb;
5275 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5276 #if PY_MAJOR_VERSION < 3
5277 ctx = PyString_FromString(name);
5279 ctx = PyUnicode_FromString(name);
5281 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5283 PyErr_WriteUnraisable(Py_None);
5285 PyErr_WriteUnraisable(ctx);
5291 #------------------------------------------------------------------------------------
5293 traceback_utility_code = UtilityCode(
5295 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5298 #include "compile.h"
5299 #include "frameobject.h"
5300 #include "traceback.h"
5302 static void __Pyx_AddTraceback(const char *funcname) {
5303 PyObject *py_srcfile = 0;
5304 PyObject *py_funcname = 0;
5305 PyObject *py_globals = 0;
5306 PyObject *empty_string = 0;
5307 PyCodeObject *py_code = 0;
5308 PyFrameObject *py_frame = 0;
5310 #if PY_MAJOR_VERSION < 3
5311 py_srcfile = PyString_FromString(%(FILENAME)s);
5313 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5315 if (!py_srcfile) goto bad;
5317 #if PY_MAJOR_VERSION < 3
5318 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5320 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5324 #if PY_MAJOR_VERSION < 3
5325 py_funcname = PyString_FromString(funcname);
5327 py_funcname = PyUnicode_FromString(funcname);
5330 if (!py_funcname) goto bad;
5331 py_globals = PyModule_GetDict(%(GLOBALS)s);
5332 if (!py_globals) goto bad;
5333 #if PY_MAJOR_VERSION < 3
5334 empty_string = PyString_FromStringAndSize("", 0);
5336 empty_string = PyBytes_FromStringAndSize("", 0);
5338 if (!empty_string) goto bad;
5339 py_code = PyCode_New(
5340 0, /*int argcount,*/
5341 #if PY_MAJOR_VERSION >= 3
5342 0, /*int kwonlyargcount,*/
5345 0, /*int stacksize,*/
5347 empty_string, /*PyObject *code,*/
5348 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5349 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5350 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5351 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5352 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5353 py_srcfile, /*PyObject *filename,*/
5354 py_funcname, /*PyObject *name,*/
5355 %(LINENO)s, /*int firstlineno,*/
5356 empty_string /*PyObject *lnotab*/
5358 if (!py_code) goto bad;
5359 py_frame = PyFrame_New(
5360 PyThreadState_GET(), /*PyThreadState *tstate,*/
5361 py_code, /*PyCodeObject *code,*/
5362 py_globals, /*PyObject *globals,*/
5363 0 /*PyObject *locals*/
5365 if (!py_frame) goto bad;
5366 py_frame->f_lineno = %(LINENO)s;
5367 PyTraceBack_Here(py_frame);
5369 Py_XDECREF(py_srcfile);
5370 Py_XDECREF(py_funcname);
5371 Py_XDECREF(empty_string);
5372 Py_XDECREF(py_code);
5373 Py_XDECREF(py_frame);
5376 'FILENAME': Naming.filename_cname,
5377 'LINENO': Naming.lineno_cname,
5378 'CFILENAME': Naming.cfilenm_cname,
5379 'CLINENO': Naming.clineno_cname,
5380 'GLOBALS': Naming.module_cname,
5381 'EMPTY_TUPLE' : Naming.empty_tuple,
5384 restore_exception_utility_code = UtilityCode(
5386 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5387 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5390 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5391 PyObject *tmp_type, *tmp_value, *tmp_tb;
5392 PyThreadState *tstate = PyThreadState_GET();
5394 #if PY_MAJOR_VERSION >= 3
5395 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5396 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5397 tmp_type = tstate->exc_type;
5398 tmp_value = tstate->exc_value;
5399 tmp_tb = tstate->exc_traceback;
5400 PyErr_NormalizeException(&type, &value, &tb);
5401 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5402 tstate->exc_type = 0;
5403 tstate->exc_value = 0;
5404 tstate->exc_traceback = 0;
5405 PyException_SetContext(value, tmp_value);
5406 Py_DECREF(tmp_type);
5411 tmp_type = tstate->curexc_type;
5412 tmp_value = tstate->curexc_value;
5413 tmp_tb = tstate->curexc_traceback;
5414 tstate->curexc_type = type;
5415 tstate->curexc_value = value;
5416 tstate->curexc_traceback = tb;
5417 Py_XDECREF(tmp_type);
5418 Py_XDECREF(tmp_value);
5422 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5423 PyThreadState *tstate = PyThreadState_GET();
5424 *type = tstate->curexc_type;
5425 *value = tstate->curexc_value;
5426 *tb = tstate->curexc_traceback;
5428 tstate->curexc_type = 0;
5429 tstate->curexc_value = 0;
5430 tstate->curexc_traceback = 0;
5435 #------------------------------------------------------------------------------------
5437 set_vtable_utility_code = UtilityCode(
5439 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5442 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5443 PyObject *pycobj = 0;
5446 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5449 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5462 #------------------------------------------------------------------------------------
5464 get_vtable_utility_code = UtilityCode(
5466 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5469 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5473 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5476 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5477 if (!*(void **)vtabptr)
5490 #------------------------------------------------------------------------------------
5492 init_string_tab_utility_code = UtilityCode(
5494 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5497 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5499 #if PY_MAJOR_VERSION < 3
5500 if (t->is_unicode && (!t->is_identifier)) {
5501 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5502 } else if (t->intern) {
5503 *t->p = PyString_InternFromString(t->s);
5505 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5507 #else /* Python 3+ has unicode identifiers */
5508 if (t->is_identifier || (t->is_unicode && t->intern)) {
5509 *t->p = PyUnicode_InternFromString(t->s);
5510 } else if (t->is_unicode) {
5511 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5513 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5524 #------------------------------------------------------------------------------------
5526 get_exception_utility_code = UtilityCode(
5528 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5531 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5532 PyObject *tmp_type, *tmp_value, *tmp_tb;
5533 PyThreadState *tstate = PyThreadState_GET();
5534 __Pyx_ErrFetch(type, value, tb);
5535 PyErr_NormalizeException(type, value, tb);
5536 if (PyErr_Occurred())
5541 tmp_type = tstate->exc_type;
5542 tmp_value = tstate->exc_value;
5543 tmp_tb = tstate->exc_traceback;
5544 tstate->exc_type = *type;
5545 tstate->exc_value = *value;
5546 tstate->exc_traceback = *tb;
5547 /* Make sure tstate is in a consistent state when we XDECREF
5548 these objects (XDECREF may run arbitrary code). */
5549 Py_XDECREF(tmp_type);
5550 Py_XDECREF(tmp_value);
5562 #------------------------------------------------------------------------------------
5564 reset_exception_utility_code = UtilityCode(
5566 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5567 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5570 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5571 PyThreadState *tstate = PyThreadState_GET();
5572 *type = tstate->exc_type;
5573 *value = tstate->exc_value;
5574 *tb = tstate->exc_traceback;
5580 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5581 PyObject *tmp_type, *tmp_value, *tmp_tb;
5582 PyThreadState *tstate = PyThreadState_GET();
5583 tmp_type = tstate->exc_type;
5584 tmp_value = tstate->exc_value;
5585 tmp_tb = tstate->exc_traceback;
5586 tstate->exc_type = type;
5587 tstate->exc_value = value;
5588 tstate->exc_traceback = tb;
5589 Py_XDECREF(tmp_type);
5590 Py_XDECREF(tmp_value);
5595 #------------------------------------------------------------------------------------
5597 force_init_threads_utility_code = UtilityCode(
5599 #ifndef __PYX_FORCE_INIT_THREADS
5600 #if PY_VERSION_HEX < 0x02040200
5601 #define __PYX_FORCE_INIT_THREADS 1
5603 #define __PYX_FORCE_INIT_THREADS 0
5608 #------------------------------------------------------------------------------------