2 # Pyrex - Parse tree nodes
5 import sys, os, time, copy
9 from Errors import error, warning, InternalError
13 from PyrexTypes import py_object_type, error_type, CTypedefType, CFuncType
14 from Symtab import ModuleScope, LocalScope, GeneratorLocalScope, \
15 StructOrUnionScope, PyClassScope, CClassScope
16 from Cython.Utils import open_new_file, replace_suffix, UtilityCode
17 from StringEncoding import EncodedString, escape_byte_string, split_docstring
22 absolute_path_length = 0
24 def relative_position(pos):
26 We embed the relative filename in the generated C file, since we
27 don't want to have to regnerate and compile all the source code
28 whenever the Python install directory moves (which could happen,
29 e.g,. when distributing binaries.)
32 a position tuple -- (absolute filename, line number column position)
40 global absolute_path_length
41 if absolute_path_length==0:
42 absolute_path_length = len(os.path.abspath(os.getcwd()))
43 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
45 def embed_position(pos, docstring):
46 if not Options.embed_pos_in_docstring:
48 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
51 return EncodedString(pos_line)
53 # make sure we can encode the filename in the docstring encoding
54 # otherwise make the docstring a unicode string
55 encoding = docstring.encoding
56 if encoding is not None:
58 encoded_bytes = pos_line.encode(encoding)
59 except UnicodeEncodeError:
63 # reuse the string encoding of the original docstring
64 doc = EncodedString(pos_line)
66 doc = EncodedString(pos_line + u'\n' + docstring)
67 doc.encoding = encoding
71 from Code import CCodeWriter
72 from types import FunctionType
74 def write_func_call(func):
76 if len(args) > 1 and isinstance(args[1], CCodeWriter):
77 # here we annotate the code with this function call
78 # but only if new code is generated
80 marker = ' /* %s -> %s.%s %s */' % (
81 ' ' * code.call_level,
82 node.__class__.__name__,
85 pristine = code.buffer.stream.tell()
87 start = code.buffer.stream.tell()
89 res = func(*args, **kwds)
91 if start == code.buffer.stream.tell():
92 code.buffer.stream.seek(pristine)
94 marker = marker.replace('->', '<-')
98 return func(*args, **kwds)
101 class VerboseCodeWriter(type):
102 # Set this as a metaclass to trace function calls in code.
103 # This slows down code generation and makes much larger files.
104 def __new__(cls, name, bases, attrs):
106 for mname, m in attrs.items():
107 if isinstance(m, FunctionType):
108 attrs[mname] = write_func_call(m)
109 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
113 # pos (string, int, int) Source file position
114 # is_name boolean Is a NameNode
115 # is_literal boolean Is a ConstNode
117 if DebugFlags.debug_trace_code_generation:
118 __metaclass__ = VerboseCodeWriter
124 # All descandants should set child_attrs to a list of the attributes
125 # containing nodes considered "children" in the tree. Each such attribute
126 # can either contain a single node or a list of nodes. See Visitor.py.
129 def __init__(self, pos, **kw):
131 self.__dict__.update(kw)
133 gil_message = "Operation"
136 def _gil_check(self, env):
141 error(self.pos, "%s not allowed without gil" % self.gil_message)
143 def clone_node(self):
144 """Clone the node. This is defined as a shallow copy, except for member lists
145 amongst the child attributes (from get_child_accessors) which are also
146 copied. Lists containing child nodes are thus seen as a way for the node
147 to hold multiple children directly; the list is not treated as a seperate
148 level in the tree."""
149 result = copy.copy(self)
150 for attrname in result.child_attrs:
151 value = getattr(result, attrname)
152 if isinstance(value, list):
153 setattr(result, attrname, [x for x in value])
158 # There are 4 phases of parse tree processing, applied in order to
159 # all the statements in a given scope-block:
161 # (0) analyse_control_flow
162 # Create the control flow tree into which state can be asserted and
165 # (1) analyse_declarations
166 # Make symbol table entries for all declarations at the current
167 # level, both explicit (def, cdef, etc.) and implicit (assignment
168 # to an otherwise undeclared name).
170 # (2) analyse_expressions
171 # Determine the result types of expressions and fill in the
172 # 'type' attribute of each ExprNode. Insert coercion nodes into the
173 # tree where needed to convert to and from Python objects.
174 # Allocate temporary locals for intermediate results. Fill
175 # in the 'result_code' attribute of each ExprNode with a C code
179 # Emit C code for all declarations, statements and expressions.
180 # Recursively applies the 3 processing phases to the bodies of
184 def analyse_control_flow(self, env):
187 def analyse_declarations(self, env):
190 def analyse_expressions(self, env):
191 raise InternalError("analyse_expressions not implemented for %s" % \
192 self.__class__.__name__)
194 def generate_code(self, code):
195 raise InternalError("generate_code not implemented for %s" % \
196 self.__class__.__name__)
198 def annotate(self, code):
199 # mro does the wrong thing
200 if isinstance(self, BlockNode):
201 self.body.annotate(code)
206 except AttributeError:
208 if not self.child_attrs:
211 for attr in self.child_attrs:
212 child = getattr(self, attr)
213 # Sometimes lists, sometimes nodes
216 elif isinstance(child, list):
218 pos = max(pos, c.end_pos())
220 pos = max(pos, child.end_pos())
224 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
226 return "<...nesting level cutoff...>"
227 if encountered is None:
229 if id(self) in encountered:
230 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
231 encountered.add(id(self))
233 def dump_child(x, level):
234 if isinstance(x, Node):
235 return x.dump(level, filter_out, cutoff-1, encountered)
236 elif isinstance(x, list):
237 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
242 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
244 return "<%s (%d)>" % (self.__class__.__name__, id(self))
247 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
248 for key, value in attrs:
249 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
250 res += "%s>" % indent
253 class CompilerDirectivesNode(Node):
255 Sets compiler directives for the children nodes
257 # directives {string:value} A dictionary holding the right value for
258 # *all* possible directives.
260 child_attrs = ["body"]
262 def analyse_control_flow(self, env):
264 env.directives = self.directives
265 self.body.analyse_control_flow(env)
268 def analyse_declarations(self, env):
270 env.directives = self.directives
271 self.body.analyse_declarations(env)
274 def analyse_expressions(self, env):
276 env.directives = self.directives
277 self.body.analyse_expressions(env)
280 def generate_function_definitions(self, env, code):
281 env_old = env.directives
282 code_old = code.globalstate.directives
283 code.globalstate.directives = self.directives
284 self.body.generate_function_definitions(env, code)
285 env.directives = env_old
286 code.globalstate.directives = code_old
288 def generate_execution_code(self, code):
289 old = code.globalstate.directives
290 code.globalstate.directives = self.directives
291 self.body.generate_execution_code(code)
292 code.globalstate.directives = old
294 def annotate(self, code):
295 old = code.globalstate.directives
296 code.globalstate.directives = self.directives
297 self.body.annotate(code)
298 code.globalstate.directives = old
300 class BlockNode(object):
301 # Mixin class for nodes representing a declaration block.
303 def generate_cached_builtins_decls(self, env, code):
304 entries = env.global_scope().undeclared_cached_builtins
305 for entry in entries:
306 code.globalstate.add_cached_builtin_decl(entry)
310 class StatListNode(Node):
311 # stats a list of StatNode
313 child_attrs = ["stats"]
315 def create_analysed(pos, env, *args, **kw):
316 node = StatListNode(pos, *args, **kw)
317 return node # No node-specific analysis necesarry
318 create_analysed = staticmethod(create_analysed)
320 def analyse_control_flow(self, env):
321 for stat in self.stats:
322 stat.analyse_control_flow(env)
324 def analyse_declarations(self, env):
325 #print "StatListNode.analyse_declarations" ###
326 for stat in self.stats:
327 stat.analyse_declarations(env)
329 def analyse_expressions(self, env):
330 #print "StatListNode.analyse_expressions" ###
331 for stat in self.stats:
332 stat.analyse_expressions(env)
334 def generate_function_definitions(self, env, code):
335 #print "StatListNode.generate_function_definitions" ###
336 for stat in self.stats:
337 stat.generate_function_definitions(env, code)
339 def generate_execution_code(self, code):
340 #print "StatListNode.generate_execution_code" ###
341 for stat in self.stats:
342 code.mark_pos(stat.pos)
343 stat.generate_execution_code(code)
345 def annotate(self, code):
346 for stat in self.stats:
350 class StatNode(Node):
352 # Code generation for statements is split into the following subphases:
354 # (1) generate_function_definitions
355 # Emit C code for the definitions of any structs,
356 # unions, enums and functions defined in the current
359 # (2) generate_execution_code
360 # Emit C code for executable statements.
363 def generate_function_definitions(self, env, code):
366 def generate_execution_code(self, code):
367 raise InternalError("generate_execution_code not implemented for %s" % \
368 self.__class__.__name__)
371 class CDefExternNode(StatNode):
372 # include_file string or None
375 child_attrs = ["body"]
377 def analyse_declarations(self, env):
378 if self.include_file:
379 env.add_include_file(self.include_file)
380 old_cinclude_flag = env.in_cinclude
382 self.body.analyse_declarations(env)
383 env.in_cinclude = old_cinclude_flag
385 def analyse_expressions(self, env):
388 def generate_execution_code(self, code):
391 def annotate(self, code):
392 self.body.annotate(code)
395 class CDeclaratorNode(Node):
396 # Part of a C declaration.
398 # Processing during analyse_declarations phase:
401 # Returns (name, type) pair where name is the
402 # CNameDeclaratorNode of the name being declared
403 # and type is the type it is being declared as.
405 # calling_convention string Calling convention of CFuncDeclaratorNode
406 # for which this is a base
410 calling_convention = ""
413 class CNameDeclaratorNode(CDeclaratorNode):
414 # name string The Pyrex name being declared
415 # cname string or None C name, if specified
416 # default ExprNode or None the value assigned on declaration
418 child_attrs = ['default']
422 def analyse(self, base_type, env, nonempty = 0):
423 if nonempty and self.name == '':
424 # May have mistaken the name for the type.
425 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
426 error(self.pos, "Missing argument name")
427 elif base_type.is_void:
428 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
430 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
431 base_type = py_object_type
432 self.type = base_type
433 return self, base_type
435 class CPtrDeclaratorNode(CDeclaratorNode):
436 # base CDeclaratorNode
438 child_attrs = ["base"]
440 def analyse(self, base_type, env, nonempty = 0):
441 if base_type.is_pyobject:
443 "Pointer base type cannot be a Python object")
444 ptr_type = PyrexTypes.c_ptr_type(base_type)
445 return self.base.analyse(ptr_type, env, nonempty = nonempty)
447 class CArrayDeclaratorNode(CDeclaratorNode):
448 # base CDeclaratorNode
451 child_attrs = ["base", "dimension"]
453 def analyse(self, base_type, env, nonempty = 0):
455 self.dimension.analyse_const_expression(env)
456 if not self.dimension.type.is_int:
457 error(self.dimension.pos, "Array dimension not integer")
458 size = self.dimension.get_constant_result_code()
466 if not base_type.is_complete():
468 "Array element type '%s' is incomplete" % base_type)
469 if base_type.is_pyobject:
471 "Array element cannot be a Python object")
472 if base_type.is_cfunction:
474 "Array element cannot be a function")
475 array_type = PyrexTypes.c_array_type(base_type, size)
476 return self.base.analyse(array_type, env, nonempty = nonempty)
479 class CFuncDeclaratorNode(CDeclaratorNode):
480 # base CDeclaratorNode
481 # args [CArgDeclNode]
482 # has_varargs boolean
483 # exception_value ConstNode
484 # exception_check boolean True if PyErr_Occurred check needed
485 # nogil boolean Can be called without gil
486 # with_gil boolean Acquire gil around function body
488 child_attrs = ["base", "args", "exception_value"]
491 optional_arg_count = 0
493 def analyse(self, return_type, env, nonempty = 0):
497 for arg_node in self.args:
498 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
499 name = name_declarator.name
500 if name_declarator.cname:
502 "Function argument cannot have C name specification")
503 # Turn *[] argument into **
505 type = PyrexTypes.c_ptr_type(type.base_type)
506 # Catch attempted C-style func(void) decl
508 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
509 func_type_args.append(
510 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
512 self.optional_arg_count += 1
513 elif self.optional_arg_count:
514 error(self.pos, "Non-default argument follows default argument")
516 if self.optional_arg_count:
517 scope = StructOrUnionScope()
518 arg_count_member = '%sn' % Naming.pyrex_prefix
519 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
520 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
521 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
522 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
523 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
528 cname = struct_cname)
529 self.op_args_struct.defined_in_pxd = 1
530 self.op_args_struct.used = 1
534 if self.exception_check == '+':
535 env.add_include_file('stdexcept')
536 if return_type.is_pyobject \
537 and (self.exception_value or self.exception_check) \
538 and self.exception_check != '+':
540 "Exception clause not allowed for function returning Python object")
542 if self.exception_value:
543 self.exception_value.analyse_const_expression(env)
544 exc_val = self.exception_value.get_constant_result_code()
545 if self.exception_check == '+':
546 exc_val_type = self.exception_value.type
547 if not exc_val_type.is_error and \
548 not exc_val_type.is_pyobject and \
549 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
550 error(self.exception_value.pos,
551 "Exception value must be a Python exception or cdef function with no arguments.")
553 if not return_type.assignable_from(self.exception_value.type):
554 error(self.exception_value.pos,
555 "Exception value incompatible with function return type")
556 exc_check = self.exception_check
557 if return_type.is_array:
559 "Function cannot return an array")
560 if return_type.is_cfunction:
562 "Function cannot return a function")
563 func_type = PyrexTypes.CFuncType(
564 return_type, func_type_args, self.has_varargs,
565 optional_arg_count = self.optional_arg_count,
566 exception_value = exc_val, exception_check = exc_check,
567 calling_convention = self.base.calling_convention,
568 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
569 if self.optional_arg_count:
570 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
571 return self.base.analyse(func_type, env)
574 class CArgDeclNode(Node):
575 # Item in a function declaration argument list.
577 # base_type CBaseTypeNode
578 # declarator CDeclaratorNode
579 # not_none boolean Tagged with 'not None'
580 # default ExprNode or None
581 # default_value PyObjectConst constant for default value
582 # is_self_arg boolean Is the "self" arg of an extension type method
583 # is_kw_only boolean Is a keyword-only argument
585 child_attrs = ["base_type", "declarator", "default"]
590 name_declarator = None
593 def analyse(self, env, nonempty = 0):
594 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
595 if self.type is None:
596 # The parser may missinterpret names as types...
598 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
600 self.declarator.name = self.base_type.name
601 self.base_type.name = None
602 self.base_type.is_basic_c_type = False
605 could_be_name = False
606 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
607 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
608 self.declarator.name = self.base_type.arg_name
609 return self.declarator.analyse(base_type, env, nonempty = nonempty)
611 return self.name_declarator, self.type
613 def calculate_default_value_code(self, code):
614 if self.default_value is None:
616 if self.default.is_literal:
617 # will not output any code, just assign the result_code
618 self.default.generate_evaluation_code(code)
619 return self.type.cast_code(self.default.result())
620 self.default_value = code.get_argument_default_const(self.type)
621 return self.default_value
623 def annotate(self, code):
625 self.default.annotate(code)
628 class CBaseTypeNode(Node):
629 # Abstract base class for C base type nodes.
631 # Processing during analyse_declarations phase:
638 class CAnalysedBaseTypeNode(Node):
643 def analyse(self, env, could_be_name = False):
646 class CSimpleBaseTypeNode(CBaseTypeNode):
648 # module_path [string] Qualifying name components
649 # is_basic_c_type boolean
652 # is_self_arg boolean Is self argument of C method
655 arg_name = None # in case the argument name was interpreted as a type
657 def analyse(self, env, could_be_name = False):
658 # Return type descriptor.
659 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
661 if self.is_basic_c_type:
662 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
664 error(self.pos, "Unrecognised type modifier combination")
665 elif self.name == "object" and not self.module_path:
666 type = py_object_type
667 elif self.name is None:
668 if self.is_self_arg and env.is_c_class_scope:
669 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
670 type = env.parent_type
672 type = py_object_type
675 scope = env.find_imported_module(self.module_path, self.pos)
679 if scope.is_c_class_scope:
680 scope = scope.global_scope()
681 entry = scope.lookup(self.name)
682 if entry and entry.is_type:
685 if self.is_self_arg and env.is_c_class_scope:
686 type = env.parent_type
688 type = py_object_type
689 self.arg_name = self.name
691 error(self.pos, "'%s' is not a type identifier" % self.name)
695 return PyrexTypes.error_type
697 class CBufferAccessTypeNode(CBaseTypeNode):
699 # positional_args [ExprNode] List of positional arguments
700 # keyword_args DictNode Keyword arguments
701 # base_type_node CBaseTypeNode
704 # type PyrexType.BufferType ...containing the right options
707 child_attrs = ["base_type_node", "positional_args",
708 "keyword_args", "dtype_node"]
714 def analyse(self, env, could_be_name = False):
715 base_type = self.base_type_node.analyse(env)
716 if base_type.is_error: return base_type
719 options = Buffer.analyse_buffer_options(
722 self.positional_args,
724 base_type.buffer_defaults)
726 self.type = PyrexTypes.BufferType(base_type, **options)
729 class CComplexBaseTypeNode(CBaseTypeNode):
730 # base_type CBaseTypeNode
731 # declarator CDeclaratorNode
733 child_attrs = ["base_type", "declarator"]
735 def analyse(self, env, could_be_name = False):
736 base = self.base_type.analyse(env, could_be_name)
737 _, type = self.declarator.analyse(base, env)
741 class CVarDefNode(StatNode):
742 # C variable definition or forward/extern function declaration.
744 # visibility 'private' or 'public' or 'extern'
745 # base_type CBaseTypeNode
746 # declarators [CDeclaratorNode]
749 # need_properties [entry]
751 # decorators [cython.locals(...)] or None
752 # directive_locals { string : NameNode } locals defined by cython.locals(...)
754 child_attrs = ["base_type", "declarators"]
758 directive_locals = {}
760 def analyse_declarations(self, env, dest_scope = None):
763 self.dest_scope = dest_scope
764 base_type = self.base_type.analyse(env)
765 if (dest_scope.is_c_class_scope
766 and self.visibility == 'public'
767 and base_type.is_pyobject
768 and (base_type.is_builtin_type or base_type.is_extension_type)):
769 self.need_properties = []
771 visibility = 'private'
773 need_property = False
774 visibility = self.visibility
776 for declarator in self.declarators:
777 name_declarator, type = declarator.analyse(base_type, env)
778 if not type.is_complete():
779 if not (self.visibility == 'extern' and type.is_array):
780 error(declarator.pos,
781 "Variable type '%s' is incomplete" % type)
782 if self.visibility == 'extern' and type.is_pyobject:
783 error(declarator.pos,
784 "Python object cannot be declared extern")
785 name = name_declarator.name
786 cname = name_declarator.cname
788 error(declarator.pos, "Missing name in declaration.")
790 if type.is_cfunction:
791 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
792 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
794 if entry is not None:
795 entry.directive_locals = self.directive_locals
797 if self.directive_locals:
798 s.error("Decorators can only be followed by functions")
799 if self.in_pxd and self.visibility != 'extern':
801 "Only 'extern' C variable declaration allowed in .pxd file")
802 entry = dest_scope.declare_var(name, type, declarator.pos,
803 cname = cname, visibility = visibility, is_cdef = 1)
805 self.need_properties.append(entry)
806 entry.needs_property = 1
809 class CStructOrUnionDefNode(StatNode):
811 # cname string or None
812 # kind "struct" or "union"
813 # typedef_flag boolean
814 # visibility "public" or "private"
816 # attributes [CVarDefNode] or None
819 child_attrs = ["attributes"]
821 def analyse_declarations(self, env):
823 if self.attributes is not None:
824 scope = StructOrUnionScope(self.name)
825 self.entry = env.declare_struct_or_union(
826 self.name, self.kind, scope, self.typedef_flag, self.pos,
827 self.cname, visibility = self.visibility)
828 if self.attributes is not None:
829 if self.in_pxd and not env.in_cinclude:
830 self.entry.defined_in_pxd = 1
831 for attr in self.attributes:
832 attr.analyse_declarations(env, scope)
833 if self.visibility != 'extern':
834 need_typedef_indirection = False
835 for attr in scope.var_entries:
838 type = type.base_type
839 if type == self.entry.type:
840 error(attr.pos, "Struct cannot contain itself as a member.")
841 if self.typedef_flag:
843 type = type.base_type
844 if type == self.entry.type:
845 need_typedef_indirection = True
846 if need_typedef_indirection:
847 # C can't handle typedef structs that refer to themselves.
848 struct_entry = self.entry
849 self.entry = env.declare_typedef(
850 self.name, struct_entry.type, self.pos,
851 cname = self.cname, visibility='ignore')
852 struct_entry.type.typedef_flag = False
853 # FIXME: this might be considered a hack ;-)
854 struct_entry.cname = struct_entry.type.cname = '_' + self.cname
856 def analyse_expressions(self, env):
859 def generate_execution_code(self, code):
863 class CEnumDefNode(StatNode):
864 # name string or None
865 # cname string or None
866 # items [CEnumDefItemNode]
867 # typedef_flag boolean
868 # visibility "public" or "private"
872 child_attrs = ["items"]
874 def analyse_declarations(self, env):
875 self.entry = env.declare_enum(self.name, self.pos,
876 cname = self.cname, typedef_flag = self.typedef_flag,
877 visibility = self.visibility)
878 if self.items is not None:
879 if self.in_pxd and not env.in_cinclude:
880 self.entry.defined_in_pxd = 1
881 for item in self.items:
882 item.analyse_declarations(env, self.entry)
884 def generate_execution_code(self, code):
885 if self.visibility == 'public':
886 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
887 for item in self.entry.enum_values:
888 code.putln("%s = PyInt_FromLong(%s); %s" % (
891 code.error_goto_if_null(temp, item.pos)))
892 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
896 code.error_goto(item.pos)))
897 code.putln("%s = 0;" % temp)
898 code.funcstate.release_temp(temp)
901 class CEnumDefItemNode(StatNode):
903 # cname string or None
904 # value ExprNode or None
906 child_attrs = ["value"]
908 def analyse_declarations(self, env, enum_entry):
910 self.value.analyse_const_expression(env)
911 if not self.value.type.is_int:
912 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
913 self.value.analyse_const_expression(env)
914 entry = env.declare_const(self.name, enum_entry.type,
915 self.value, self.pos, cname = self.cname,
916 visibility = enum_entry.visibility)
917 enum_entry.enum_values.append(entry)
920 class CTypeDefNode(StatNode):
921 # base_type CBaseTypeNode
922 # declarator CDeclaratorNode
923 # visibility "public" or "private"
926 child_attrs = ["base_type", "declarator"]
928 def analyse_declarations(self, env):
929 base = self.base_type.analyse(env)
930 name_declarator, type = self.declarator.analyse(base, env)
931 name = name_declarator.name
932 cname = name_declarator.cname
933 entry = env.declare_typedef(name, type, self.pos,
934 cname = cname, visibility = self.visibility)
935 if self.in_pxd and not env.in_cinclude:
936 entry.defined_in_pxd = 1
938 def analyse_expressions(self, env):
940 def generate_execution_code(self, code):
944 class FuncDefNode(StatNode, BlockNode):
945 # Base class for function definition nodes.
947 # return_type PyrexType
948 # #filename string C name of filename string const
950 # needs_closure boolean Whether or not this function has inner functions/classes/yield
951 # directive_locals { string : NameNode } locals defined by cython.locals(...)
955 needs_closure = False
957 def analyse_default_values(self, env):
958 genv = env.global_scope()
959 for arg in self.args:
962 arg.default.analyse_types(env)
963 arg.default = arg.default.coerce_to(arg.type, genv)
966 "This argument cannot have a default value")
969 def need_gil_acquisition(self, lenv):
972 def create_local_scope(self, env):
974 while env.is_py_class_scope or env.is_c_class_scope:
975 env = env.outer_scope
976 if self.needs_closure:
977 lenv = GeneratorLocalScope(name = self.entry.name, outer_scope = genv)
979 lenv = LocalScope(name = self.entry.name, outer_scope = genv)
980 lenv.return_type = self.return_type
981 type = self.entry.type
982 if type.is_cfunction:
983 lenv.nogil = type.nogil and not type.with_gil
984 self.local_scope = lenv
987 def generate_function_definitions(self, env, code):
990 lenv = self.local_scope
992 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
993 self.entry.scope.is_c_class_scope)
995 # Generate C code for header and body of function
996 code.enter_cfunc_scope()
997 code.return_from_error_cleanup_label = code.new_label()
999 # ----- Top-level constants used by this function
1000 code.mark_pos(self.pos)
1001 self.generate_cached_builtins_decls(lenv, code)
1002 # ----- Function header
1005 self.py_func.generate_function_header(code,
1006 with_pymethdef = env.is_py_class_scope,
1008 self.generate_function_header(code,
1009 with_pymethdef = env.is_py_class_scope)
1010 # ----- Local variable declarations
1011 lenv.mangle_closure_cnames(Naming.cur_scope_cname)
1012 self.generate_argument_declarations(lenv, code)
1013 if self.needs_closure:
1014 code.putln("/* TODO: declare and create scope object */")
1015 code.put_var_declarations(lenv.var_entries)
1017 if not self.return_type.is_void:
1018 if self.return_type.is_pyobject:
1022 (self.return_type.declaration_code(
1023 Naming.retval_cname),
1025 tempvardecl_code = code.insertion_point()
1026 self.generate_keyword_list(code)
1027 # ----- Extern library function declarations
1028 lenv.generate_library_function_declarations(code)
1029 # ----- GIL acquisition
1030 acquire_gil = self.need_gil_acquisition(lenv)
1032 env.use_utility_code(force_init_threads_utility_code)
1033 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1034 # ----- Automatic lead-ins for certain special functions
1036 code.put_setup_refcount_context(self.entry.name)
1037 if is_getbuffer_slot:
1038 self.getbuffer_init(code)
1039 # ----- Fetch arguments
1040 self.generate_argument_parsing_code(env, code)
1041 # If an argument is assigned to in the body, we must
1042 # incref it to properly keep track of refcounts.
1043 for entry in lenv.arg_entries:
1044 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1045 code.put_var_incref(entry)
1046 # ----- Initialise local variables
1047 for entry in lenv.var_entries:
1048 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1049 code.put_init_var_to_py_none(entry)
1050 # ----- Initialise local buffer auxiliary variables
1051 for entry in lenv.var_entries + lenv.arg_entries:
1052 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1053 code.putln("%s.buf = NULL;" % entry.buffer_aux.buffer_info_var.cname)
1054 # ----- Check and convert arguments
1055 self.generate_argument_type_tests(code)
1056 # ----- Acquire buffer arguments
1057 for entry in lenv.arg_entries:
1058 if entry.type.is_buffer:
1059 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1060 # ----- Function body
1061 self.body.generate_execution_code(code)
1062 # ----- Default return value
1064 if self.return_type.is_pyobject:
1065 #if self.return_type.is_extension_type:
1066 # lhs = "(PyObject *)%s" % Naming.retval_cname
1068 lhs = Naming.retval_cname
1069 code.put_init_to_py_none(lhs, self.return_type)
1071 val = self.return_type.default_value
1073 code.putln("%s = %s;" % (Naming.retval_cname, val))
1074 # ----- Error cleanup
1075 if code.error_label in code.labels_used:
1076 code.put_goto(code.return_label)
1077 code.put_label(code.error_label)
1078 for cname, type in code.funcstate.all_managed_temps():
1079 code.put_xdecref(cname, type)
1081 # Clean up buffers -- this calls a Python function
1082 # so need to save and restore error state
1083 buffers_present = len(lenv.buffer_entries) > 0
1085 code.globalstate.use_utility_code(restore_exception_utility_code)
1086 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1087 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1088 for entry in lenv.buffer_entries:
1089 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1090 #code.putln("%s = 0;" % entry.cname)
1091 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1093 err_val = self.error_value()
1094 exc_check = self.caller_will_check_exceptions()
1095 if err_val is not None or exc_check:
1096 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1098 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1099 % self.entry.qualified_name, 0)
1101 '__Pyx_WriteUnraisable("%s");' %
1102 self.entry.qualified_name)
1103 env.use_utility_code(unraisable_exception_utility_code)
1104 env.use_utility_code(restore_exception_utility_code)
1105 default_retval = self.return_type.default_value
1106 if err_val is None and default_retval:
1107 err_val = default_retval
1108 if err_val is not None:
1111 Naming.retval_cname,
1114 if is_getbuffer_slot:
1115 self.getbuffer_error_cleanup(code)
1117 # If we are using the non-error cleanup section we should
1118 # jump past it if we have an error. The if-test below determine
1119 # whether this section is used.
1120 if buffers_present or is_getbuffer_slot:
1121 code.put_goto(code.return_from_error_cleanup_label)
1124 # ----- Non-error return cleanup
1125 # If you add anything here, remember to add a condition to the
1126 # if-test above in the error block (so that it can jump past this
1128 code.put_label(code.return_label)
1129 for entry in lenv.buffer_entries:
1131 code.putln("%s;" % Buffer.get_release_buffer_code(entry))
1132 if is_getbuffer_slot:
1133 self.getbuffer_normal_cleanup(code)
1134 # ----- Return cleanup for both error and no-error return
1135 code.put_label(code.return_from_error_cleanup_label)
1136 if not Options.init_local_none:
1137 for entry in lenv.var_entries:
1138 if lenv.control_flow.get_state((entry.name, 'initalized')) is not True:
1139 entry.xdecref_cleanup = 1
1140 code.put_var_decrefs(lenv.var_entries, used_only = 1)
1141 # Decref any increfed args
1142 for entry in lenv.arg_entries:
1143 if entry.type.is_pyobject and lenv.control_flow.get_state((entry.name, 'source')) != 'arg':
1144 code.put_var_decref(entry)
1146 # code.putln("/* TODO: decref scope object */")
1148 # This code is duplicated in ModuleNode.generate_module_init_func
1150 default_retval = self.return_type.default_value
1151 err_val = self.error_value()
1152 if err_val is None and default_retval:
1153 err_val = default_retval
1154 if self.return_type.is_pyobject:
1155 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1157 code.put_finish_refcount_context()
1160 code.putln("PyGILState_Release(_save);")
1162 if not self.return_type.is_void:
1163 code.putln("return %s;" % Naming.retval_cname)
1166 # ----- Go back and insert temp variable declarations
1167 tempvardecl_code.put_temp_declarations(code.funcstate)
1168 # ----- Python version
1169 code.exit_cfunc_scope()
1171 self.py_func.generate_function_definitions(env, code)
1172 self.generate_wrapper_functions(code)
1174 def declare_argument(self, env, arg):
1175 if arg.type.is_void:
1176 error(arg.pos, "Invalid use of 'void'")
1177 elif not arg.type.is_complete() and not arg.type.is_array:
1179 "Argument type '%s' is incomplete" % arg.type)
1180 return env.declare_arg(arg.name, arg.type, arg.pos)
1182 def generate_wrapper_functions(self, code):
1185 def generate_execution_code(self, code):
1186 # Evaluate and store argument default values
1187 for arg in self.args:
1188 default = arg.default
1190 if not default.is_literal:
1191 default.generate_evaluation_code(code)
1192 default.make_owned_reference(code)
1193 result = default.result_as(arg.type)
1196 arg.calculate_default_value_code(code),
1198 if arg.type.is_pyobject:
1199 code.put_giveref(default.result())
1200 default.generate_post_assignment_code(code)
1201 default.free_temps(code)
1202 # For Python class methods, create and store function object
1204 self.assmt.generate_execution_code(code)
1207 # Special code for the __getbuffer__ function
1209 def getbuffer_init(self, code):
1210 info = self.local_scope.arg_entries[1].cname
1211 # Python 3.0 betas have a bug in memoryview which makes it call
1212 # getbuffer with a NULL parameter. For now we work around this;
1213 # the following line should be removed when this bug is fixed.
1214 code.putln("if (%s == NULL) return 0;" % info)
1215 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1216 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1218 def getbuffer_error_cleanup(self, code):
1219 info = self.local_scope.arg_entries[1].cname
1220 code.put_gotref("%s->obj" % info)
1221 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1224 def getbuffer_normal_cleanup(self, code):
1225 info = self.local_scope.arg_entries[1].cname
1226 code.putln("if (%s->obj == Py_None) {" % info)
1227 code.put_gotref("Py_None")
1228 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1231 class CFuncDefNode(FuncDefNode):
1232 # C function definition.
1234 # modifiers ['inline']
1235 # visibility 'private' or 'public' or 'extern'
1236 # base_type CBaseTypeNode
1237 # declarator CDeclaratorNode
1240 # decorators [DecoratorNode] list of decorators
1242 # with_gil boolean Acquire GIL around body
1244 # py_func wrapper for calling from Python
1245 # overridable whether or not this is a cpdef function
1246 # inline_in_pxd whether this is an inline function in a pxd file
1248 child_attrs = ["base_type", "declarator", "body", "py_func"]
1250 inline_in_pxd = False
1252 directive_locals = {}
1254 def unqualified_name(self):
1255 return self.entry.name
1257 def analyse_declarations(self, env):
1258 if 'locals' in env.directives and env.directives['locals']:
1259 self.directive_locals = env.directives['locals']
1260 directive_locals = self.directive_locals
1261 base_type = self.base_type.analyse(env)
1262 # The 2 here is because we need both function and argument names.
1263 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1264 if not type.is_cfunction:
1266 "Suite attached to non-function declaration")
1267 # Remember the actual type according to the function header
1268 # written here, because the type in the symbol table entry
1269 # may be different if we're overriding a C method inherited
1270 # from the base type of an extension type.
1272 type.is_overridable = self.overridable
1273 declarator = self.declarator
1274 while not hasattr(declarator, 'args'):
1275 declarator = declarator.base
1276 self.args = declarator.args
1277 for formal_arg, type_arg in zip(self.args, type.args):
1278 formal_arg.type = type_arg.type
1279 formal_arg.name = type_arg.name
1280 formal_arg.cname = type_arg.cname
1281 name = name_declarator.name
1282 cname = name_declarator.cname
1283 self.entry = env.declare_cfunction(
1284 name, type, self.pos,
1285 cname = cname, visibility = self.visibility,
1286 defining = self.body is not None,
1287 api = self.api, modifiers = self.modifiers)
1288 self.entry.inline_func_in_pxd = self.inline_in_pxd
1289 self.return_type = type.return_type
1291 if self.overridable and not env.is_module_scope:
1292 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1293 # An error will be produced in the cdef function
1294 self.overridable = False
1296 if self.overridable:
1298 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1299 self.py_func = DefNode(pos = self.pos,
1300 name = self.entry.name,
1303 starstar_arg = None,
1305 body = py_func_body,
1307 self.py_func.is_module_scope = env.is_module_scope
1308 self.py_func.analyse_declarations(env)
1309 self.entry.as_variable = self.py_func.entry
1310 # Reset scope entry the above cfunction
1311 env.entries[name] = self.entry
1312 if not env.is_module_scope or Options.lookup_module_cpdef:
1313 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1314 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1316 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1318 args = self.type.args
1319 if omit_optional_args:
1320 args = args[:len(args) - self.type.optional_arg_count]
1321 arg_names = [arg.name for arg in args]
1323 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1325 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1326 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1327 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1328 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)
1329 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1331 def declare_arguments(self, env):
1332 for arg in self.type.args:
1334 error(arg.pos, "Missing argument name")
1335 self.declare_argument(env, arg)
1337 def need_gil_acquisition(self, lenv):
1338 return self.type.with_gil
1340 def gil_check(self, env):
1342 with_gil = type.with_gil
1343 if type.nogil and not with_gil:
1344 if type.return_type.is_pyobject:
1346 "Function with Python return type cannot be declared nogil")
1347 for entry in env.var_entries:
1348 if entry.type.is_pyobject:
1349 error(self.pos, "Function declared nogil has Python locals or temporaries")
1351 def analyse_expressions(self, env):
1352 self.local_scope.directives = env.directives
1353 if self.py_func is not None:
1354 # this will also analyse the default values
1355 self.py_func.analyse_expressions(env)
1357 self.analyse_default_values(env)
1359 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1362 visibility = self.entry.visibility
1363 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1364 arg_decls.append(arg.declaration_code())
1365 if with_dispatch and self.overridable:
1366 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1367 if type.optional_arg_count and with_opt_args:
1368 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1369 if type.has_varargs:
1370 arg_decls.append("...")
1372 arg_decls = ["void"]
1374 cname = self.entry.func_cname
1375 entity = type.function_header_code(cname, ', '.join(arg_decls))
1376 if visibility == 'public':
1377 dll_linkage = "DL_EXPORT"
1380 header = self.return_type.declaration_code(entity,
1381 dll_linkage = dll_linkage)
1382 if visibility == 'extern':
1383 storage_class = "%s " % Naming.extern_c_macro
1384 elif visibility == 'public':
1387 storage_class = "static "
1388 code.putln("%s%s %s {" % (
1390 ' '.join(self.modifiers).upper(), # macro forms
1393 def generate_argument_declarations(self, env, code):
1394 for arg in self.args:
1396 result = arg.calculate_default_value_code(code)
1397 code.putln('%s = %s;' % (
1398 arg.type.declaration_code(arg.cname), result))
1400 def generate_keyword_list(self, code):
1403 def generate_argument_parsing_code(self, env, code):
1405 if self.type.optional_arg_count:
1406 code.putln('if (%s) {' % Naming.optional_args_cname)
1407 for arg in self.args:
1409 # FIXME: simple name prefixing doesn't work when
1410 # argument name mangling is in place
1411 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1412 declarator = arg.declarator
1413 while not hasattr(declarator, 'name'):
1414 declarator = declarator.base
1415 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, declarator.name))
1417 for _ in range(self.type.optional_arg_count):
1421 def generate_argument_conversion_code(self, code):
1424 def generate_argument_type_tests(self, code):
1425 # Generate type tests for args whose type in a parent
1426 # class is a supertype of the declared type.
1427 for arg in self.type.args:
1428 if arg.needs_type_test:
1429 self.generate_arg_type_test(arg, code)
1431 def generate_arg_type_test(self, arg, code):
1432 # Generate type test for one argument.
1433 if arg.type.typeobj_is_available():
1434 typeptr_cname = arg.type.typeptr_cname
1435 arg_code = "((PyObject *)%s)" % arg.cname
1437 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1442 type.is_builtin_type,
1443 code.error_goto(arg.pos)))
1445 error(arg.pos, "Cannot test type of extern C class "
1446 "without type object name specification")
1448 def error_value(self):
1449 if self.return_type.is_pyobject:
1453 return self.entry.type.exception_value
1455 def caller_will_check_exceptions(self):
1456 return self.entry.type.exception_check
1458 def generate_wrapper_functions(self, code):
1459 # If the C signature of a function has changed, we need to generate
1460 # wrappers to put in the slots here.
1463 func_type = entry.type
1464 while entry.prev_entry is not None:
1466 entry = entry.prev_entry
1467 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1469 self.generate_function_header(code,
1471 with_dispatch = entry.type.is_overridable,
1472 with_opt_args = entry.type.optional_arg_count,
1473 cname = entry.func_cname)
1474 if not self.return_type.is_void:
1476 args = self.type.args
1477 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1478 if entry.type.is_overridable:
1479 arglist.append(Naming.skip_dispatch_cname)
1480 elif func_type.is_overridable:
1482 if entry.type.optional_arg_count:
1483 arglist.append(Naming.optional_args_cname)
1484 elif func_type.optional_arg_count:
1485 arglist.append('NULL')
1486 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1490 class PyArgDeclNode(Node):
1491 # Argument which must be a Python object (used
1492 # for * and ** arguments).
1495 # entry Symtab.Entry
1499 class DecoratorNode(Node):
1502 # decorator NameNode or CallNode
1503 child_attrs = ['decorator']
1506 class DefNode(FuncDefNode):
1507 # A Python function definition.
1509 # name string the Python name of the function
1510 # decorators [DecoratorNode] list of decorators
1511 # args [CArgDeclNode] formal arguments
1512 # star_arg PyArgDeclNode or None * argument
1513 # starstar_arg PyArgDeclNode or None ** argument
1514 # doc EncodedString or None
1517 # The following subnode is constructed internally
1518 # when the def statement is inside a Python class definition.
1520 # assmt AssignmentNode Function construction/assignment
1522 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1526 num_required_kw_args = 0
1527 reqd_kw_flags_cname = "0"
1533 def __init__(self, pos, **kwds):
1534 FuncDefNode.__init__(self, pos, **kwds)
1536 for arg in self.args:
1543 self.num_kwonly_args = k
1544 self.num_required_kw_args = rk
1545 self.num_required_args = r
1547 def as_cfunction(self, cfunc=None, scope=None):
1549 error(self.star_arg.pos, "cdef function cannot have star argument")
1550 if self.starstar_arg:
1551 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1554 for formal_arg in self.args:
1555 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1556 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1558 type = py_object_type,
1559 pos = formal_arg.pos))
1560 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1562 has_varargs = False,
1563 exception_value = None,
1564 exception_check = False,
1567 is_overridable = True)
1568 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1570 cfunc_type = cfunc.type
1571 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1572 error(self.pos, "wrong number of arguments")
1573 error(declarator.pos, "previous declaration here")
1574 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1575 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1576 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1577 formal_arg.type = type_arg.type
1578 formal_arg.name_declarator = name_declarator
1580 if cfunc_type.exception_value is None:
1581 exception_value = None
1583 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1584 declarator = CFuncDeclaratorNode(self.pos,
1585 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1587 has_varargs = False,
1588 exception_check = cfunc_type.exception_check,
1589 exception_value = exception_value,
1590 with_gil = cfunc_type.with_gil,
1591 nogil = cfunc_type.nogil)
1592 return CFuncDefNode(self.pos,
1594 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1595 declarator = declarator,
1598 overridable = cfunc_type.is_overridable,
1600 with_gil = cfunc_type.with_gil,
1601 nogil = cfunc_type.nogil,
1602 visibility = 'private',
1604 directive_locals = getattr(cfunc, 'directive_locals', {}))
1606 def analyse_declarations(self, env):
1607 if 'locals' in env.directives:
1608 directive_locals = env.directives['locals']
1610 directive_locals = {}
1611 self.directive_locals = directive_locals
1612 for arg in self.args:
1613 if hasattr(arg, 'name'):
1615 name_declarator = None
1617 base_type = arg.base_type.analyse(env)
1618 name_declarator, type = \
1619 arg.declarator.analyse(base_type, env)
1620 arg.name = name_declarator.name
1621 if arg.name in directive_locals:
1622 type_node = directive_locals[arg.name]
1623 other_type = type_node.analyse_as_type(env)
1624 if other_type is None:
1625 error(type_node.pos, "Not a type")
1626 elif (type is not PyrexTypes.py_object_type
1627 and not type.same_as(other_type)):
1628 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1629 error(type_node.pos, "Previous declaration here")
1632 if name_declarator and name_declarator.cname:
1634 "Python function argument cannot have C name specification")
1635 arg.type = type.as_argument_type()
1637 arg.needs_conversion = 0
1638 arg.needs_type_test = 0
1640 if arg.not_none and not arg.type.is_extension_type:
1642 "Only extension type arguments can have 'not None'")
1643 self.declare_pyfunction(env)
1644 self.analyse_signature(env)
1645 self.return_type = self.entry.signature.return_type()
1647 def analyse_signature(self, env):
1648 any_type_tests_needed = 0
1649 # Use the simpler calling signature for zero- and one-argument functions.
1650 if not self.entry.is_special and not self.star_arg and not self.starstar_arg:
1651 if self.entry.signature is TypeSlots.pyfunction_signature and Options.optimize_simple_methods:
1652 if len(self.args) == 0:
1653 self.entry.signature = TypeSlots.pyfunction_noargs
1654 elif len(self.args) == 1:
1655 if self.args[0].default is None and not self.args[0].kw_only:
1656 self.entry.signature = TypeSlots.pyfunction_onearg
1657 elif self.entry.signature is TypeSlots.pymethod_signature:
1658 if len(self.args) == 1:
1659 self.entry.signature = TypeSlots.unaryfunc
1660 elif len(self.args) == 2:
1661 if self.args[1].default is None and not self.args[1].kw_only:
1662 self.entry.signature = TypeSlots.ibinaryfunc
1663 elif self.entry.is_special:
1664 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
1665 sig = self.entry.signature
1666 nfixed = sig.num_fixed_args()
1667 for i in range(nfixed):
1668 if i < len(self.args):
1671 if sig.is_self_arg(i):
1673 arg.hdr_type = arg.type = env.parent_type
1674 arg.needs_conversion = 0
1676 arg.hdr_type = sig.fixed_arg_type(i)
1677 if not arg.type.same_as(arg.hdr_type):
1678 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
1679 arg.needs_type_test = 1
1680 any_type_tests_needed = 1
1682 arg.needs_conversion = 1
1683 if arg.needs_conversion:
1684 arg.hdr_cname = Naming.arg_prefix + arg.name
1686 arg.hdr_cname = Naming.var_prefix + arg.name
1688 self.bad_signature()
1690 if nfixed < len(self.args):
1691 if not sig.has_generic_args:
1692 self.bad_signature()
1693 for arg in self.args:
1694 if arg.is_generic and \
1695 (arg.type.is_extension_type or arg.type.is_builtin_type):
1696 arg.needs_type_test = 1
1697 any_type_tests_needed = 1
1698 if any_type_tests_needed:
1699 env.use_utility_code(arg_type_test_utility_code)
1701 def bad_signature(self):
1702 sig = self.entry.signature
1703 expected_str = "%d" % sig.num_fixed_args()
1704 if sig.has_generic_args:
1705 expected_str = expected_str + " or more"
1707 if name.startswith("__") and name.endswith("__"):
1708 desc = "Special method"
1712 "%s %s has wrong number of arguments "
1713 "(%d declared, %s expected)" % (
1714 desc, self.name, len(self.args), expected_str))
1716 def signature_has_nongeneric_args(self):
1717 argcount = len(self.args)
1718 if argcount == 0 or (argcount == 1 and self.args[0].is_self_arg):
1722 def signature_has_generic_args(self):
1723 return self.entry.signature.has_generic_args
1725 def declare_pyfunction(self, env):
1726 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
1728 entry = env.lookup_here(self.name)
1729 if entry and entry.type.is_cfunction and not self.is_wrapper:
1730 warning(self.pos, "Overriding cdef method with def method.", 5)
1731 entry = env.declare_pyfunction(self.name, self.pos)
1733 prefix = env.scope_prefix
1734 entry.func_cname = \
1735 Naming.pyfunc_prefix + prefix + name
1736 entry.pymethdef_cname = \
1737 Naming.pymethdef_prefix + prefix + name
1738 if Options.docstrings:
1739 entry.doc = embed_position(self.pos, self.doc)
1741 Naming.funcdoc_prefix + prefix + name
1745 def declare_arguments(self, env):
1746 for arg in self.args:
1748 error(arg.pos, "Missing argument name")
1749 if arg.needs_conversion:
1750 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
1751 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
1752 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1753 if arg.type.is_pyobject:
1754 arg.entry.init = "0"
1755 arg.entry.init_to_none = 0
1757 arg.entry = self.declare_argument(env, arg)
1759 arg.entry.is_self_arg = arg.is_self_arg
1761 if arg.is_self_arg or \
1762 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
1763 arg.entry.is_declared_generic = 1
1764 self.declare_python_arg(env, self.star_arg)
1765 self.declare_python_arg(env, self.starstar_arg)
1767 def declare_python_arg(self, env, arg):
1769 entry = env.declare_var(arg.name,
1770 PyrexTypes.py_object_type, arg.pos)
1773 entry.init_to_none = 0
1774 entry.xdecref_cleanup = 1
1776 env.control_flow.set_state((), (arg.name, 'initalized'), True)
1778 def analyse_expressions(self, env):
1779 self.local_scope.directives = env.directives
1780 self.analyse_default_values(env)
1781 if env.is_py_class_scope:
1782 self.synthesize_assignment_node(env)
1784 def synthesize_assignment_node(self, env):
1786 self.assmt = SingleAssignmentNode(self.pos,
1787 lhs = ExprNodes.NameNode(self.pos, name = self.name),
1788 rhs = ExprNodes.UnboundMethodNode(self.pos,
1789 function = ExprNodes.PyCFunctionNode(self.pos,
1790 pymethdef_cname = self.entry.pymethdef_cname)))
1791 self.assmt.analyse_declarations(env)
1792 self.assmt.analyse_expressions(env)
1794 def generate_function_header(self, code, with_pymethdef, proto_only=0):
1796 sig = self.entry.signature
1797 if sig.has_dummy_arg:
1798 arg_code_list.append(
1799 "PyObject *%s" % Naming.self_cname)
1800 for arg in self.args:
1801 if not arg.is_generic:
1803 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
1805 arg_code_list.append(
1806 arg.hdr_type.declaration_code(arg.hdr_cname))
1807 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
1808 arg_code_list.append("PyObject *unused")
1809 if sig.has_generic_args:
1810 arg_code_list.append(
1811 "PyObject *%s, PyObject *%s"
1812 % (Naming.args_cname, Naming.kwds_cname))
1813 arg_code = ", ".join(arg_code_list)
1814 dc = self.return_type.declaration_code(self.entry.func_cname)
1815 header = "static %s(%s)" % (dc, arg_code)
1816 code.putln("%s; /*proto*/" % header)
1819 if self.entry.doc and Options.docstrings:
1820 docstr = self.entry.doc
1821 if not isinstance(docstr, str):
1822 docstr = docstr.utf8encode()
1824 'static char %s[] = "%s";' % (
1825 self.entry.doc_cname,
1826 split_docstring(escape_byte_string(docstr))))
1829 "static PyMethodDef %s = " %
1830 self.entry.pymethdef_cname)
1831 code.put_pymethoddef(self.entry, ";")
1832 code.putln("%s {" % header)
1834 def generate_argument_declarations(self, env, code):
1835 for arg in self.args:
1836 if arg.is_generic: # or arg.needs_conversion:
1837 if arg.needs_conversion:
1838 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
1840 code.put_var_declaration(arg.entry)
1842 def generate_keyword_list(self, code):
1843 if self.signature_has_generic_args() and \
1844 self.signature_has_nongeneric_args():
1846 "static PyObject **%s[] = {" %
1847 Naming.pykwdlist_cname)
1848 for arg in self.args:
1850 pystring_cname = code.intern_identifier(arg.name)
1851 code.put('&%s,' % pystring_cname)
1854 def generate_argument_parsing_code(self, env, code):
1855 # Generate PyArg_ParseTuple call for generic
1856 # arguments, if any.
1857 if self.entry.signature.has_dummy_arg:
1858 # get rid of unused argument warning
1859 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
1861 old_error_label = code.new_error_label()
1862 our_error_label = code.error_label
1863 end_label = code.new_label("argument_unpacking_done")
1865 has_kwonly_args = self.num_kwonly_args > 0
1866 has_star_or_kw_args = self.star_arg is not None \
1867 or self.starstar_arg is not None or has_kwonly_args
1869 if not self.signature_has_generic_args():
1870 if has_star_or_kw_args:
1871 error(self.pos, "This method cannot have * or keyword arguments")
1872 self.generate_argument_conversion_code(code)
1874 elif not self.signature_has_nongeneric_args():
1875 # func(*args) or func(**kw) or func(*args, **kw)
1876 self.generate_stararg_copy_code(code)
1879 positional_args = []
1882 for arg in self.args:
1883 arg_entry = arg.entry
1887 if not arg.is_self_arg:
1889 kw_only_args.append(arg)
1891 positional_args.append(arg)
1893 kw_only_args.append(arg)
1896 error(arg.pos, "Non-default argument following default argument")
1897 elif not arg.is_self_arg:
1898 positional_args.append(arg)
1900 self.generate_tuple_and_keyword_parsing_code(
1901 positional_args, kw_only_args, end_label, code)
1903 code.error_label = old_error_label
1904 if code.label_used(our_error_label):
1905 if not code.label_used(end_label):
1906 code.put_goto(end_label)
1907 code.put_label(our_error_label)
1908 if has_star_or_kw_args:
1909 self.generate_arg_decref(self.star_arg, code)
1910 if self.starstar_arg:
1911 if self.starstar_arg.entry.xdecref_cleanup:
1912 code.put_var_xdecref(self.starstar_arg.entry)
1914 code.put_var_decref(self.starstar_arg.entry)
1915 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1916 code.putln("return %s;" % self.error_value())
1917 if code.label_used(end_label):
1918 code.put_label(end_label)
1920 def generate_arg_assignment(self, arg, item, code):
1921 if arg.type.is_pyobject:
1923 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
1924 code.putln("%s = %s;" % (arg.entry.cname, item))
1926 func = arg.type.from_py_function
1928 code.putln("%s = %s(%s); %s" % (
1932 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
1934 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
1936 def generate_arg_xdecref(self, arg, code):
1938 code.put_var_xdecref(arg.entry)
1940 def generate_arg_decref(self, arg, code):
1942 code.put_var_decref(arg.entry)
1944 def generate_stararg_copy_code(self, code):
1945 if not self.star_arg:
1946 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1947 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
1949 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
1950 self.name.utf8encode(), Naming.args_cname, self.error_value()))
1953 code.globalstate.use_utility_code(keyword_string_check_utility_code)
1955 if self.starstar_arg:
1957 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
1959 kwarg_check = "%s" % Naming.kwds_cname
1961 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
1962 Naming.kwds_cname, Naming.kwds_cname)
1964 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
1965 kwarg_check, Naming.kwds_cname, self.name,
1966 bool(self.starstar_arg), self.error_value()))
1968 if self.starstar_arg:
1969 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
1970 self.starstar_arg.entry.cname,
1973 code.putln("if (unlikely(!%s)) return %s;" % (
1974 self.starstar_arg.entry.cname, self.error_value()))
1975 self.starstar_arg.entry.xdecref_cleanup = 0
1976 code.put_gotref(self.starstar_arg.entry.cname)
1980 code.put_incref(Naming.args_cname, py_object_type)
1981 code.putln("%s = %s;" % (
1982 self.star_arg.entry.cname,
1984 self.star_arg.entry.xdecref_cleanup = 0
1986 def generate_tuple_and_keyword_parsing_code(self, positional_args,
1987 kw_only_args, success_label, code):
1988 argtuple_error_label = code.new_label("argtuple_error")
1990 min_positional_args = self.num_required_args - self.num_required_kw_args
1991 if len(self.args) > 0 and self.args[0].is_self_arg:
1992 min_positional_args -= 1
1993 max_positional_args = len(positional_args)
1994 has_fixed_positional_count = not self.star_arg and \
1995 min_positional_args == max_positional_args
1997 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
1998 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
1999 if self.num_required_kw_args:
2000 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2002 if self.starstar_arg or self.star_arg:
2003 self.generate_stararg_init_code(max_positional_args, code)
2005 # --- optimised code when we receive keyword arguments
2006 if self.num_required_kw_args:
2007 likely_hint = "likely"
2009 likely_hint = "unlikely"
2010 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2011 self.generate_keyword_unpacking_code(
2012 min_positional_args, max_positional_args,
2013 has_fixed_positional_count,
2014 positional_args, kw_only_args, argtuple_error_label, code)
2016 # --- optimised code when we do not receive any keyword arguments
2017 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2018 # Python raises arg tuple related errors first, so we must
2019 # check the length here
2020 if min_positional_args == max_positional_args and not self.star_arg:
2024 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2025 Naming.args_cname, compare, min_positional_args))
2026 code.put_goto(argtuple_error_label)
2028 if self.num_required_kw_args:
2029 # pure error case: keywords required but not passed
2030 if max_positional_args > min_positional_args and not self.star_arg:
2031 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2032 Naming.args_cname, max_positional_args))
2033 code.put_goto(argtuple_error_label)
2034 code.putln('} else {')
2035 for i, arg in enumerate(kw_only_args):
2037 pystring_cname = code.intern_identifier(arg.name)
2038 # required keyword-only argument missing
2039 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2040 self.name.utf8encode(),
2042 code.putln(code.error_goto(self.pos))
2045 elif min_positional_args == max_positional_args:
2046 # parse the exact number of positional arguments from the
2048 code.putln('} else {')
2049 for i, arg in enumerate(positional_args):
2050 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2051 self.generate_arg_assignment(arg, item, code)
2052 self.generate_arg_default_assignments(code)
2055 # parse the positional arguments from the variable length
2057 code.putln('} else {')
2058 self.generate_arg_default_assignments(code)
2059 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2061 code.putln('default:')
2062 reversed_args = list(enumerate(positional_args))[::-1]
2063 for i, arg in reversed_args:
2064 if i >= min_positional_args-1:
2065 if min_positional_args > 1:
2066 code.putln('case %2d:' % (i+1)) # pure code beautification
2068 code.put('case %2d: ' % (i+1))
2069 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2070 self.generate_arg_assignment(arg, item, code)
2071 if min_positional_args == 0:
2072 code.put('case 0: ')
2073 code.putln('break;')
2075 if min_positional_args:
2076 for i in range(min_positional_args-1, -1, -1):
2077 code.putln('case %2d:' % i)
2078 code.put_goto(argtuple_error_label)
2080 code.put('default: ')
2081 code.put_goto(argtuple_error_label)
2086 if code.label_used(argtuple_error_label):
2087 code.put_goto(success_label)
2088 code.put_label(argtuple_error_label)
2089 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2090 self.name.utf8encode(), has_fixed_positional_count,
2091 min_positional_args, max_positional_args,
2093 code.putln(code.error_goto(self.pos))
2095 def generate_arg_default_assignments(self, code):
2096 for arg in self.args:
2097 if arg.is_generic and arg.default:
2101 arg.calculate_default_value_code(code)))
2103 def generate_stararg_init_code(self, max_positional_args, code):
2104 if self.starstar_arg:
2105 self.starstar_arg.entry.xdecref_cleanup = 0
2106 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2107 self.starstar_arg.entry.cname,
2108 self.starstar_arg.entry.cname,
2109 self.error_value()))
2110 code.put_gotref(self.starstar_arg.entry.cname)
2112 self.star_arg.entry.xdecref_cleanup = 0
2113 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2115 max_positional_args))
2116 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2117 self.star_arg.entry.cname, Naming.args_cname,
2118 max_positional_args, Naming.args_cname))
2119 code.put_gotref(self.star_arg.entry.cname)
2120 if self.starstar_arg:
2122 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2123 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2124 code.putln('return %s;' % self.error_value())
2127 code.putln("if (unlikely(!%s)) return %s;" % (
2128 self.star_arg.entry.cname, self.error_value()))
2129 code.putln('} else {')
2130 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2131 code.put_incref(Naming.empty_tuple, py_object_type)
2134 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2135 has_fixed_positional_count, positional_args,
2136 kw_only_args, argtuple_error_label, code):
2137 all_args = tuple(positional_args) + tuple(kw_only_args)
2138 max_args = len(all_args)
2141 for i, arg in enumerate(all_args):
2142 if arg.default and arg.type.is_pyobject:
2143 default_value = arg.calculate_default_value_code(code)
2144 if arg.type is not PyrexTypes.py_object_type:
2145 default_value = "(PyObject*)"+default_value
2146 default_args.append((i, default_value))
2148 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2150 # it looks funny to separate the init-to-0 from setting the
2151 # default value, but C89 needs this
2152 code.putln("PyObject* values[%d] = {%s};" % (
2153 max_args, ','.join(['0']*max_args)))
2154 for i, default_value in default_args:
2155 code.putln('values[%d] = %s;' % (i, default_value))
2157 # parse the tuple and check that it's not too long
2158 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2160 code.putln('default:')
2161 for i in range(max_positional_args-1, -1, -1):
2162 code.put('case %2d: ' % (i+1))
2163 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2164 i, Naming.args_cname, i))
2165 code.putln('case 0: break;')
2166 if not self.star_arg:
2167 code.put('default: ') # more arguments than allowed
2168 code.put_goto(argtuple_error_label)
2171 # now fill up the positional/required arguments with values
2173 if self.num_required_args or max_positional_args > 0:
2174 last_required_arg = -1
2175 for i, arg in enumerate(all_args):
2177 last_required_arg = i
2178 if last_required_arg < max_positional_args:
2179 last_required_arg = max_positional_args-1
2180 num_required_args = self.num_required_args
2181 if max_positional_args > 0:
2182 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2183 for i, arg in enumerate(all_args[:last_required_arg+1]):
2184 if max_positional_args > 0 and i <= max_positional_args:
2185 if self.star_arg and i == max_positional_args:
2186 code.putln('default:')
2188 code.putln('case %2d:' % i)
2189 pystring_cname = code.intern_identifier(arg.name)
2192 # handled separately below
2194 code.putln('if (kw_args > %d) {' % num_required_args)
2195 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2196 Naming.kwds_cname, pystring_cname))
2197 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2200 num_required_args -= 1
2201 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2202 i, Naming.kwds_cname, pystring_cname))
2203 code.putln('if (likely(values[%d])) kw_args--;' % i);
2204 if i < min_positional_args:
2206 # special case: we know arg 0 is missing
2208 code.put_goto(argtuple_error_label)
2210 # print the correct number of values (args or
2211 # kwargs) that were passed into positional
2212 # arguments up to this point
2213 code.putln('else {')
2214 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2215 self.name.utf8encode(), has_fixed_positional_count,
2216 min_positional_args, max_positional_args, i))
2217 code.putln(code.error_goto(self.pos))
2220 code.putln('else {')
2221 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2222 self.name.utf8encode(), pystring_cname))
2223 code.putln(code.error_goto(self.pos))
2225 if max_positional_args > 0:
2228 if kw_only_args and not self.starstar_arg:
2229 # unpack optional keyword-only arguments
2230 # checking for interned strings in a dict is faster than iterating
2231 # but it's too likely that we must iterate if we expect **kwargs
2233 for i, arg in enumerate(all_args[max_positional_args:]):
2234 if not arg.kw_only or not arg.default:
2236 optional_args.append((i+max_positional_args, arg))
2238 # this mimics an unrolled loop so that we can "break" out of it
2239 code.putln('while (kw_args > 0) {')
2240 code.putln('PyObject* value;')
2241 for i, arg in optional_args:
2242 pystring_cname = code.intern_identifier(arg.name)
2244 'value = PyDict_GetItem(%s, %s);' % (
2245 Naming.kwds_cname, pystring_cname))
2247 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2248 code.putln('break;')
2251 code.putln('if (unlikely(kw_args > 0)) {')
2252 # non-positional/-required kw args left in dict: default args,
2253 # kw-only args, **kwargs or error
2255 # This is sort of a catch-all: except for checking required
2256 # arguments, this will always do the right thing for unpacking
2257 # keyword arguments, so that we can concentrate on optimising
2258 # common cases above.
2259 if max_positional_args == 0:
2262 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2263 Naming.args_cname, max_positional_args,
2264 Naming.args_cname, max_positional_args))
2265 pos_arg_count = "used_pos_args"
2267 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2268 code.globalstate.use_utility_code(parse_keywords_utility_code)
2270 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2272 Naming.pykwdlist_cname,
2273 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2275 self.name.utf8encode()))
2276 code.putln(code.error_goto(self.pos))
2279 # convert arg values to their final type and assign them
2280 for i, arg in enumerate(all_args):
2281 if arg.default and not arg.type.is_pyobject:
2282 code.putln("if (values[%d]) {" % i)
2283 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2284 if arg.default and not arg.type.is_pyobject:
2285 code.putln('} else {')
2289 arg.calculate_default_value_code(code)))
2292 def generate_argument_conversion_code(self, code):
2293 # Generate code to convert arguments from
2294 # signature type to declared type, if needed.
2295 for arg in self.args:
2296 if arg.needs_conversion:
2297 self.generate_arg_conversion(arg, code)
2299 def generate_arg_conversion(self, arg, code):
2300 # Generate conversion code for one argument.
2301 old_type = arg.hdr_type
2303 if old_type.is_pyobject:
2305 code.putln("if (%s) {" % arg.hdr_cname)
2307 code.putln("assert(%s); {" % arg.hdr_cname)
2308 self.generate_arg_conversion_from_pyobject(arg, code)
2310 elif new_type.is_pyobject:
2311 self.generate_arg_conversion_to_pyobject(arg, code)
2313 if new_type.assignable_from(old_type):
2315 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2318 "Cannot convert 1 argument from '%s' to '%s'" %
2319 (old_type, new_type))
2321 def generate_arg_conversion_from_pyobject(self, arg, code):
2323 func = new_type.from_py_function
2324 # copied from CoerceFromPyTypeNode
2326 code.putln("%s = %s(%s); %s" % (
2330 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2333 "Cannot convert Python object argument to type '%s'"
2336 def generate_arg_conversion_to_pyobject(self, arg, code):
2337 old_type = arg.hdr_type
2338 func = old_type.to_py_function
2340 code.putln("%s = %s(%s); %s" % (
2344 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2345 code.put_var_gotref(arg.entry)
2348 "Cannot convert argument of type '%s' to Python object"
2351 def generate_argument_type_tests(self, code):
2352 # Generate type tests for args whose signature
2353 # type is PyObject * and whose declared type is
2354 # a subtype thereof.
2355 for arg in self.args:
2356 if arg.needs_type_test:
2357 self.generate_arg_type_test(arg, code)
2359 def generate_arg_type_test(self, arg, code):
2360 # Generate type test for one argument.
2361 if arg.type.typeobj_is_available():
2362 typeptr_cname = arg.type.typeptr_cname
2363 arg_code = "((PyObject *)%s)" % arg.entry.cname
2365 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
2370 arg.type.is_builtin_type,
2371 code.error_goto(arg.pos)))
2373 error(arg.pos, "Cannot test type of extern C class "
2374 "without type object name specification")
2376 def error_value(self):
2377 return self.entry.signature.error_value
2379 def caller_will_check_exceptions(self):
2382 class OverrideCheckNode(StatNode):
2383 # A Node for dispatching to the def method if it
2392 child_attrs = ['body']
2396 def analyse_expressions(self, env):
2397 self.args = env.arg_entries
2398 if self.py_func.is_module_scope:
2403 self.func_node = ExprNodes.PyTempNode(self.pos, env)
2404 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2405 call_node = ExprNodes.SimpleCallNode(self.pos,
2406 function=self.func_node,
2407 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2408 self.body = ReturnStatNode(self.pos, value=call_node)
2409 self.body.analyse_expressions(env)
2411 def generate_execution_code(self, code):
2412 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2413 # Check to see if we are an extension type
2414 if self.py_func.is_module_scope:
2415 self_arg = "((PyObject *)%s)" % Naming.module_cname
2417 self_arg = "((PyObject *)%s)" % self.args[0].cname
2418 code.putln("/* Check if called by wrapper */")
2419 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2420 code.putln("/* Check if overriden in Python */")
2421 if self.py_func.is_module_scope:
2422 code.putln("else {")
2424 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2425 self.func_node.allocate(code)
2426 err = code.error_goto_if_null(self.func_node.result(), self.pos)
2427 # need to get attribute manually--scope would return cdef method
2428 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2429 self.func_node.result(), self_arg, interned_attr_cname, err))
2430 code.put_gotref(self.func_node.py_result())
2431 is_builtin_function_or_method = 'PyCFunction_Check(%s)' % self.func_node.result()
2432 is_overridden = '(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)' % (
2433 self.func_node.result(), self.py_func.entry.func_cname)
2434 code.putln('if (!%s || %s) {' % (is_builtin_function_or_method, is_overridden))
2435 self.body.generate_execution_code(code)
2437 code.put_decref_clear(self.func_node.result(), PyrexTypes.py_object_type)
2439 self.func_node.release(code)
2441 class ClassDefNode(StatNode, BlockNode):
2444 class PyClassDefNode(ClassDefNode):
2445 # A Python class definition.
2447 # name EncodedString Name of the class
2448 # doc string or None
2449 # body StatNode Attribute definition code
2450 # entry Symtab.Entry
2451 # scope PyClassScope
2453 # The following subnodes are constructed internally:
2455 # dict DictNode Class dictionary
2456 # classobj ClassNode Class object
2457 # target NameNode Variable to assign class object to
2459 child_attrs = ["body", "dict", "classobj", "target"]
2461 def __init__(self, pos, name, bases, doc, body):
2462 StatNode.__init__(self, pos)
2467 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2468 if self.doc and Options.docstrings:
2469 doc = embed_position(self.pos, self.doc)
2470 doc_node = ExprNodes.StringNode(pos, value = doc)
2473 self.classobj = ExprNodes.ClassNode(pos, name = name,
2474 bases = bases, dict = self.dict, doc = doc_node)
2475 self.target = ExprNodes.NameNode(pos, name = name)
2477 def as_cclass(self):
2479 Return this node as if it were declared as an extension class
2481 bases = self.classobj.bases.args
2483 base_class_name = None
2484 base_class_module = None
2485 elif len(bases) == 1:
2488 from ExprNodes import AttributeNode, NameNode
2489 while isinstance(base, AttributeNode):
2490 path.insert(0, base.attribute)
2492 if isinstance(base, NameNode):
2493 path.insert(0, base.name)
2494 base_class_name = path[-1]
2496 base_class_module = u'.'.join(path[:-1])
2498 base_class_module = None
2500 error(self.classobj.bases.args.pos, "Invalid base class")
2502 error(self.classobj.bases.args.pos, "C class may only have one base class")
2505 return CClassDefNode(self.pos,
2506 visibility = 'private',
2508 class_name = self.name,
2509 base_class_module = base_class_module,
2510 base_class_name = base_class_name,
2515 def create_scope(self, env):
2517 while env.is_py_class_scope or env.is_c_class_scope:
2518 env = env.outer_scope
2519 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2522 def analyse_declarations(self, env):
2523 self.target.analyse_target_declaration(env)
2524 cenv = self.create_scope(env)
2525 cenv.class_obj_cname = self.target.entry.cname
2526 self.body.analyse_declarations(cenv)
2528 def analyse_expressions(self, env):
2529 self.dict.analyse_expressions(env)
2530 self.classobj.analyse_expressions(env)
2531 genv = env.global_scope()
2533 self.body.analyse_expressions(cenv)
2534 self.target.analyse_target_expression(env, self.classobj)
2536 def generate_function_definitions(self, env, code):
2537 self.body.generate_function_definitions(self.scope, code)
2539 def generate_execution_code(self, code):
2540 code.pyclass_stack.append(self)
2542 self.dict.generate_evaluation_code(code)
2543 self.classobj.generate_evaluation_code(code)
2544 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2545 self.body.generate_execution_code(code)
2546 self.target.generate_assignment_code(self.classobj, code)
2547 self.dict.generate_disposal_code(code)
2548 self.dict.free_temps(code)
2549 code.pyclass_stack.pop()
2552 class CClassDefNode(ClassDefNode):
2553 # An extension type definition.
2555 # visibility 'private' or 'public' or 'extern'
2556 # typedef_flag boolean
2558 # module_name string or None For import of extern type objects
2559 # class_name string Unqualified name of class
2560 # as_name string or None Name to declare as in this scope
2561 # base_class_module string or None Module containing the base class
2562 # base_class_name string or None Name of the base class
2563 # objstruct_name string or None Specified C name of object struct
2564 # typeobj_name string or None Specified C name of type object
2565 # in_pxd boolean Is in a .pxd file
2566 # doc string or None
2567 # body StatNode or None
2568 # entry Symtab.Entry
2569 # base_type PyExtensionType or None
2570 # buffer_defaults_node DictNode or None Declares defaults for a buffer
2571 # buffer_defaults_pos
2573 child_attrs = ["body"]
2574 buffer_defaults_node = None
2575 buffer_defaults_pos = None
2576 typedef_flag = False
2578 objstruct_name = None
2581 def analyse_declarations(self, env):
2582 #print "CClassDefNode.analyse_declarations:", self.class_name
2583 #print "...visibility =", self.visibility
2584 #print "...module_name =", self.module_name
2587 if self.buffer_defaults_node:
2588 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
2589 env, [], self.buffer_defaults_node,
2590 need_complete=False)
2592 buffer_defaults = None
2594 if env.in_cinclude and not self.objstruct_name:
2595 error(self.pos, "Object struct name specification required for "
2596 "C class defined in 'extern from' block")
2597 self.base_type = None
2598 # Now that module imports are cached, we need to
2599 # import the modules for extern classes.
2600 if self.module_name:
2602 for module in env.cimported_modules:
2603 if module.name == self.module_name:
2604 self.module = module
2605 if self.module is None:
2606 self.module = ModuleScope(self.module_name, None, env.context)
2607 self.module.has_extern_class = 1
2608 env.add_imported_module(self.module)
2610 if self.base_class_name:
2611 if self.base_class_module:
2612 base_class_scope = env.find_module(self.base_class_module, self.pos)
2614 base_class_scope = env
2615 if self.base_class_name == 'object':
2616 # extension classes are special and don't need to inherit from object
2617 if base_class_scope is None or base_class_scope.lookup('object') is None:
2618 self.base_class_name = None
2619 self.base_class_module = None
2620 base_class_scope = None
2621 if base_class_scope:
2622 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
2623 if base_class_entry:
2624 if not base_class_entry.is_type:
2625 error(self.pos, "'%s' is not a type name" % self.base_class_name)
2626 elif not base_class_entry.type.is_extension_type:
2627 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
2628 elif not base_class_entry.type.is_complete():
2629 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
2631 self.base_type = base_class_entry.type
2632 has_body = self.body is not None
2633 if self.module_name and self.visibility != 'extern':
2634 module_path = self.module_name.split(".")
2635 home_scope = env.find_imported_module(module_path, self.pos)
2641 if self.visibility == 'extern':
2642 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
2643 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
2645 self.entry = home_scope.declare_c_class(
2646 name = self.class_name,
2648 defining = has_body and self.in_pxd,
2649 implementing = has_body and not self.in_pxd,
2650 module_name = self.module_name,
2651 base_type = self.base_type,
2652 objstruct_cname = self.objstruct_name,
2653 typeobj_cname = self.typeobj_name,
2654 visibility = self.visibility,
2655 typedef_flag = self.typedef_flag,
2657 buffer_defaults = buffer_defaults)
2658 if home_scope is not env and self.visibility == 'extern':
2659 env.add_imported_entry(self.class_name, self.entry, pos)
2660 scope = self.entry.type.scope
2662 if self.doc and Options.docstrings:
2663 scope.doc = embed_position(self.pos, self.doc)
2666 self.body.analyse_declarations(scope)
2670 scope.implemented = 1
2671 env.allocate_vtable_names(self.entry)
2673 def analyse_expressions(self, env):
2675 scope = self.entry.type.scope
2676 self.body.analyse_expressions(scope)
2678 def generate_function_definitions(self, env, code):
2680 self.body.generate_function_definitions(
2681 self.entry.type.scope, code)
2683 def generate_execution_code(self, code):
2684 # This is needed to generate evaluation code for
2685 # default values of method arguments.
2687 self.body.generate_execution_code(code)
2689 def annotate(self, code):
2691 self.body.annotate(code)
2694 class PropertyNode(StatNode):
2695 # Definition of a property in an extension type.
2698 # doc EncodedString or None Doc string
2701 child_attrs = ["body"]
2703 def analyse_declarations(self, env):
2704 entry = env.declare_property(self.name, self.doc, self.pos)
2706 self.body.analyse_declarations(entry.scope)
2708 def analyse_expressions(self, env):
2709 self.body.analyse_expressions(env)
2711 def generate_function_definitions(self, env, code):
2712 self.body.generate_function_definitions(env, code)
2714 def generate_execution_code(self, code):
2717 def annotate(self, code):
2718 self.body.annotate(code)
2721 class GlobalNode(StatNode):
2722 # Global variable declaration.
2728 def analyse_declarations(self, env):
2729 for name in self.names:
2730 env.declare_global(name, self.pos)
2732 def analyse_expressions(self, env):
2735 def generate_execution_code(self, code):
2739 class ExprStatNode(StatNode):
2740 # Expression used as a statement.
2744 child_attrs = ["expr"]
2746 def analyse_declarations(self, env):
2748 if isinstance(self.expr, ExprNodes.GeneralCallNode):
2749 func = self.expr.function.as_cython_attribute()
2750 if func == u'declare':
2751 args, kwds = self.expr.explicit_args_kwds()
2753 error(self.expr.pos, "Variable names must be specified.")
2754 for var, type_node in kwds.key_value_pairs:
2755 type = type_node.analyse_as_type(env)
2757 error(type_node.pos, "Unknown type")
2759 env.declare_var(var.value, type, var.pos, is_cdef = True)
2760 self.__class__ = PassStatNode
2762 def analyse_expressions(self, env):
2763 self.expr.analyse_expressions(env)
2765 def generate_execution_code(self, code):
2766 self.expr.generate_evaluation_code(code)
2767 if not self.expr.is_temp and self.expr.result():
2768 code.putln("%s;" % self.expr.result())
2769 self.expr.generate_disposal_code(code)
2770 self.expr.free_temps(code)
2772 def annotate(self, code):
2773 self.expr.annotate(code)
2776 class AssignmentNode(StatNode):
2777 # Abstract base class for assignment nodes.
2779 # The analyse_expressions and generate_execution_code
2780 # phases of assignments are split into two sub-phases
2781 # each, to enable all the right hand sides of a
2782 # parallel assignment to be evaluated before assigning
2783 # to any of the left hand sides.
2785 def analyse_expressions(self, env):
2786 self.analyse_types(env)
2788 # def analyse_expressions(self, env):
2789 # self.analyse_expressions_1(env)
2790 # self.analyse_expressions_2(env)
2792 def generate_execution_code(self, code):
2793 self.generate_rhs_evaluation_code(code)
2794 self.generate_assignment_code(code)
2797 class SingleAssignmentNode(AssignmentNode):
2798 # The simplest case:
2802 # lhs ExprNode Left hand side
2803 # rhs ExprNode Right hand side
2804 # first bool Is this guaranteed the first assignment to lhs?
2806 child_attrs = ["lhs", "rhs"]
2808 declaration_only = False
2810 def analyse_declarations(self, env):
2813 # handle declarations of the form x = cython.foo()
2814 if isinstance(self.rhs, ExprNodes.CallNode):
2815 func_name = self.rhs.function.as_cython_attribute()
2817 args, kwds = self.rhs.explicit_args_kwds()
2819 if func_name in ['declare', 'typedef']:
2820 if len(args) > 2 or kwds is not None:
2821 error(rhs.pos, "Can only declare one type at a time.")
2823 type = args[0].analyse_as_type(env)
2825 error(args[0].pos, "Unknown type")
2828 if func_name == 'declare':
2829 if isinstance(lhs, ExprNodes.NameNode):
2830 vars = [(lhs.name, lhs.pos)]
2831 elif isinstance(lhs, ExprNodes.TupleNode):
2832 vars = [(var.name, var.pos) for var in lhs.args]
2834 error(lhs.pos, "Invalid declaration")
2836 for var, pos in vars:
2837 env.declare_var(var, type, pos, is_cdef = True)
2842 self.declaration_only = True
2844 self.declaration_only = True
2845 if not isinstance(lhs, ExprNodes.NameNode):
2846 error(lhs.pos, "Invalid declaration.")
2847 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
2849 elif func_name in ['struct', 'union']:
2850 self.declaration_only = True
2851 if len(args) > 0 or kwds is None:
2852 error(rhs.pos, "Struct or union members must be given by name.")
2855 for member, type_node in kwds.key_value_pairs:
2856 type = type_node.analyse_as_type(env)
2858 error(type_node.pos, "Unknown type")
2860 members.append((member.value, type, member.pos))
2861 if len(members) < len(kwds.key_value_pairs):
2863 if not isinstance(self.lhs, ExprNodes.NameNode):
2864 error(self.lhs.pos, "Invalid declaration.")
2865 name = self.lhs.name
2866 scope = StructOrUnionScope(name)
2867 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
2868 for member, type, pos in members:
2869 scope.declare_var(member, type, pos)
2871 if self.declaration_only:
2874 self.lhs.analyse_target_declaration(env)
2876 def analyse_types(self, env, use_temp = 0):
2877 self.rhs.analyse_types(env)
2878 self.lhs.analyse_target_types(env)
2879 self.lhs.gil_assignment_check(env)
2880 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
2882 self.rhs = self.rhs.coerce_to_temp(env)
2884 def generate_rhs_evaluation_code(self, code):
2885 self.rhs.generate_evaluation_code(code)
2887 def generate_assignment_code(self, code):
2888 self.lhs.generate_assignment_code(self.rhs, code)
2890 def annotate(self, code):
2891 self.lhs.annotate(code)
2892 self.rhs.annotate(code)
2895 class CascadedAssignmentNode(AssignmentNode):
2896 # An assignment with multiple left hand sides:
2900 # lhs_list [ExprNode] Left hand sides
2901 # rhs ExprNode Right hand sides
2905 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
2907 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
2908 coerced_rhs_list = None
2910 def analyse_declarations(self, env):
2911 for lhs in self.lhs_list:
2912 lhs.analyse_target_declaration(env)
2914 def analyse_types(self, env, use_temp = 0):
2915 self.rhs.analyse_types(env)
2917 self.rhs = self.rhs.coerce_to_temp(env)
2919 self.rhs = self.rhs.coerce_to_simple(env)
2920 from ExprNodes import CloneNode
2921 self.coerced_rhs_list = []
2922 for lhs in self.lhs_list:
2923 lhs.analyse_target_types(env)
2924 lhs.gil_assignment_check(env)
2925 rhs = CloneNode(self.rhs)
2926 rhs = rhs.coerce_to(lhs.type, env)
2927 self.coerced_rhs_list.append(rhs)
2929 def generate_rhs_evaluation_code(self, code):
2930 self.rhs.generate_evaluation_code(code)
2932 def generate_assignment_code(self, code):
2933 for i in range(len(self.lhs_list)):
2934 lhs = self.lhs_list[i]
2935 rhs = self.coerced_rhs_list[i]
2936 rhs.generate_evaluation_code(code)
2937 lhs.generate_assignment_code(rhs, code)
2938 # Assignment has disposed of the cloned RHS
2939 self.rhs.generate_disposal_code(code)
2940 self.rhs.free_temps(code)
2942 def annotate(self, code):
2943 for i in range(len(self.lhs_list)):
2944 lhs = self.lhs_list[i].annotate(code)
2945 rhs = self.coerced_rhs_list[i].annotate(code)
2946 self.rhs.annotate(code)
2949 class ParallelAssignmentNode(AssignmentNode):
2950 # A combined packing/unpacking assignment:
2954 # This has been rearranged by the parser into
2956 # a = d ; b = e ; c = f
2958 # but we must evaluate all the right hand sides
2959 # before assigning to any of the left hand sides.
2961 # stats [AssignmentNode] The constituent assignments
2963 child_attrs = ["stats"]
2965 def analyse_declarations(self, env):
2966 for stat in self.stats:
2967 stat.analyse_declarations(env)
2969 def analyse_expressions(self, env):
2970 for stat in self.stats:
2971 stat.analyse_types(env, use_temp = 1)
2973 # def analyse_expressions(self, env):
2974 # for stat in self.stats:
2975 # stat.analyse_expressions_1(env, use_temp = 1)
2976 # for stat in self.stats:
2977 # stat.analyse_expressions_2(env)
2979 def generate_execution_code(self, code):
2980 for stat in self.stats:
2981 stat.generate_rhs_evaluation_code(code)
2982 for stat in self.stats:
2983 stat.generate_assignment_code(code)
2985 def annotate(self, code):
2986 for stat in self.stats:
2990 class InPlaceAssignmentNode(AssignmentNode):
2991 # An in place arithmatic operand:
2997 # lhs ExprNode Left hand side
2998 # rhs ExprNode Right hand side
2999 # op char one of "+-*/%^&|"
3000 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3002 # This code is a bit tricky because in order to obey Python
3003 # semantics the sub-expressions (e.g. indices) of the lhs must
3004 # not be evaluated twice. So we must re-use the values calculated
3005 # in evaluation phase for the assignment phase as well.
3006 # Fortunately, the type of the lhs node is fairly constrained
3007 # (it must be a NameNode, AttributeNode, or IndexNode).
3009 child_attrs = ["lhs", "rhs"]
3012 def analyse_declarations(self, env):
3013 self.lhs.analyse_target_declaration(env)
3015 def analyse_types(self, env):
3016 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3017 self.rhs.analyse_types(env)
3018 self.lhs.analyse_target_types(env)
3019 if Options.incref_local_binop and self.dup.type.is_pyobject:
3020 self.dup = self.dup.coerce_to_temp(env)
3022 if self.lhs.type.is_pyobject:
3023 self.rhs = self.rhs.coerce_to_pyobject(env)
3024 elif self.rhs.type.is_pyobject:
3025 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3026 if self.lhs.type.is_pyobject:
3027 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3028 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3030 def generate_execution_code(self, code):
3032 self.rhs.generate_evaluation_code(code)
3033 self.dup.generate_subexpr_evaluation_code(code)
3034 if self.dup.is_temp:
3035 self.dup.allocate_temp_result(code)
3036 # self.dup.generate_result_code is run only if it is not buffer access
3037 if self.operator == "**":
3041 if self.lhs.type.is_pyobject:
3042 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3043 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3044 self.dup.generate_result_code(code)
3045 self.result_value_temp.allocate(code)
3047 "%s = %s(%s, %s%s); %s" % (
3048 self.result_value.result(),
3049 self.py_operation_function(),
3050 self.dup.py_result(),
3051 self.rhs.py_result(),
3053 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3054 code.put_gotref(self.result_value.py_result())
3055 self.result_value.generate_evaluation_code(code) # May be a type check...
3056 self.rhs.generate_disposal_code(code)
3057 self.rhs.free_temps(code)
3058 self.dup.generate_disposal_code(code)
3059 self.dup.free_temps(code)
3060 self.lhs.generate_assignment_code(self.result_value, code)
3061 self.result_value_temp.release(code)
3063 c_op = self.operator
3067 if self.lhs.type.is_int and self.rhs.type.is_int:
3068 error(self.pos, "** with two C int types is ambiguous")
3070 error(self.pos, "No C inplace power operator")
3071 # have to do assignment directly to avoid side-effects
3072 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3073 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3075 self.dup.generate_result_code(code)
3076 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3077 self.rhs.generate_disposal_code(code)
3078 self.rhs.free_temps(code)
3079 if self.dup.is_temp:
3080 self.dup.generate_subexpr_disposal_code(code)
3081 self.dup.free_subexpr_temps(code)
3083 def create_dup_node(self, env):
3086 self.dup.analyse_types(env)
3087 if isinstance(self.lhs, ExprNodes.NameNode):
3088 target_lhs = ExprNodes.NameNode(self.dup.pos,
3089 name = self.dup.name,
3090 is_temp = self.dup.is_temp,
3091 entry = self.dup.entry)
3092 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3093 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3094 obj = ExprNodes.CloneNode(self.lhs.obj),
3095 attribute = self.dup.attribute,
3096 is_temp = self.dup.is_temp)
3097 elif isinstance(self.lhs, ExprNodes.IndexNode):
3099 index = ExprNodes.CloneNode(self.lhs.index)
3102 if self.lhs.indices:
3103 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3106 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3107 base = ExprNodes.CloneNode(self.dup.base),
3110 is_temp = self.dup.is_temp)
3113 self.lhs = target_lhs
3116 def py_operation_function(self):
3117 return self.py_functions[self.operator]
3120 "|": "PyNumber_InPlaceOr",
3121 "^": "PyNumber_InPlaceXor",
3122 "&": "PyNumber_InPlaceAnd",
3123 "+": "PyNumber_InPlaceAdd",
3124 "-": "PyNumber_InPlaceSubtract",
3125 "*": "PyNumber_InPlaceMultiply",
3126 "/": "PyNumber_InPlaceDivide",
3127 "%": "PyNumber_InPlaceRemainder",
3128 "<<": "PyNumber_InPlaceLshift",
3129 ">>": "PyNumber_InPlaceRshift",
3130 "**": "PyNumber_InPlacePower",
3131 "//": "PyNumber_InPlaceFloorDivide",
3134 def annotate(self, code):
3135 self.lhs.annotate(code)
3136 self.rhs.annotate(code)
3137 self.dup.annotate(code)
3140 class PrintStatNode(StatNode):
3143 # arg_tuple TupleNode
3144 # append_newline boolean
3146 child_attrs = ["arg_tuple"]
3148 def analyse_expressions(self, env):
3149 self.arg_tuple.analyse_expressions(env)
3150 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3151 env.use_utility_code(printing_utility_code)
3152 if len(self.arg_tuple.args) == 1 and self.append_newline:
3153 env.use_utility_code(printing_one_utility_code)
3155 gil_check = StatNode._gil_check
3156 gil_message = "Python print statement"
3158 def generate_execution_code(self, code):
3159 if len(self.arg_tuple.args) == 1 and self.append_newline:
3160 arg = self.arg_tuple.args[0]
3161 arg.generate_evaluation_code(code)
3164 "if (__Pyx_PrintOne(%s) < 0) %s" % (
3166 code.error_goto(self.pos)))
3167 arg.generate_disposal_code(code)
3168 arg.free_temps(code)
3170 self.arg_tuple.generate_evaluation_code(code)
3172 "if (__Pyx_Print(%s, %d) < 0) %s" % (
3173 self.arg_tuple.py_result(),
3174 self.append_newline,
3175 code.error_goto(self.pos)))
3176 self.arg_tuple.generate_disposal_code(code)
3177 self.arg_tuple.free_temps(code)
3179 def annotate(self, code):
3180 self.arg_tuple.annotate(code)
3183 class ExecStatNode(StatNode):
3188 child_attrs = ["args"]
3190 def analyse_expressions(self, env):
3191 for i, arg in enumerate(self.args):
3192 arg.analyse_expressions(env)
3193 arg = arg.coerce_to_pyobject(env)
3195 env.use_utility_code(Builtin.pyexec_utility_code)
3197 gil_check = StatNode._gil_check
3198 gil_message = "Python exec statement"
3200 def generate_execution_code(self, code):
3202 for arg in self.args:
3203 arg.generate_evaluation_code(code)
3204 args.append( arg.py_result() )
3205 args = tuple(args + ['0', '0'][:3-len(args)])
3206 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3207 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3208 (temp_result,) + args))
3209 for arg in self.args:
3210 arg.generate_disposal_code(code)
3211 arg.free_temps(code)
3213 code.error_goto_if_null(temp_result, self.pos))
3214 code.put_gotref(temp_result)
3215 code.put_decref_clear(temp_result, py_object_type)
3216 code.funcstate.release_temp(temp_result)
3218 def annotate(self, code):
3219 for arg in self.args:
3223 class DelStatNode(StatNode):
3228 child_attrs = ["args"]
3230 def analyse_declarations(self, env):
3231 for arg in self.args:
3232 arg.analyse_target_declaration(env)
3234 def analyse_expressions(self, env):
3235 for arg in self.args:
3236 arg.analyse_target_expression(env, None)
3237 if not arg.type.is_pyobject:
3238 error(arg.pos, "Deletion of non-Python object")
3239 #arg.release_target_temp(env)
3241 def gil_check(self, env):
3242 for arg in self.args:
3243 if arg.type.is_pyobject:
3244 self._gil_check(env)
3246 gil_message = "Deleting Python object"
3248 def generate_execution_code(self, code):
3249 for arg in self.args:
3250 if arg.type.is_pyobject:
3251 arg.generate_deletion_code(code)
3252 # else error reported earlier
3254 def annotate(self, code):
3255 for arg in self.args:
3259 class PassStatNode(StatNode):
3264 def analyse_expressions(self, env):
3267 def generate_execution_code(self, code):
3271 class BreakStatNode(StatNode):
3275 def analyse_expressions(self, env):
3278 def generate_execution_code(self, code):
3279 if not code.break_label:
3280 error(self.pos, "break statement not inside loop")
3282 code.put_goto(code.break_label)
3285 class ContinueStatNode(StatNode):
3289 def analyse_expressions(self, env):
3292 def generate_execution_code(self, code):
3293 if code.funcstate.in_try_finally:
3294 error(self.pos, "continue statement inside try of try...finally")
3295 elif not code.continue_label:
3296 error(self.pos, "continue statement not inside loop")
3298 code.put_goto(code.continue_label)
3301 class ReturnStatNode(StatNode):
3304 # value ExprNode or None
3305 # return_type PyrexType
3307 child_attrs = ["value"]
3309 def analyse_expressions(self, env):
3310 return_type = env.return_type
3311 self.return_type = return_type
3313 error(self.pos, "Return not inside a function body")
3316 self.value.analyse_types(env)
3317 if return_type.is_void or return_type.is_returncode:
3318 error(self.value.pos,
3319 "Return with value in void function")
3321 self.value = self.value.coerce_to(env.return_type, env)
3323 if (not return_type.is_void
3324 and not return_type.is_pyobject
3325 and not return_type.is_returncode):
3326 error(self.pos, "Return value required")
3328 def gil_check(self, env):
3329 if self.return_type.is_pyobject:
3330 self._gil_check(env)
3332 gil_message = "Returning Python object"
3334 def generate_execution_code(self, code):
3335 code.mark_pos(self.pos)
3336 if not self.return_type:
3337 # error reported earlier
3339 if self.return_type.is_pyobject:
3340 code.put_xdecref(Naming.retval_cname,
3343 self.value.generate_evaluation_code(code)
3344 self.value.make_owned_reference(code)
3347 Naming.retval_cname,
3348 self.value.result_as(self.return_type)))
3349 self.value.generate_post_assignment_code(code)
3350 self.value.free_temps(code)
3352 if self.return_type.is_pyobject:
3353 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3354 elif self.return_type.is_returncode:
3357 Naming.retval_cname,
3358 self.return_type.default_value))
3359 for cname, type in code.funcstate.temps_holding_reference():
3360 code.put_decref_clear(cname, type)
3361 code.put_goto(code.return_label)
3363 def annotate(self, code):
3365 self.value.annotate(code)
3368 class RaiseStatNode(StatNode):
3371 # exc_type ExprNode or None
3372 # exc_value ExprNode or None
3373 # exc_tb ExprNode or None
3375 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3377 def analyse_expressions(self, env):
3379 self.exc_type.analyse_types(env)
3380 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3382 self.exc_value.analyse_types(env)
3383 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3385 self.exc_tb.analyse_types(env)
3386 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3387 env.use_utility_code(raise_utility_code)
3388 env.use_utility_code(restore_exception_utility_code)
3390 gil_check = StatNode._gil_check
3391 gil_message = "Raising exception"
3393 def generate_execution_code(self, code):
3395 self.exc_type.generate_evaluation_code(code)
3396 type_code = self.exc_type.py_result()
3400 self.exc_value.generate_evaluation_code(code)
3401 value_code = self.exc_value.py_result()
3405 self.exc_tb.generate_evaluation_code(code)
3406 tb_code = self.exc_tb.py_result()
3409 if self.exc_type or self.exc_value or self.exc_tb:
3411 "__Pyx_Raise(%s, %s, %s);" % (
3418 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3420 obj.generate_disposal_code(code)
3421 obj.free_temps(code)
3423 code.error_goto(self.pos))
3425 def annotate(self, code):
3427 self.exc_type.annotate(code)
3429 self.exc_value.annotate(code)
3431 self.exc_tb.annotate(code)
3434 class ReraiseStatNode(StatNode):
3438 def analyse_expressions(self, env):
3439 env.use_utility_code(raise_utility_code)
3440 env.use_utility_code(restore_exception_utility_code)
3442 gil_check = StatNode._gil_check
3443 gil_message = "Raising exception"
3445 def generate_execution_code(self, code):
3446 vars = code.funcstate.exc_vars
3448 code.putln("__Pyx_Raise(%s, %s, %s);" % tuple(vars))
3449 code.putln(code.error_goto(self.pos))
3451 error(self.pos, "Reraise not inside except clause")
3454 class AssertStatNode(StatNode):
3458 # value ExprNode or None
3460 child_attrs = ["cond", "value"]
3462 def analyse_expressions(self, env):
3463 self.cond = self.cond.analyse_boolean_expression(env)
3465 self.value.analyse_types(env)
3466 self.value = self.value.coerce_to_pyobject(env)
3468 gil_check = StatNode._gil_check
3469 gil_message = "Raising exception"
3471 def generate_execution_code(self, code):
3472 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3473 self.cond.generate_evaluation_code(code)
3475 "if (unlikely(!%s)) {" %
3478 self.value.generate_evaluation_code(code)
3480 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3481 self.value.py_result())
3482 self.value.generate_disposal_code(code)
3483 self.value.free_temps(code)
3486 "PyErr_SetNone(PyExc_AssertionError);")
3488 code.error_goto(self.pos))
3491 self.cond.generate_disposal_code(code)
3492 self.cond.free_temps(code)
3493 code.putln("#endif")
3495 def annotate(self, code):
3496 self.cond.annotate(code)
3498 self.value.annotate(code)
3501 class IfStatNode(StatNode):
3504 # if_clauses [IfClauseNode]
3505 # else_clause StatNode or None
3507 child_attrs = ["if_clauses", "else_clause"]
3509 def analyse_control_flow(self, env):
3510 env.start_branching(self.pos)
3511 for if_clause in self.if_clauses:
3512 if_clause.analyse_control_flow(env)
3513 env.next_branch(if_clause.end_pos())
3514 if self.else_clause:
3515 self.else_clause.analyse_control_flow(env)
3516 env.finish_branching(self.end_pos())
3518 def analyse_declarations(self, env):
3519 for if_clause in self.if_clauses:
3520 if_clause.analyse_declarations(env)
3521 if self.else_clause:
3522 self.else_clause.analyse_declarations(env)
3524 def analyse_expressions(self, env):
3525 for if_clause in self.if_clauses:
3526 if_clause.analyse_expressions(env)
3527 if self.else_clause:
3528 self.else_clause.analyse_expressions(env)
3530 def generate_execution_code(self, code):
3531 code.mark_pos(self.pos)
3532 end_label = code.new_label()
3533 for if_clause in self.if_clauses:
3534 if_clause.generate_execution_code(code, end_label)
3535 if self.else_clause:
3536 code.putln("/*else*/ {")
3537 self.else_clause.generate_execution_code(code)
3539 code.put_label(end_label)
3541 def annotate(self, code):
3542 for if_clause in self.if_clauses:
3543 if_clause.annotate(code)
3544 if self.else_clause:
3545 self.else_clause.annotate(code)
3548 class IfClauseNode(Node):
3549 # if or elif clause in an if statement
3551 # condition ExprNode
3554 child_attrs = ["condition", "body"]
3556 def analyse_control_flow(self, env):
3557 self.body.analyse_control_flow(env)
3559 def analyse_declarations(self, env):
3560 self.condition.analyse_declarations(env)
3561 self.body.analyse_declarations(env)
3563 def analyse_expressions(self, env):
3565 self.condition.analyse_temp_boolean_expression(env)
3566 self.body.analyse_expressions(env)
3568 def generate_execution_code(self, code, end_label):
3569 self.condition.generate_evaluation_code(code)
3572 self.condition.result())
3573 self.condition.generate_disposal_code(code)
3574 self.condition.free_temps(code)
3575 self.body.generate_execution_code(code)
3579 code.put_goto(end_label)
3582 def annotate(self, code):
3583 self.condition.annotate(code)
3584 self.body.annotate(code)
3587 class SwitchCaseNode(StatNode):
3588 # Generated in the optimization of an if-elif-else node
3590 # conditions [ExprNode]
3593 child_attrs = ['conditions', 'body']
3595 def generate_execution_code(self, code):
3596 for cond in self.conditions:
3597 code.mark_pos(cond.pos)
3598 cond.generate_evaluation_code(code)
3599 code.putln("case %s:" % cond.result())
3600 self.body.generate_execution_code(code)
3601 code.putln("break;")
3603 def annotate(self, code):
3604 for cond in self.conditions:
3606 self.body.annotate(code)
3608 class SwitchStatNode(StatNode):
3609 # Generated in the optimization of an if-elif-else node
3612 # cases [SwitchCaseNode]
3613 # else_clause StatNode or None
3615 child_attrs = ['test', 'cases', 'else_clause']
3617 def generate_execution_code(self, code):
3618 code.putln("switch (%s) {" % self.test.result())
3619 for case in self.cases:
3620 case.generate_execution_code(code)
3621 if self.else_clause is not None:
3622 code.putln("default:")
3623 self.else_clause.generate_execution_code(code)
3624 code.putln("break;")
3627 def annotate(self, code):
3628 self.test.annotate(code)
3629 for case in self.cases:
3631 if self.else_clause is not None:
3632 self.else_clause.annotate(code)
3634 class LoopNode(object):
3636 def analyse_control_flow(self, env):
3637 env.start_branching(self.pos)
3638 self.body.analyse_control_flow(env)
3639 env.next_branch(self.body.end_pos())
3640 if self.else_clause:
3641 self.else_clause.analyse_control_flow(env)
3642 env.finish_branching(self.end_pos())
3645 class WhileStatNode(LoopNode, StatNode):
3648 # condition ExprNode
3650 # else_clause StatNode
3652 child_attrs = ["condition", "body", "else_clause"]
3654 def analyse_declarations(self, env):
3655 self.body.analyse_declarations(env)
3656 if self.else_clause:
3657 self.else_clause.analyse_declarations(env)
3659 def analyse_expressions(self, env):
3661 self.condition.analyse_temp_boolean_expression(env)
3662 self.body.analyse_expressions(env)
3663 if self.else_clause:
3664 self.else_clause.analyse_expressions(env)
3666 def generate_execution_code(self, code):
3667 old_loop_labels = code.new_loop_labels()
3670 self.condition.generate_evaluation_code(code)
3671 self.condition.generate_disposal_code(code)
3674 self.condition.result())
3675 self.condition.free_temps(code)
3676 self.body.generate_execution_code(code)
3677 code.put_label(code.continue_label)
3679 break_label = code.break_label
3680 code.set_loop_labels(old_loop_labels)
3681 if self.else_clause:
3682 code.putln("/*else*/ {")
3683 self.else_clause.generate_execution_code(code)
3685 code.put_label(break_label)
3687 def annotate(self, code):
3688 self.condition.annotate(code)
3689 self.body.annotate(code)
3690 if self.else_clause:
3691 self.else_clause.annotate(code)
3694 def ForStatNode(pos, **kw):
3695 if 'iterator' in kw:
3696 return ForInStatNode(pos, **kw)
3698 return ForFromStatNode(pos, **kw)
3700 class ForInStatNode(LoopNode, StatNode):
3704 # iterator IteratorNode
3706 # else_clause StatNode
3707 # item NextNode used internally
3709 child_attrs = ["target", "iterator", "body", "else_clause"]
3712 def analyse_declarations(self, env):
3713 self.target.analyse_target_declaration(env)
3714 self.body.analyse_declarations(env)
3715 if self.else_clause:
3716 self.else_clause.analyse_declarations(env)
3718 def analyse_expressions(self, env):
3720 self.target.analyse_target_types(env)
3721 self.iterator.analyse_expressions(env)
3722 self.item = ExprNodes.NextNode(self.iterator, env)
3723 self.item = self.item.coerce_to(self.target.type, env)
3724 self.body.analyse_expressions(env)
3725 if self.else_clause:
3726 self.else_clause.analyse_expressions(env)
3728 def generate_execution_code(self, code):
3729 old_loop_labels = code.new_loop_labels()
3730 self.iterator.allocate_counter_temp(code)
3731 self.iterator.generate_evaluation_code(code)
3734 self.item.generate_evaluation_code(code)
3735 self.target.generate_assignment_code(self.item, code)
3736 self.body.generate_execution_code(code)
3737 code.put_label(code.continue_label)
3740 break_label = code.break_label
3741 code.set_loop_labels(old_loop_labels)
3742 if self.else_clause:
3743 code.putln("/*else*/ {")
3744 self.else_clause.generate_execution_code(code)
3746 code.put_label(break_label)
3747 self.iterator.release_counter_temp(code)
3748 self.iterator.generate_disposal_code(code)
3749 self.iterator.free_temps(code)
3751 def annotate(self, code):
3752 self.target.annotate(code)
3753 self.iterator.annotate(code)
3754 self.body.annotate(code)
3755 if self.else_clause:
3756 self.else_clause.annotate(code)
3757 self.item.annotate(code)
3760 class ForFromStatNode(LoopNode, StatNode):
3761 # for name from expr rel name rel expr
3768 # step ExprNode or None
3770 # else_clause StatNode or None
3776 # loopvar_node ExprNode (usually a NameNode or temp node)
3777 # py_loopvar_node PyTempNode or None
3778 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
3780 is_py_target = False
3782 py_loopvar_node = None
3785 def analyse_declarations(self, env):
3786 self.target.analyse_target_declaration(env)
3787 self.body.analyse_declarations(env)
3788 if self.else_clause:
3789 self.else_clause.analyse_declarations(env)
3791 def analyse_expressions(self, env):
3793 self.target.analyse_target_types(env)
3794 self.bound1.analyse_types(env)
3795 self.bound2.analyse_types(env)
3796 if self.step is not None:
3797 if isinstance(self.step, ExprNodes.UnaryMinusNode):
3798 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
3799 self.step.analyse_types(env)
3801 target_type = self.target.type
3802 if self.target.type.is_numeric:
3803 loop_type = self.target.type
3805 loop_type = PyrexTypes.c_int_type
3806 if not self.bound1.type.is_pyobject:
3807 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
3808 if not self.bound2.type.is_pyobject:
3809 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
3810 if self.step is not None and not self.step.type.is_pyobject:
3811 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
3812 self.bound1 = self.bound1.coerce_to(loop_type, env)
3813 self.bound2 = self.bound2.coerce_to(loop_type, env)
3814 if not self.bound2.is_literal:
3815 self.bound2 = self.bound2.coerce_to_temp(env)
3816 if self.step is not None:
3817 self.step = self.step.coerce_to(loop_type, env)
3818 if not self.step.is_literal:
3819 self.step = self.step.coerce_to_temp(env)
3821 target_type = self.target.type
3822 if not (target_type.is_pyobject or target_type.is_numeric):
3823 error(self.target.pos,
3824 "for-from loop variable must be c numeric type or Python object")
3825 if target_type.is_numeric:
3826 self.is_py_target = False
3827 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
3828 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
3829 self.loopvar_node = self.target
3830 self.py_loopvar_node = None
3832 self.is_py_target = True
3833 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
3834 self.loopvar_node = c_loopvar_node
3835 self.py_loopvar_node = \
3836 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
3837 self.body.analyse_expressions(env)
3838 if self.else_clause:
3839 self.else_clause.analyse_expressions(env)
3841 def generate_execution_code(self, code):
3842 old_loop_labels = code.new_loop_labels()
3843 from_range = self.from_range
3844 self.bound1.generate_evaluation_code(code)
3845 self.bound2.generate_evaluation_code(code)
3846 offset, incop = self.relation_table[self.relation1]
3847 if self.step is not None:
3848 self.step.generate_evaluation_code(code)
3849 step = self.step.result()
3850 incop = "%s=%s" % (incop[0], step)
3852 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3853 self.loopvar_node.allocate(code)
3854 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3855 self.py_loopvar_node.allocate(code)
3857 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
3859 loopvar_name = self.loopvar_node.result()
3861 "for (%s = %s%s; %s %s %s; %s%s) {" % (
3863 self.bound1.result(), offset,
3864 loopvar_name, self.relation2, self.bound2.result(),
3865 loopvar_name, incop))
3866 if self.py_loopvar_node:
3867 self.py_loopvar_node.generate_evaluation_code(code)
3868 self.target.generate_assignment_code(self.py_loopvar_node, code)
3870 code.putln("%s = %s;" % (
3871 self.target.result(), loopvar_name))
3872 self.body.generate_execution_code(code)
3873 code.put_label(code.continue_label)
3874 if self.py_loopvar_node:
3875 # Reassign py variable to loop var here.
3876 # (For consistancy, should rarely come up in practice.)
3878 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, self.target, None)
3879 from_py_node.temp_code = loopvar_name
3880 from_py_node.generate_result_code(code)
3882 if self.py_loopvar_node:
3883 # This is potentially wasteful, but we don't want the semantics to
3884 # depend on whether or not the loop is a python type.
3885 self.py_loopvar_node.generate_evaluation_code(code)
3886 self.target.generate_assignment_code(self.py_loopvar_node, code)
3887 break_label = code.break_label
3888 code.set_loop_labels(old_loop_labels)
3889 if self.else_clause:
3890 code.putln("/*else*/ {")
3891 self.else_clause.generate_execution_code(code)
3893 code.put_label(break_label)
3894 self.bound1.generate_disposal_code(code)
3895 self.bound1.free_temps(code)
3896 self.bound2.generate_disposal_code(code)
3897 self.bound2.free_temps(code)
3898 if isinstance(self.loopvar_node, ExprNodes.TempNode):
3899 self.loopvar_node.release(code)
3900 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
3901 self.py_loopvar_node.release(code)
3902 if self.step is not None:
3903 self.step.generate_disposal_code(code)
3904 self.step.free_temps(code)
3907 # {relop : (initial offset, increment op)}
3914 def annotate(self, code):
3915 self.target.annotate(code)
3916 self.bound1.annotate(code)
3917 self.bound2.annotate(code)
3919 self.bound2.annotate(code)
3920 self.body.annotate(code)
3921 if self.else_clause:
3922 self.else_clause.annotate(code)
3925 class WithStatNode(StatNode):
3927 Represents a Python with statement.
3929 This is only used at parse tree level; and is not present in
3930 analysis or generation phases.
3932 # manager The with statement manager object
3933 # target Node (lhs expression)
3935 child_attrs = ["manager", "target", "body"]
3937 class TryExceptStatNode(StatNode):
3938 # try .. except statement
3941 # except_clauses [ExceptClauseNode]
3942 # else_clause StatNode or None
3944 child_attrs = ["body", "except_clauses", "else_clause"]
3946 def analyse_control_flow(self, env):
3947 env.start_branching(self.pos)
3948 self.body.analyse_control_flow(env)
3949 successful_try = env.control_flow # grab this for later
3950 env.next_branch(self.body.end_pos())
3951 env.finish_branching(self.body.end_pos())
3953 env.start_branching(self.except_clauses[0].pos)
3954 for except_clause in self.except_clauses:
3955 except_clause.analyse_control_flow(env)
3956 env.next_branch(except_clause.end_pos())
3958 # the else cause it executed only when the try clause finishes
3959 env.control_flow.incoming = successful_try
3960 if self.else_clause:
3961 self.else_clause.analyse_control_flow(env)
3962 env.finish_branching(self.end_pos())
3964 def analyse_declarations(self, env):
3965 self.body.analyse_declarations(env)
3966 for except_clause in self.except_clauses:
3967 except_clause.analyse_declarations(env)
3968 if self.else_clause:
3969 self.else_clause.analyse_declarations(env)
3970 env.use_utility_code(reset_exception_utility_code)
3972 def analyse_expressions(self, env):
3973 self.body.analyse_expressions(env)
3974 default_clause_seen = 0
3975 for except_clause in self.except_clauses:
3976 except_clause.analyse_expressions(env)
3977 if default_clause_seen:
3978 error(except_clause.pos, "default 'except:' must be last")
3979 if not except_clause.pattern:
3980 default_clause_seen = 1
3981 self.has_default_clause = default_clause_seen
3982 if self.else_clause:
3983 self.else_clause.analyse_expressions(env)
3985 gil_check = StatNode._gil_check
3986 gil_message = "Try-except statement"
3988 def generate_execution_code(self, code):
3989 old_return_label = code.return_label
3990 old_break_label = code.break_label
3991 old_continue_label = code.continue_label
3992 old_error_label = code.new_error_label()
3993 our_error_label = code.error_label
3994 except_end_label = code.new_label('exception_handled')
3995 except_error_label = code.new_label('except_error')
3996 except_return_label = code.new_label('except_return')
3997 try_return_label = code.new_label('try_return')
3998 try_break_label = code.new_label('try_break')
3999 try_continue_label = code.new_label('try_continue')
4000 try_end_label = code.new_label('try_end')
4003 code.putln("PyObject %s;" %
4004 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4005 code.putln("__Pyx_ExceptionSave(%s);" %
4006 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4007 for var in Naming.exc_save_vars:
4008 code.put_xgotref(var)
4011 code.return_label = try_return_label
4012 code.break_label = try_break_label
4013 code.continue_label = try_continue_label
4014 self.body.generate_execution_code(code)
4017 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4018 code.error_label = except_error_label
4019 code.return_label = except_return_label
4020 if self.else_clause:
4023 self.else_clause.generate_execution_code(code)
4026 for var in Naming.exc_save_vars:
4027 code.put_xdecref_clear(var, py_object_type)
4028 code.put_goto(try_end_label)
4029 if code.label_used(try_return_label):
4030 code.put_label(try_return_label)
4031 for var in Naming.exc_save_vars:
4032 code.put_xdecref_clear(var, py_object_type)
4033 code.put_goto(old_return_label)
4034 code.put_label(our_error_label)
4035 for temp_name, type in temps_to_clean_up:
4036 code.put_xdecref_clear(temp_name, type)
4037 for except_clause in self.except_clauses:
4038 except_clause.generate_handling_code(code, except_end_label)
4040 error_label_used = code.label_used(except_error_label)
4041 if error_label_used or not self.has_default_clause:
4042 if error_label_used:
4043 code.put_label(except_error_label)
4044 for var in Naming.exc_save_vars:
4045 code.put_xdecref(var, py_object_type)
4046 code.put_goto(old_error_label)
4048 if code.label_used(try_break_label):
4049 code.put_label(try_break_label)
4050 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4051 code.putln("__Pyx_ExceptionReset(%s);" %
4052 ', '.join(Naming.exc_save_vars))
4053 code.put_goto(old_break_label)
4055 if code.label_used(try_continue_label):
4056 code.put_label(try_continue_label)
4057 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4058 code.putln("__Pyx_ExceptionReset(%s);" %
4059 ', '.join(Naming.exc_save_vars))
4060 code.put_goto(old_continue_label)
4062 if code.label_used(except_return_label):
4063 code.put_label(except_return_label)
4064 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4065 code.putln("__Pyx_ExceptionReset(%s);" %
4066 ', '.join(Naming.exc_save_vars))
4067 code.put_goto(old_return_label)
4069 if code.label_used(except_end_label):
4070 code.put_label(except_end_label)
4071 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4072 code.putln("__Pyx_ExceptionReset(%s);" %
4073 ', '.join(Naming.exc_save_vars))
4074 code.put_label(try_end_label)
4077 code.return_label = old_return_label
4078 code.break_label = old_break_label
4079 code.continue_label = old_continue_label
4080 code.error_label = old_error_label
4082 def annotate(self, code):
4083 self.body.annotate(code)
4084 for except_node in self.except_clauses:
4085 except_node.annotate(code)
4086 if self.else_clause:
4087 self.else_clause.annotate(code)
4090 class ExceptClauseNode(Node):
4091 # Part of try ... except statement.
4094 # target ExprNode or None
4096 # excinfo_target NameNode or None optional target for exception info
4097 # match_flag string result of exception match
4098 # exc_value ExcValueNode used internally
4099 # function_name string qualified name of enclosing function
4100 # exc_vars (string * 3) local exception variables
4102 # excinfo_target is never set by the parser, but can be set by a transform
4103 # in order to extract more extensive information about the exception as a
4104 # sys.exc_info()-style tuple into a target variable
4106 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4109 excinfo_target = None
4111 def analyse_declarations(self, env):
4113 self.target.analyse_target_declaration(env)
4114 if self.excinfo_target is not None:
4115 self.excinfo_target.analyse_target_declaration(env)
4116 self.body.analyse_declarations(env)
4118 def analyse_expressions(self, env):
4120 genv = env.global_scope()
4121 self.function_name = env.qualified_name
4123 self.pattern.analyse_expressions(env)
4124 self.pattern = self.pattern.coerce_to_pyobject(env)
4127 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4128 self.target.analyse_target_expression(env, self.exc_value)
4129 if self.excinfo_target is not None:
4131 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4132 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4133 self.excinfo_tuple.analyse_expressions(env)
4134 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4136 self.body.analyse_expressions(env)
4138 def generate_handling_code(self, code, end_label):
4139 code.mark_pos(self.pos)
4141 self.pattern.generate_evaluation_code(code)
4143 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4145 "%s = PyErr_ExceptionMatches(%s);" % (
4147 self.pattern.py_result()))
4148 self.pattern.generate_disposal_code(code)
4149 self.pattern.free_temps(code)
4153 code.funcstate.release_temp(match_flag)
4155 code.putln("/*except:*/ {")
4157 if not getattr(self.body, 'stats', True):
4158 # most simple case: no exception variable, empty body (pass)
4159 # => reset the exception state, done
4160 code.putln("PyErr_Restore(0,0,0);")
4161 code.put_goto(end_label)
4165 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4168 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4169 # We always have to fetch the exception value even if
4170 # there is no target, because this also normalises the
4171 # exception and stores it in the thread state.
4172 code.globalstate.use_utility_code(get_exception_utility_code)
4173 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4174 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4175 code.error_goto(self.pos)))
4179 self.exc_value.set_var(exc_vars[1])
4180 self.exc_value.generate_evaluation_code(code)
4181 self.target.generate_assignment_code(self.exc_value, code)
4182 if self.excinfo_target is not None:
4183 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4184 node.set_var(tempvar)
4185 self.excinfo_tuple.generate_evaluation_code(code)
4186 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4188 old_break_label, old_continue_label = code.break_label, code.continue_label
4189 code.break_label = code.new_label('except_break')
4190 code.continue_label = code.new_label('except_continue')
4192 old_exc_vars = code.funcstate.exc_vars
4193 code.funcstate.exc_vars = exc_vars
4194 self.body.generate_execution_code(code)
4195 code.funcstate.exc_vars = old_exc_vars
4196 for var in exc_vars:
4197 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4198 code.put_goto(end_label)
4200 if code.label_used(code.break_label):
4201 code.put_label(code.break_label)
4202 for var in exc_vars:
4203 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4204 code.put_goto(old_break_label)
4205 code.break_label = old_break_label
4207 if code.label_used(code.continue_label):
4208 code.put_label(code.continue_label)
4209 for var in exc_vars:
4210 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4211 code.put_goto(old_continue_label)
4212 code.continue_label = old_continue_label
4214 for temp in exc_vars:
4215 code.funcstate.release_temp(temp)
4220 def annotate(self, code):
4222 self.pattern.annotate(code)
4224 self.target.annotate(code)
4225 self.body.annotate(code)
4228 class TryFinallyStatNode(StatNode):
4229 # try ... finally statement
4232 # finally_clause StatNode
4234 # The plan is that we funnel all continue, break
4235 # return and error gotos into the beginning of the
4236 # finally block, setting a variable to remember which
4237 # one we're doing. At the end of the finally block, we
4238 # switch on the variable to figure out where to go.
4239 # In addition, if we're doing an error, we save the
4240 # exception on entry to the finally block and restore
4243 child_attrs = ["body", "finally_clause"]
4245 preserve_exception = 1
4247 disallow_continue_in_try_finally = 0
4248 # There doesn't seem to be any point in disallowing
4249 # continue in the try block, since we have no problem
4252 def create_analysed(pos, env, body, finally_clause):
4253 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4255 create_analysed = staticmethod(create_analysed)
4257 def analyse_control_flow(self, env):
4258 env.start_branching(self.pos)
4259 self.body.analyse_control_flow(env)
4260 env.next_branch(self.body.end_pos())
4261 env.finish_branching(self.body.end_pos())
4262 self.finally_clause.analyse_control_flow(env)
4264 def analyse_declarations(self, env):
4265 self.body.analyse_declarations(env)
4266 self.finally_clause.analyse_declarations(env)
4268 def analyse_expressions(self, env):
4269 self.body.analyse_expressions(env)
4270 self.finally_clause.analyse_expressions(env)
4272 gil_check = StatNode._gil_check
4273 gil_message = "Try-finally statement"
4275 def generate_execution_code(self, code):
4276 old_error_label = code.error_label
4277 old_labels = code.all_new_labels()
4278 new_labels = code.get_all_labels()
4279 new_error_label = code.error_label
4280 catch_label = code.new_label()
4283 if self.disallow_continue_in_try_finally:
4284 was_in_try_finally = code.funcstate.in_try_finally
4285 code.funcstate.in_try_finally = 1
4286 self.body.generate_execution_code(code)
4287 if self.disallow_continue_in_try_finally:
4288 code.funcstate.in_try_finally = was_in_try_finally
4291 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4295 error_label_used = 0
4296 for i, new_label in enumerate(new_labels):
4297 if new_label in code.labels_used:
4298 cases_used.append(i)
4299 if new_label == new_error_label:
4300 error_label_used = 1
4301 error_label_case = i
4305 if error_label_used and self.preserve_exception:
4307 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4309 "int %s;" % Naming.exc_lineno_name)
4310 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4311 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4312 code.putln(exc_var_init_zero)
4314 exc_var_init_zero = None
4315 code.use_label(catch_label)
4317 "__pyx_why = 0; goto %s;" % catch_label)
4318 for i in cases_used:
4319 new_label = new_labels[i]
4320 #if new_label and new_label != "<try>":
4321 if new_label == new_error_label and self.preserve_exception:
4322 self.put_error_catcher(code,
4323 new_error_label, i+1, catch_label, temps_to_clean_up)
4325 code.put('%s: ' % new_label)
4326 if exc_var_init_zero:
4327 code.putln(exc_var_init_zero)
4328 code.putln("__pyx_why = %s; goto %s;" % (
4331 code.put_label(catch_label)
4332 code.set_all_labels(old_labels)
4333 if error_label_used:
4334 code.new_error_label()
4335 finally_error_label = code.error_label
4336 self.finally_clause.generate_execution_code(code)
4337 if error_label_used:
4338 if finally_error_label in code.labels_used and self.preserve_exception:
4339 over_label = code.new_label()
4340 code.put_goto(over_label);
4341 code.put_label(finally_error_label)
4342 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4343 for var in Naming.exc_vars:
4344 code.putln("Py_XDECREF(%s);" % var)
4346 code.put_goto(old_error_label)
4347 code.put_label(over_label)
4348 code.error_label = old_error_label
4351 "switch (__pyx_why) {")
4352 for i in cases_used:
4353 old_label = old_labels[i]
4354 if old_label == old_error_label and self.preserve_exception:
4355 self.put_error_uncatcher(code, i+1, old_error_label)
4357 code.use_label(old_label)
4359 "case %s: goto %s;" % (
4367 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4368 code.globalstate.use_utility_code(restore_exception_utility_code)
4375 for temp_name, type in temps_to_clean_up:
4376 code.put_xdecref_clear(temp_name, type)
4378 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
4382 Naming.exc_lineno_name, Naming.lineno_cname))
4386 code.put_goto(catch_label)
4390 def put_error_uncatcher(self, code, i, error_label):
4391 code.globalstate.use_utility_code(restore_exception_utility_code)
4396 "__Pyx_ErrRestore(%s, %s, %s);" %
4400 Naming.lineno_cname, Naming.exc_lineno_name))
4401 for var in Naming.exc_vars:
4405 code.put_goto(error_label)
4409 def annotate(self, code):
4410 self.body.annotate(code)
4411 self.finally_clause.annotate(code)
4414 class GILStatNode(TryFinallyStatNode):
4415 # 'with gil' or 'with nogil' statement
4417 # state string 'gil' or 'nogil'
4421 preserve_exception = 0
4423 def __init__(self, pos, state, body):
4425 TryFinallyStatNode.__init__(self, pos,
4427 finally_clause = GILExitNode(pos, state = state))
4429 def analyse_expressions(self, env):
4430 env.use_utility_code(force_init_threads_utility_code)
4431 was_nogil = env.nogil
4433 TryFinallyStatNode.analyse_expressions(self, env)
4434 env.nogil = was_nogil
4436 def gil_check(self, env):
4439 def generate_execution_code(self, code):
4440 code.mark_pos(self.pos)
4441 if self.state == 'gil':
4442 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
4444 code.putln("{ PyThreadState *_save;")
4445 code.putln("Py_UNBLOCK_THREADS")
4446 TryFinallyStatNode.generate_execution_code(self, code)
4450 class GILExitNode(StatNode):
4451 # Used as the 'finally' block in a GILStatNode
4453 # state string 'gil' or 'nogil'
4457 def analyse_expressions(self, env):
4460 def generate_execution_code(self, code):
4461 if self.state == 'gil':
4462 code.putln("PyGILState_Release();")
4464 code.putln("Py_BLOCK_THREADS")
4467 class CImportStatNode(StatNode):
4470 # module_name string Qualified name of module being imported
4471 # as_name string or None Name specified in "as" clause, if any
4475 def analyse_declarations(self, env):
4476 if not env.is_module_scope:
4477 error(self.pos, "cimport only allowed at module level")
4479 module_scope = env.find_module(self.module_name, self.pos)
4480 if "." in self.module_name:
4481 names = [EncodedString(name) for name in self.module_name.split(".")]
4483 top_module_scope = env.context.find_submodule(top_name)
4484 module_scope = top_module_scope
4485 for name in names[1:]:
4486 submodule_scope = module_scope.find_submodule(name)
4487 module_scope.declare_module(name, submodule_scope, self.pos)
4488 module_scope = submodule_scope
4490 env.declare_module(self.as_name, module_scope, self.pos)
4492 env.declare_module(top_name, top_module_scope, self.pos)
4494 name = self.as_name or self.module_name
4495 env.declare_module(name, module_scope, self.pos)
4497 def analyse_expressions(self, env):
4500 def generate_execution_code(self, code):
4504 class FromCImportStatNode(StatNode):
4505 # from ... cimport statement
4507 # module_name string Qualified name of module
4508 # imported_names [(pos, name, as_name, kind)] Names to be imported
4512 def analyse_declarations(self, env):
4513 if not env.is_module_scope:
4514 error(self.pos, "cimport only allowed at module level")
4516 module_scope = env.find_module(self.module_name, self.pos)
4517 env.add_imported_module(module_scope)
4518 for pos, name, as_name, kind in self.imported_names:
4520 for local_name, entry in module_scope.entries.items():
4521 env.add_imported_entry(local_name, entry, pos)
4523 entry = module_scope.lookup(name)
4525 if kind and not self.declaration_matches(entry, kind):
4526 entry.redeclared(pos)
4528 if kind == 'struct' or kind == 'union':
4529 entry = module_scope.declare_struct_or_union(name,
4530 kind = kind, scope = None, typedef_flag = 0, pos = pos)
4531 elif kind == 'class':
4532 entry = module_scope.declare_c_class(name, pos = pos,
4533 module_name = self.module_name)
4535 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
4536 if submodule_scope.parent_module is module_scope:
4537 env.declare_module(as_name or name, submodule_scope, self.pos)
4539 error(pos, "Name '%s' not declared in module '%s'"
4540 % (name, self.module_name))
4543 local_name = as_name or name
4544 env.add_imported_entry(local_name, entry, pos)
4546 def declaration_matches(self, entry, kind):
4547 if not entry.is_type:
4551 if not type.is_extension_type:
4554 if not type.is_struct_or_union:
4556 if kind != type.kind:
4560 def analyse_expressions(self, env):
4563 def generate_execution_code(self, code):
4567 class FromImportStatNode(StatNode):
4568 # from ... import statement
4571 # items [(string, NameNode)]
4572 # interned_items [(string, NameNode, ExprNode)]
4573 # item PyTempNode used internally
4574 # import_star boolean used internally
4576 child_attrs = ["module"]
4579 def analyse_declarations(self, env):
4580 for name, target in self.items:
4582 if not env.is_module_scope:
4583 error(self.pos, "import * only allowed at module level")
4585 env.has_import_star = 1
4586 self.import_star = 1
4588 target.analyse_target_declaration(env)
4590 def analyse_expressions(self, env):
4592 self.module.analyse_expressions(env)
4593 self.item = ExprNodes.PyTempNode(self.pos, env)
4594 self.interned_items = []
4595 for name, target in self.items:
4597 for _, entry in env.entries.items():
4598 if not entry.is_type and entry.type.is_extension_type:
4599 env.use_utility_code(ExprNodes.type_test_utility_code)
4602 entry = env.lookup(target.name)
4603 if entry.is_type and entry.type.name == name and entry.type.module_name == self.module.module_name.value:
4604 continue # already cimported
4605 target.analyse_target_expression(env, None)
4606 if target.type is py_object_type:
4609 coerced_item = self.item.coerce_to(target.type, env)
4610 self.interned_items.append(
4611 (name, target, coerced_item))
4613 def generate_execution_code(self, code):
4614 self.module.generate_evaluation_code(code)
4615 if self.import_star:
4617 'if (%s(%s) < 0) %s;' % (
4619 self.module.py_result(),
4620 code.error_goto(self.pos)))
4621 self.item.allocate(code)
4622 for name, target, coerced_item in self.interned_items:
4623 cname = code.intern_identifier(name)
4625 '%s = PyObject_GetAttr(%s, %s); %s' % (
4627 self.module.py_result(),
4629 code.error_goto_if_null(self.item.result(), self.pos)))
4630 code.put_gotref(self.item.py_result())
4631 if coerced_item is None:
4632 target.generate_assignment_code(self.item, code)
4634 coerced_item.allocate_temp_result(code)
4635 coerced_item.generate_result_code(code)
4636 target.generate_assignment_code(coerced_item, code)
4637 if self.item.result() != coerced_item.result():
4638 code.put_decref_clear(self.item.result(), self.item.type)
4639 self.item.release(code)
4640 self.module.generate_disposal_code(code)
4641 self.module.free_temps(code)
4645 #------------------------------------------------------------------------------------
4647 # Runtime support code
4649 #------------------------------------------------------------------------------------
4651 utility_function_predeclarations = \
4654 #define INLINE __inline__
4656 #define INLINE __inline
4661 typedef struct {PyObject **p; char *s; long n; char is_unicode; char intern; char is_identifier;} __Pyx_StringTabEntry; /*proto*/
4665 static int %(skip_dispatch_cname)s = 0;
4667 """ % { 'skip_dispatch_cname': Naming.skip_dispatch_cname }
4669 if Options.gcc_branch_hints:
4670 branch_prediction_macros = \
4673 /* Test for GCC > 2.95 */
4674 #if __GNUC__ > 2 || \
4675 (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
4676 #define likely(x) __builtin_expect(!!(x), 1)
4677 #define unlikely(x) __builtin_expect(!!(x), 0)
4678 #else /* __GNUC__ > 2 ... */
4679 #define likely(x) (x)
4680 #define unlikely(x) (x)
4681 #endif /* __GNUC__ > 2 ... */
4682 #else /* __GNUC__ */
4683 #define likely(x) (x)
4684 #define unlikely(x) (x)
4685 #endif /* __GNUC__ */
4688 branch_prediction_macros = \
4690 #define likely(x) (x)
4691 #define unlikely(x) (x)
4694 #get_name_predeclaration = \
4695 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
4697 #get_name_interned_predeclaration = \
4698 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
4700 #------------------------------------------------------------------------------------
4702 printing_utility_code = UtilityCode(
4704 static int __Pyx_Print(PyObject *, int); /*proto*/
4705 #if PY_MAJOR_VERSION >= 3
4706 static PyObject* %s = 0;
4707 static PyObject* %s = 0;
4709 """ % (Naming.print_function, Naming.print_function_kwargs),
4711 #if PY_MAJOR_VERSION < 3
4712 static PyObject *__Pyx_GetStdout(void) {
4713 PyObject *f = PySys_GetObject((char *)"stdout");
4715 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
4720 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4725 if (!(f = __Pyx_GetStdout()))
4727 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
4728 if (PyFile_SoftSpace(f, 1)) {
4729 if (PyFile_WriteString(" ", f) < 0)
4732 v = PyTuple_GET_ITEM(arg_tuple, i);
4733 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
4735 if (PyString_Check(v)) {
4736 char *s = PyString_AsString(v);
4737 Py_ssize_t len = PyString_Size(v);
4739 isspace(Py_CHARMASK(s[len-1])) &&
4741 PyFile_SoftSpace(f, 0);
4745 if (PyFile_WriteString("\n", f) < 0)
4747 PyFile_SoftSpace(f, 0);
4752 #else /* Python 3 has a print function */
4754 static int __Pyx_Print(PyObject *arg_tuple, int newline) {
4755 PyObject* kwargs = 0;
4756 PyObject* result = 0;
4757 PyObject* end_string;
4758 if (!%(PRINT_FUNCTION)s) {
4759 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
4760 if (!%(PRINT_FUNCTION)s)
4764 if (!%(PRINT_KWARGS)s) {
4765 %(PRINT_KWARGS)s = PyDict_New();
4766 if (!%(PRINT_KWARGS)s)
4768 end_string = PyUnicode_FromStringAndSize(" ", 1);
4771 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
4772 Py_DECREF(end_string);
4775 Py_DECREF(end_string);
4777 kwargs = %(PRINT_KWARGS)s;
4779 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
4787 """ % {'BUILTINS' : Naming.builtins_cname,
4788 'PRINT_FUNCTION' : Naming.print_function,
4789 'PRINT_KWARGS' : Naming.print_function_kwargs}
4793 printing_one_utility_code = UtilityCode(
4795 static int __Pyx_PrintOne(PyObject *o); /*proto*/
4798 #if PY_MAJOR_VERSION < 3
4800 static int __Pyx_PrintOne(PyObject *o) {
4802 if (!(f = __Pyx_GetStdout()))
4804 if (PyFile_SoftSpace(f, 0)) {
4805 if (PyFile_WriteString(" ", f) < 0)
4808 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
4810 if (PyFile_WriteString("\n", f) < 0)
4813 /* the line below is just to avoid compiler
4814 * compiler warnings about unused functions */
4815 return __Pyx_Print(NULL, 0);
4818 #else /* Python 3 has a print function */
4820 static int __Pyx_PrintOne(PyObject *o) {
4822 PyObject* arg_tuple = PyTuple_New(1);
4823 if (unlikely(!arg_tuple))
4826 PyTuple_SET_ITEM(arg_tuple, 0, o);
4827 res = __Pyx_Print(arg_tuple, 1);
4828 Py_DECREF(arg_tuple);
4834 requires=[printing_utility_code])
4838 #------------------------------------------------------------------------------------
4840 # The following function is based on do_raise() from ceval.c.
4842 raise_utility_code = UtilityCode(
4844 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
4847 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
4851 /* First, check the traceback argument, replacing None with NULL. */
4852 if (tb == Py_None) {
4856 else if (tb != NULL && !PyTraceBack_Check(tb)) {
4857 PyErr_SetString(PyExc_TypeError,
4858 "raise: arg 3 must be a traceback or None");
4861 /* Next, replace a missing value with None */
4862 if (value == NULL) {
4866 #if PY_VERSION_HEX < 0x02050000
4867 if (!PyClass_Check(type))
4869 if (!PyType_Check(type))
4872 /* Raising an instance. The value should be a dummy. */
4873 if (value != Py_None) {
4874 PyErr_SetString(PyExc_TypeError,
4875 "instance exception may not have a separate value");
4878 /* Normalize to raise <class>, <instance> */
4881 #if PY_VERSION_HEX < 0x02050000
4882 if (PyInstance_Check(type)) {
4883 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
4888 PyErr_SetString(PyExc_TypeError,
4889 "raise: exception must be an old-style class or instance");
4893 type = (PyObject*) Py_TYPE(type);
4895 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
4896 PyErr_SetString(PyExc_TypeError,
4897 "raise: exception class must be a subclass of BaseException");
4902 __Pyx_ErrRestore(type, value, tb);
4912 #------------------------------------------------------------------------------------
4914 reraise_utility_code = UtilityCode(
4916 static void __Pyx_ReRaise(void); /*proto*/
4919 static void __Pyx_ReRaise(void) {
4920 PyThreadState *tstate = PyThreadState_GET();
4921 PyObject* tmp_type = tstate->curexc_type;
4922 PyObject* tmp_value = tstate->curexc_value;
4923 PyObject* tmp_tb = tstate->curexc_traceback;
4924 tstate->curexc_type = tstate->exc_type;
4925 tstate->curexc_value = tstate->exc_value;
4926 tstate->curexc_traceback = tstate->exc_traceback;
4927 tstate->exc_type = 0;
4928 tstate->exc_value = 0;
4929 tstate->exc_traceback = 0;
4930 Py_XDECREF(tmp_type);
4931 Py_XDECREF(tmp_value);
4936 #------------------------------------------------------------------------------------
4938 arg_type_test_utility_code = UtilityCode(
4940 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4941 const char *name, int exact); /*proto*/
4944 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
4945 const char *name, int exact)
4948 PyErr_Format(PyExc_SystemError, "Missing type object");
4951 if (none_allowed && obj == Py_None) return 1;
4953 if (Py_TYPE(obj) == type) return 1;
4956 if (PyObject_TypeCheck(obj, type)) return 1;
4958 PyErr_Format(PyExc_TypeError,
4959 "Argument '%s' has incorrect type (expected %s, got %s)",
4960 name, type->tp_name, Py_TYPE(obj)->tp_name);
4965 #------------------------------------------------------------------------------------
4967 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
4968 # many or too few positional arguments were found. This handles
4969 # Py_ssize_t formatting correctly.
4971 raise_argtuple_invalid_utility_code = UtilityCode(
4973 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
4974 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
4977 static void __Pyx_RaiseArgtupleInvalid(
4978 const char* func_name,
4982 Py_ssize_t num_found)
4984 Py_ssize_t num_expected;
4985 const char *number, *more_or_less;
4987 if (num_found < num_min) {
4988 num_expected = num_min;
4989 more_or_less = "at least";
4991 num_expected = num_max;
4992 more_or_less = "at most";
4995 more_or_less = "exactly";
4997 number = (num_expected == 1) ? "" : "s";
4998 PyErr_Format(PyExc_TypeError,
4999 #if PY_VERSION_HEX < 0x02050000
5000 "%s() takes %s %d positional argument%s (%d given)",
5002 "%s() takes %s %zd positional argument%s (%zd given)",
5004 func_name, more_or_less, num_expected, number, num_found);
5008 raise_keyword_required_utility_code = UtilityCode(
5010 static INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5013 static INLINE void __Pyx_RaiseKeywordRequired(
5014 const char* func_name,
5017 PyErr_Format(PyExc_TypeError,
5018 #if PY_MAJOR_VERSION >= 3
5019 "%s() needs keyword-only argument %U", func_name, kw_name);
5021 "%s() needs keyword-only argument %s", func_name,
5022 PyString_AS_STRING(kw_name));
5027 raise_double_keywords_utility_code = UtilityCode(
5029 static void __Pyx_RaiseDoubleKeywordsError(
5030 const char* func_name, PyObject* kw_name); /*proto*/
5033 static void __Pyx_RaiseDoubleKeywordsError(
5034 const char* func_name,
5037 PyErr_Format(PyExc_TypeError,
5038 #if PY_MAJOR_VERSION >= 3
5039 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5041 "%s() got multiple values for keyword argument '%s'", func_name,
5042 PyString_AS_STRING(kw_name));
5047 #------------------------------------------------------------------------------------
5049 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5050 # were passed to a function, or if any keywords were passed to a
5051 # function that does not accept them.
5053 keyword_string_check_utility_code = UtilityCode(
5055 static INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5056 const char* function_name, int kw_allowed); /*proto*/
5059 static INLINE int __Pyx_CheckKeywordStrings(
5061 const char* function_name,
5066 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5067 #if PY_MAJOR_VERSION < 3
5068 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5070 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5072 goto invalid_keyword_type;
5074 if ((!kw_allowed) && unlikely(key))
5075 goto invalid_keyword;
5077 invalid_keyword_type:
5078 PyErr_Format(PyExc_TypeError,
5079 "%s() keywords must be strings", function_name);
5082 PyErr_Format(PyExc_TypeError,
5083 #if PY_MAJOR_VERSION < 3
5084 "%s() got an unexpected keyword argument '%s'",
5085 function_name, PyString_AsString(key));
5087 "%s() got an unexpected keyword argument '%U'",
5088 function_name, key);
5094 #------------------------------------------------------------------------------------
5096 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5097 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5098 # keywords will raise an invalid keyword error.
5100 # Three kinds of errors are checked: 1) non-string keywords, 2)
5101 # unexpected keywords and 3) overlap with positional arguments.
5103 # If num_posargs is greater 0, it denotes the number of positional
5104 # arguments that were passed and that must therefore not appear
5105 # amongst the keywords as well.
5107 # This method does not check for required keyword arguments.
5110 parse_keywords_utility_code = UtilityCode(
5112 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5113 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5114 const char* function_name); /*proto*/
5117 static int __Pyx_ParseOptionalKeywords(
5119 PyObject **argnames[],
5122 Py_ssize_t num_pos_args,
5123 const char* function_name)
5125 PyObject *key = 0, *value = 0;
5128 PyObject*** first_kw_arg = argnames + num_pos_args;
5130 while (PyDict_Next(kwds, &pos, &key, &value)) {
5131 name = first_kw_arg;
5132 while (*name && (**name != key)) name++;
5134 values[name-argnames] = value;
5136 #if PY_MAJOR_VERSION < 3
5137 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5139 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5141 goto invalid_keyword_type;
5143 for (name = first_kw_arg; *name; name++) {
5144 #if PY_MAJOR_VERSION >= 3
5145 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5146 PyUnicode_Compare(**name, key) == 0) break;
5148 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5149 _PyString_Eq(**name, key)) break;
5153 values[name-argnames] = value;
5155 /* unexpected keyword found */
5156 for (name=argnames; name != first_kw_arg; name++) {
5157 if (**name == key) goto arg_passed_twice;
5158 #if PY_MAJOR_VERSION >= 3
5159 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
5160 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
5162 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
5163 _PyString_Eq(**name, key)) goto arg_passed_twice;
5167 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
5169 goto invalid_keyword;
5177 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
5179 invalid_keyword_type:
5180 PyErr_Format(PyExc_TypeError,
5181 "%s() keywords must be strings", function_name);
5184 PyErr_Format(PyExc_TypeError,
5185 #if PY_MAJOR_VERSION < 3
5186 "%s() got an unexpected keyword argument '%s'",
5187 function_name, PyString_AsString(key));
5189 "%s() got an unexpected keyword argument '%U'",
5190 function_name, key);
5197 #------------------------------------------------------------------------------------
5199 traceback_utility_code = UtilityCode(
5201 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
5204 #include "compile.h"
5205 #include "frameobject.h"
5206 #include "traceback.h"
5208 static void __Pyx_AddTraceback(const char *funcname) {
5209 PyObject *py_srcfile = 0;
5210 PyObject *py_funcname = 0;
5211 PyObject *py_globals = 0;
5212 PyObject *empty_string = 0;
5213 PyCodeObject *py_code = 0;
5214 PyFrameObject *py_frame = 0;
5216 #if PY_MAJOR_VERSION < 3
5217 py_srcfile = PyString_FromString(%(FILENAME)s);
5219 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
5221 if (!py_srcfile) goto bad;
5223 #if PY_MAJOR_VERSION < 3
5224 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5226 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
5230 #if PY_MAJOR_VERSION < 3
5231 py_funcname = PyString_FromString(funcname);
5233 py_funcname = PyUnicode_FromString(funcname);
5236 if (!py_funcname) goto bad;
5237 py_globals = PyModule_GetDict(%(GLOBALS)s);
5238 if (!py_globals) goto bad;
5239 #if PY_MAJOR_VERSION < 3
5240 empty_string = PyString_FromStringAndSize("", 0);
5242 empty_string = PyBytes_FromStringAndSize("", 0);
5244 if (!empty_string) goto bad;
5245 py_code = PyCode_New(
5246 0, /*int argcount,*/
5247 #if PY_MAJOR_VERSION >= 3
5248 0, /*int kwonlyargcount,*/
5251 0, /*int stacksize,*/
5253 empty_string, /*PyObject *code,*/
5254 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
5255 %(EMPTY_TUPLE)s, /*PyObject *names,*/
5256 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
5257 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
5258 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
5259 py_srcfile, /*PyObject *filename,*/
5260 py_funcname, /*PyObject *name,*/
5261 %(LINENO)s, /*int firstlineno,*/
5262 empty_string /*PyObject *lnotab*/
5264 if (!py_code) goto bad;
5265 py_frame = PyFrame_New(
5266 PyThreadState_GET(), /*PyThreadState *tstate,*/
5267 py_code, /*PyCodeObject *code,*/
5268 py_globals, /*PyObject *globals,*/
5269 0 /*PyObject *locals*/
5271 if (!py_frame) goto bad;
5272 py_frame->f_lineno = %(LINENO)s;
5273 PyTraceBack_Here(py_frame);
5275 Py_XDECREF(py_srcfile);
5276 Py_XDECREF(py_funcname);
5277 Py_XDECREF(empty_string);
5278 Py_XDECREF(py_code);
5279 Py_XDECREF(py_frame);
5282 'FILENAME': Naming.filename_cname,
5283 'LINENO': Naming.lineno_cname,
5284 'CFILENAME': Naming.cfilenm_cname,
5285 'CLINENO': Naming.clineno_cname,
5286 'GLOBALS': Naming.module_cname,
5287 'EMPTY_TUPLE' : Naming.empty_tuple,
5290 restore_exception_utility_code = UtilityCode(
5292 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5293 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5296 static INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5297 PyObject *tmp_type, *tmp_value, *tmp_tb;
5298 PyThreadState *tstate = PyThreadState_GET();
5300 #if PY_MAJOR_VERSION >= 3
5301 /* Note: this is a temporary work-around to prevent crashes in Python 3.0 */
5302 if ((tstate->exc_type != NULL) & (tstate->exc_type != Py_None)) {
5303 tmp_type = tstate->exc_type;
5304 tmp_value = tstate->exc_value;
5305 tmp_tb = tstate->exc_traceback;
5306 PyErr_NormalizeException(&type, &value, &tb);
5307 PyErr_NormalizeException(&tmp_type, &tmp_value, &tmp_tb);
5308 tstate->exc_type = 0;
5309 tstate->exc_value = 0;
5310 tstate->exc_traceback = 0;
5311 PyException_SetContext(value, tmp_value);
5312 Py_DECREF(tmp_type);
5317 tmp_type = tstate->curexc_type;
5318 tmp_value = tstate->curexc_value;
5319 tmp_tb = tstate->curexc_traceback;
5320 tstate->curexc_type = type;
5321 tstate->curexc_value = value;
5322 tstate->curexc_traceback = tb;
5323 Py_XDECREF(tmp_type);
5324 Py_XDECREF(tmp_value);
5328 static INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5329 PyThreadState *tstate = PyThreadState_GET();
5330 *type = tstate->curexc_type;
5331 *value = tstate->curexc_value;
5332 *tb = tstate->curexc_traceback;
5334 tstate->curexc_type = 0;
5335 tstate->curexc_value = 0;
5336 tstate->curexc_traceback = 0;
5341 #------------------------------------------------------------------------------------
5343 unraisable_exception_utility_code = UtilityCode(
5345 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
5348 static void __Pyx_WriteUnraisable(const char *name) {
5349 PyObject *old_exc, *old_val, *old_tb;
5351 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
5352 #if PY_MAJOR_VERSION < 3
5353 ctx = PyString_FromString(name);
5355 ctx = PyUnicode_FromString(name);
5357 __Pyx_ErrRestore(old_exc, old_val, old_tb);
5359 PyErr_WriteUnraisable(Py_None);
5361 PyErr_WriteUnraisable(ctx);
5366 requires=[restore_exception_utility_code])
5368 #------------------------------------------------------------------------------------
5370 set_vtable_utility_code = UtilityCode(
5372 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
5375 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
5376 PyObject *pycobj = 0;
5379 pycobj = PyCObject_FromVoidPtr(vtable, 0);
5382 if (PyDict_SetItemString(dict, "__pyx_vtable__", pycobj) < 0)
5395 #------------------------------------------------------------------------------------
5397 get_vtable_utility_code = UtilityCode(
5399 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
5402 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
5406 pycobj = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
5409 *(void **)vtabptr = PyCObject_AsVoidPtr(pycobj);
5410 if (!*(void **)vtabptr)
5423 #------------------------------------------------------------------------------------
5425 init_string_tab_utility_code = UtilityCode(
5427 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
5430 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
5432 #if PY_MAJOR_VERSION < 3
5433 if (t->is_unicode && (!t->is_identifier)) {
5434 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
5435 } else if (t->intern) {
5436 *t->p = PyString_InternFromString(t->s);
5438 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
5440 #else /* Python 3+ has unicode identifiers */
5441 if (t->is_identifier || (t->is_unicode && t->intern)) {
5442 *t->p = PyUnicode_InternFromString(t->s);
5443 } else if (t->is_unicode) {
5444 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
5446 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
5457 #------------------------------------------------------------------------------------
5459 get_exception_utility_code = UtilityCode(
5461 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5464 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5465 PyObject *tmp_type, *tmp_value, *tmp_tb;
5466 PyThreadState *tstate = PyThreadState_GET();
5467 *type = tstate->curexc_type;
5468 *value = tstate->curexc_value;
5469 *tb = tstate->curexc_traceback;
5470 tstate->curexc_type = 0;
5471 tstate->curexc_value = 0;
5472 tstate->curexc_traceback = 0;
5473 PyErr_NormalizeException(type, value, tb);
5474 if (PyErr_Occurred())
5479 tmp_type = tstate->exc_type;
5480 tmp_value = tstate->exc_value;
5481 tmp_tb = tstate->exc_traceback;
5482 tstate->exc_type = *type;
5483 tstate->exc_value = *value;
5484 tstate->exc_traceback = *tb;
5485 /* Make sure tstate is in a consistent state when we XDECREF
5486 these objects (XDECREF may run arbitrary code). */
5487 Py_XDECREF(tmp_type);
5488 Py_XDECREF(tmp_value);
5500 #------------------------------------------------------------------------------------
5502 reset_exception_utility_code = UtilityCode(
5504 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5505 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5508 static INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5509 PyThreadState *tstate = PyThreadState_GET();
5510 *type = tstate->exc_type;
5511 *value = tstate->exc_value;
5512 *tb = tstate->exc_traceback;
5518 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5519 PyObject *tmp_type, *tmp_value, *tmp_tb;
5520 PyThreadState *tstate = PyThreadState_GET();
5521 tmp_type = tstate->exc_type;
5522 tmp_value = tstate->exc_value;
5523 tmp_tb = tstate->exc_traceback;
5524 tstate->exc_type = type;
5525 tstate->exc_value = value;
5526 tstate->exc_traceback = tb;
5527 Py_XDECREF(tmp_type);
5528 Py_XDECREF(tmp_value);
5533 #------------------------------------------------------------------------------------
5535 force_init_threads_utility_code = UtilityCode(
5537 #ifndef __PYX_FORCE_INIT_THREADS
5538 #if PY_VERSION_HEX < 0x02040200
5539 #define __PYX_FORCE_INIT_THREADS 1
5541 #define __PYX_FORCE_INIT_THREADS 0
5546 #------------------------------------------------------------------------------------