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