3 # Pyrex - Parse tree nodes
8 cython.declare(sys=object, os=object, time=object, copy=object,
9 Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10 py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11 StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12 CppClassScope=object, UtilityCode=object, EncodedString=object,
13 absolute_path_length=cython.Py_ssize_t)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode, ClosureTempAllocator
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
32 absolute_path_length = 0
34 def relative_position(pos):
36 We embed the relative filename in the generated C file, since we
37 don't want to have to regnerate and compile all the source code
38 whenever the Python install directory moves (which could happen,
39 e.g,. when distributing binaries.)
42 a position tuple -- (absolute filename, line number column position)
50 global absolute_path_length
51 if absolute_path_length==0:
52 absolute_path_length = len(os.path.abspath(os.getcwd()))
53 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
63 # make sure we can encode the filename in the docstring encoding
64 # otherwise make the docstring a unicode string
65 encoding = docstring.encoding
66 if encoding is not None:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
86 if len(args) > 1 and isinstance(args[1], CCodeWriter):
87 # here we annotate the code with this function call
88 # but only if new code is generated
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
111 class VerboseCodeWriter(type):
112 # Set this as a metaclass to trace function calls in code.
113 # This slows down code generation and makes much larger files.
114 def __new__(cls, name, bases, attrs):
116 for mname, m in attrs.items():
117 if isinstance(m, FunctionType):
118 attrs[mname] = write_func_call(m)
119 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
134 # All descandants should set child_attrs to a list of the attributes
135 # containing nodes considered "children" in the tree. Each such attribute
136 # can either contain a single node or a list of nodes. See Visitor.py.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
159 def clone_node(self):
160 """Clone the node. This is defined as a shallow copy, except for member lists
161 amongst the child attributes (from get_child_accessors) which are also
162 copied. Lists containing child nodes are thus seen as a way for the node
163 to hold multiple children directly; the list is not treated as a seperate
164 level in the tree."""
165 result = copy.copy(self)
166 for attrname in result.child_attrs:
167 value = getattr(result, attrname)
168 if isinstance(value, list):
169 setattr(result, attrname, [x for x in value])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
181 # (1) analyse_declarations
182 # Make symbol table entries for all declarations at the current
183 # level, both explicit (def, cdef, etc.) and implicit (assignment
184 # to an otherwise undeclared name).
186 # (2) analyse_expressions
187 # Determine the result types of expressions and fill in the
188 # 'type' attribute of each ExprNode. Insert coercion nodes into the
189 # tree where needed to convert to and from Python objects.
190 # Allocate temporary locals for intermediate results. Fill
191 # in the 'result_code' attribute of each ExprNode with a C code
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
249 def dump_child(x, level):
250 if isinstance(x, Node):
251 return x.dump(level, filter_out, cutoff-1, encountered)
252 elif isinstance(x, list):
253 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
263 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264 for key, value in attrs:
265 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
266 res += "%s>" % indent
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
296 def generate_function_definitions(self, env, code):
297 env_old = env.directives
298 code_old = code.globalstate.directives
299 code.globalstate.directives = self.directives
300 self.body.generate_function_definitions(env, code)
301 env.directives = env_old
302 code.globalstate.directives = code_old
304 def generate_execution_code(self, code):
305 old = code.globalstate.directives
306 code.globalstate.directives = self.directives
307 self.body.generate_execution_code(code)
308 code.globalstate.directives = old
310 def annotate(self, code):
311 old = code.globalstate.directives
312 code.globalstate.directives = self.directives
313 self.body.annotate(code)
314 code.globalstate.directives = old
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
319 def generate_cached_builtins_decls(self, env, code):
320 entries = env.global_scope().undeclared_cached_builtins
321 for entry in entries:
322 code.globalstate.add_cached_builtin_decl(entry)
325 def generate_lambda_definitions(self, env, code):
326 for node in env.lambda_defs:
327 node.generate_function_definitions(env, code)
329 class StatListNode(Node):
330 # stats a list of StatNode
332 child_attrs = ["stats"]
334 def create_analysed(pos, env, *args, **kw):
335 node = StatListNode(pos, *args, **kw)
336 return node # No node-specific analysis necesarry
337 create_analysed = staticmethod(create_analysed)
339 def analyse_control_flow(self, env):
340 for stat in self.stats:
341 stat.analyse_control_flow(env)
343 def analyse_declarations(self, env):
344 #print "StatListNode.analyse_declarations" ###
345 for stat in self.stats:
346 stat.analyse_declarations(env)
348 def analyse_expressions(self, env):
349 #print "StatListNode.analyse_expressions" ###
350 for stat in self.stats:
351 stat.analyse_expressions(env)
353 def generate_function_definitions(self, env, code):
354 #print "StatListNode.generate_function_definitions" ###
355 for stat in self.stats:
356 stat.generate_function_definitions(env, code)
358 def generate_execution_code(self, code):
359 #print "StatListNode.generate_execution_code" ###
360 for stat in self.stats:
361 code.mark_pos(stat.pos)
362 stat.generate_execution_code(code)
364 def annotate(self, code):
365 for stat in self.stats:
369 class StatNode(Node):
371 # Code generation for statements is split into the following subphases:
373 # (1) generate_function_definitions
374 # Emit C code for the definitions of any structs,
375 # unions, enums and functions defined in the current
378 # (2) generate_execution_code
379 # Emit C code for executable statements.
382 def generate_function_definitions(self, env, code):
385 def generate_execution_code(self, code):
386 raise InternalError("generate_execution_code not implemented for %s" % \
387 self.__class__.__name__)
390 class CDefExternNode(StatNode):
391 # include_file string or None
394 child_attrs = ["body"]
396 def analyse_declarations(self, env):
397 if self.include_file:
398 env.add_include_file(self.include_file)
399 old_cinclude_flag = env.in_cinclude
401 self.body.analyse_declarations(env)
402 env.in_cinclude = old_cinclude_flag
404 def analyse_expressions(self, env):
407 def generate_execution_code(self, code):
410 def annotate(self, code):
411 self.body.annotate(code)
414 class CDeclaratorNode(Node):
415 # Part of a C declaration.
417 # Processing during analyse_declarations phase:
420 # Returns (name, type) pair where name is the
421 # CNameDeclaratorNode of the name being declared
422 # and type is the type it is being declared as.
424 # calling_convention string Calling convention of CFuncDeclaratorNode
425 # for which this is a base
429 calling_convention = ""
432 class CNameDeclaratorNode(CDeclaratorNode):
433 # name string The Pyrex name being declared
434 # cname string or None C name, if specified
435 # default ExprNode or None the value assigned on declaration
437 child_attrs = ['default']
441 def analyse(self, base_type, env, nonempty = 0):
442 if nonempty and self.name == '':
443 # May have mistaken the name for the type.
444 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
445 error(self.pos, "Missing argument name")
446 elif base_type.is_void:
447 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
449 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
450 base_type = py_object_type
451 self.type = base_type
452 return self, base_type
454 class CPtrDeclaratorNode(CDeclaratorNode):
455 # base CDeclaratorNode
457 child_attrs = ["base"]
459 def analyse(self, base_type, env, nonempty = 0):
460 if base_type.is_pyobject:
462 "Pointer base type cannot be a Python object")
463 ptr_type = PyrexTypes.c_ptr_type(base_type)
464 return self.base.analyse(ptr_type, env, nonempty = nonempty)
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Reference base type cannot be a Python object")
475 ref_type = PyrexTypes.c_ref_type(base_type)
476 return self.base.analyse(ref_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
485 if base_type.is_cpp_class:
486 from ExprNodes import TupleNode
487 if isinstance(self.dimension, TupleNode):
488 args = self.dimension.args
490 args = self.dimension,
491 values = [v.analyse_as_type(env) for v in args]
493 ix = values.index(None)
494 error(args[ix].pos, "Template parameter not a type.")
496 base_type = base_type.specialize_here(self.pos, values)
497 return self.base.analyse(base_type, env, nonempty = nonempty)
499 self.dimension.analyse_const_expression(env)
500 if not self.dimension.type.is_int:
501 error(self.dimension.pos, "Array dimension not integer")
502 size = self.dimension.get_constant_c_result_code()
511 if not base_type.is_complete():
513 "Array element type '%s' is incomplete" % base_type)
514 if base_type.is_pyobject:
516 "Array element cannot be a Python object")
517 if base_type.is_cfunction:
519 "Array element cannot be a function")
520 array_type = PyrexTypes.c_array_type(base_type, size)
521 return self.base.analyse(array_type, env, nonempty = nonempty)
524 class CFuncDeclaratorNode(CDeclaratorNode):
525 # base CDeclaratorNode
526 # args [CArgDeclNode]
527 # has_varargs boolean
528 # exception_value ConstNode
529 # exception_check boolean True if PyErr_Occurred check needed
530 # nogil boolean Can be called without gil
531 # with_gil boolean Acquire gil around function body
533 child_attrs = ["base", "args", "exception_value"]
536 optional_arg_count = 0
538 def analyse(self, return_type, env, nonempty = 0):
542 for i, arg_node in enumerate(self.args):
543 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544 is_self_arg = (i == 0 and env.is_c_class_scope))
545 name = name_declarator.name
546 if name_declarator.cname:
548 "Function argument cannot have C name specification")
549 # Turn *[] argument into **
551 type = PyrexTypes.c_ptr_type(type.base_type)
552 # Catch attempted C-style func(void) decl
554 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
555 func_type_args.append(
556 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
558 self.optional_arg_count += 1
559 elif self.optional_arg_count:
560 error(self.pos, "Non-default argument follows default argument")
562 if self.optional_arg_count:
563 scope = StructOrUnionScope()
564 arg_count_member = '%sn' % Naming.pyrex_prefix
565 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
566 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
567 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
568 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
569 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
574 cname = struct_cname)
575 self.op_args_struct.defined_in_pxd = 1
576 self.op_args_struct.used = 1
580 if self.exception_check == '+':
581 env.add_include_file('stdexcept')
582 if return_type.is_pyobject \
583 and (self.exception_value or self.exception_check) \
584 and self.exception_check != '+':
586 "Exception clause not allowed for function returning Python object")
588 if self.exception_value:
589 self.exception_value.analyse_const_expression(env)
590 if self.exception_check == '+':
591 self.exception_value.analyse_types(env)
592 exc_val_type = self.exception_value.type
593 if not exc_val_type.is_error and \
594 not exc_val_type.is_pyobject and \
595 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
596 error(self.exception_value.pos,
597 "Exception value must be a Python exception or cdef function with no arguments.")
598 exc_val = self.exception_value
600 self.exception_value = self.exception_value.coerce_to(return_type, env)
601 if self.exception_value.analyse_const_expression(env):
602 exc_val = self.exception_value.get_constant_c_result_code()
604 raise InternalError("get_constant_c_result_code not implemented for %s" %
605 self.exception_value.__class__.__name__)
606 if not return_type.assignable_from(self.exception_value.type):
607 error(self.exception_value.pos,
608 "Exception value incompatible with function return type")
609 exc_check = self.exception_check
610 if return_type.is_array:
612 "Function cannot return an array")
613 if return_type.is_cfunction:
615 "Function cannot return a function")
616 func_type = PyrexTypes.CFuncType(
617 return_type, func_type_args, self.has_varargs,
618 optional_arg_count = self.optional_arg_count,
619 exception_value = exc_val, exception_check = exc_check,
620 calling_convention = self.base.calling_convention,
621 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
622 if self.optional_arg_count:
623 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
624 callspec = env.directives['callspec']
626 current = func_type.calling_convention
627 if current and current != callspec:
628 error(self.pos, "cannot have both '%s' and '%s' "
629 "calling conventions" % (current, callspec))
630 func_type.calling_convention = callspec
631 return self.base.analyse(func_type, env)
634 class CArgDeclNode(Node):
635 # Item in a function declaration argument list.
637 # base_type CBaseTypeNode
638 # declarator CDeclaratorNode
639 # not_none boolean Tagged with 'not None'
640 # or_none boolean Tagged with 'or None'
641 # accept_none boolean Resolved boolean for not_none/or_none
642 # default ExprNode or None
643 # default_value PyObjectConst constant for default value
644 # annotation ExprNode or None Py3 function arg annotation
645 # is_self_arg boolean Is the "self" arg of an extension type method
646 # is_type_arg boolean Is the "class" arg of an extension type classmethod
647 # is_kw_only boolean Is a keyword-only argument
649 child_attrs = ["base_type", "declarator", "default"]
655 name_declarator = None
659 def analyse(self, env, nonempty = 0, is_self_arg = False):
661 self.base_type.is_self_arg = self.is_self_arg = True
662 if self.type is None:
663 # The parser may missinterpret names as types...
665 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
667 self.declarator.name = self.base_type.name
668 self.base_type.name = None
669 self.base_type.is_basic_c_type = False
672 could_be_name = False
673 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
674 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
675 self.declarator.name = self.base_type.arg_name
676 # The parser is unable to resolve the ambiguity of [] as part of the
677 # type (e.g. in buffers) or empty declarator (as with arrays).
678 # This is only arises for empty multi-dimensional arrays.
679 if (base_type.is_array
680 and isinstance(self.base_type, TemplatedTypeNode)
681 and isinstance(self.declarator, CArrayDeclaratorNode)):
682 declarator = self.declarator
683 while isinstance(declarator.base, CArrayDeclaratorNode):
684 declarator = declarator.base
685 declarator.base = self.base_type.array_declarator
686 base_type = base_type.base_type
687 return self.declarator.analyse(base_type, env, nonempty = nonempty)
689 return self.name_declarator, self.type
691 def calculate_default_value_code(self, code):
692 if self.default_value is None:
694 if self.default.is_literal:
695 # will not output any code, just assign the result_code
696 self.default.generate_evaluation_code(code)
697 return self.type.cast_code(self.default.result())
698 self.default_value = code.get_argument_default_const(self.type)
699 return self.default_value
701 def annotate(self, code):
703 self.default.annotate(code)
706 class CBaseTypeNode(Node):
707 # Abstract base class for C base type nodes.
709 # Processing during analyse_declarations phase:
716 def analyse_as_type(self, env):
717 return self.analyse(env)
719 class CAnalysedBaseTypeNode(Node):
724 def analyse(self, env, could_be_name = False):
727 class CSimpleBaseTypeNode(CBaseTypeNode):
729 # module_path [string] Qualifying name components
730 # is_basic_c_type boolean
734 # is_self_arg boolean Is self argument of C method
735 # ##is_type_arg boolean Is type argument of class method
738 arg_name = None # in case the argument name was interpreted as a type
740 def analyse(self, env, could_be_name = False):
741 # Return type descriptor.
742 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
744 if self.is_basic_c_type:
745 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
747 error(self.pos, "Unrecognised type modifier combination")
748 elif self.name == "object" and not self.module_path:
749 type = py_object_type
750 elif self.name is None:
751 if self.is_self_arg and env.is_c_class_scope:
752 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
753 type = env.parent_type
754 ## elif self.is_type_arg and env.is_c_class_scope:
755 ## type = Builtin.type_type
757 type = py_object_type
760 scope = env.find_imported_module(self.module_path, self.pos)
764 if scope.is_c_class_scope:
765 scope = scope.global_scope()
766 entry = scope.lookup(self.name)
767 if entry and entry.is_type:
770 if self.is_self_arg and env.is_c_class_scope:
771 type = env.parent_type
772 ## elif self.is_type_arg and env.is_c_class_scope:
773 ## type = Builtin.type_type
775 type = py_object_type
776 self.arg_name = self.name
779 if not self.name in self.templates:
780 error(self.pos, "'%s' is not a type identifier" % self.name)
781 type = PyrexTypes.TemplatePlaceholderType(self.name)
783 error(self.pos, "'%s' is not a type identifier" % self.name)
785 if not type.is_numeric or type.is_complex:
786 error(self.pos, "can only complexify c numeric types")
787 type = PyrexTypes.CComplexType(type)
788 type.create_declaration_utility_code(env)
789 elif type is Builtin.complex_type:
790 # Special case: optimise builtin complex type into C's
791 # double complex. The parser cannot do this (as for the
792 # normal scalar types) as the user may have redeclared the
793 # 'complex' type. Testing for the exact type here works.
794 type = PyrexTypes.c_double_complex_type
795 type.create_declaration_utility_code(env)
800 return PyrexTypes.error_type
802 class CNestedBaseTypeNode(CBaseTypeNode):
803 # For C++ classes that live inside other C++ classes.
806 # base_type CBaseTypeNode
808 child_attrs = ['base_type']
810 def analyse(self, env, could_be_name = None):
811 base_type = self.base_type.analyse(env)
812 if base_type is PyrexTypes.error_type:
813 return PyrexTypes.error_type
814 if not base_type.is_cpp_class:
815 error(self.pos, "'%s' is not a valid type scope" % base_type)
816 return PyrexTypes.error_type
817 type_entry = base_type.scope.lookup_here(self.name)
818 if not type_entry or not type_entry.is_type:
819 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
820 return PyrexTypes.error_type
821 return type_entry.type
823 class TemplatedTypeNode(CBaseTypeNode):
825 # positional_args [ExprNode] List of positional arguments
826 # keyword_args DictNode Keyword arguments
827 # base_type_node CBaseTypeNode
830 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
833 child_attrs = ["base_type_node", "positional_args",
834 "keyword_args", "dtype_node"]
840 def analyse(self, env, could_be_name = False, base_type = None):
841 if base_type is None:
842 base_type = self.base_type_node.analyse(env)
843 if base_type.is_error: return base_type
845 if base_type.is_cpp_class:
847 if self.keyword_args and self.keyword_args.key_value_pairs:
848 error(self.pos, "c++ templates cannot take keyword arguments");
849 self.type = PyrexTypes.error_type
852 for template_node in self.positional_args:
853 type = template_node.analyse_as_type(env)
855 error(template_node.pos, "unknown type in template argument")
857 template_types.append(type)
858 self.type = base_type.specialize_here(self.pos, template_types)
860 elif base_type.is_pyobject:
864 options = Buffer.analyse_buffer_options(
867 self.positional_args,
869 base_type.buffer_defaults)
871 if sys.version_info[0] < 3:
872 # Py 2.x enforces byte strings as keyword arguments ...
873 options = dict([ (name.encode('ASCII'), value)
874 for name, value in options.items() ])
876 self.type = PyrexTypes.BufferType(base_type, **options)
880 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
881 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
882 error(self.pos, "invalid array declaration")
883 self.type = PyrexTypes.error_type
885 # It would be nice to merge this class with CArrayDeclaratorNode,
886 # but arrays are part of the declaration, not the type...
887 if not self.positional_args:
890 dimension = self.positional_args[0]
891 self.array_declarator = CArrayDeclaratorNode(self.pos,
892 base = empty_declarator,
893 dimension = dimension)
894 self.type = self.array_declarator.analyse(base_type, env)[1]
898 class CComplexBaseTypeNode(CBaseTypeNode):
899 # base_type CBaseTypeNode
900 # declarator CDeclaratorNode
902 child_attrs = ["base_type", "declarator"]
904 def analyse(self, env, could_be_name = False):
905 base = self.base_type.analyse(env, could_be_name)
906 _, type = self.declarator.analyse(base, env)
910 class CVarDefNode(StatNode):
911 # C variable definition or forward/extern function declaration.
913 # visibility 'private' or 'public' or 'extern'
914 # base_type CBaseTypeNode
915 # declarators [CDeclaratorNode]
919 # decorators [cython.locals(...)] or None
920 # directive_locals { string : NameNode } locals defined by cython.locals(...)
922 child_attrs = ["base_type", "declarators"]
925 directive_locals = {}
927 def analyse_declarations(self, env, dest_scope = None):
930 self.dest_scope = dest_scope
931 base_type = self.base_type.analyse(env)
933 # If the field is an external typedef, we cannot be sure about the type,
934 # so do conversion ourself rather than rely on the CPython mechanism (through
935 # a property; made in AnalyseDeclarationsTransform).
936 if (dest_scope.is_c_class_scope
937 and self.visibility in ('public', 'readonly')):
940 need_property = False
941 visibility = self.visibility
943 for declarator in self.declarators:
944 name_declarator, type = declarator.analyse(base_type, env)
945 if not type.is_complete():
946 if not (self.visibility == 'extern' and type.is_array):
947 error(declarator.pos,
948 "Variable type '%s' is incomplete" % type)
949 if self.visibility == 'extern' and type.is_pyobject:
950 error(declarator.pos,
951 "Python object cannot be declared extern")
952 name = name_declarator.name
953 cname = name_declarator.cname
955 error(declarator.pos, "Missing name in declaration.")
957 if type.is_cfunction:
958 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
959 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
961 if entry is not None:
962 entry.directive_locals = self.directive_locals
964 if self.directive_locals:
965 error(self.pos, "Decorators can only be followed by functions")
966 if self.in_pxd and self.visibility != 'extern':
968 "Only 'extern' C variable declaration allowed in .pxd file")
969 entry = dest_scope.declare_var(name, type, declarator.pos,
970 cname = cname, visibility = visibility, is_cdef = 1)
971 entry.needs_property = need_property
974 class CStructOrUnionDefNode(StatNode):
976 # cname string or None
977 # kind "struct" or "union"
978 # typedef_flag boolean
979 # visibility "public" or "private"
981 # attributes [CVarDefNode] or None
985 child_attrs = ["attributes"]
987 def analyse_declarations(self, env):
989 if self.visibility == 'extern' and self.packed:
990 error(self.pos, "Cannot declare extern struct as 'packed'")
991 if self.attributes is not None:
992 scope = StructOrUnionScope(self.name)
993 self.entry = env.declare_struct_or_union(
994 self.name, self.kind, scope, self.typedef_flag, self.pos,
995 self.cname, visibility = self.visibility, packed = self.packed)
996 if self.attributes is not None:
997 if self.in_pxd and not env.in_cinclude:
998 self.entry.defined_in_pxd = 1
999 for attr in self.attributes:
1000 attr.analyse_declarations(env, scope)
1001 if self.visibility != 'extern':
1002 need_typedef_indirection = False
1003 for attr in scope.var_entries:
1005 while type.is_array:
1006 type = type.base_type
1007 if type == self.entry.type:
1008 error(attr.pos, "Struct cannot contain itself as a member.")
1009 if self.typedef_flag:
1011 type = type.base_type
1012 if type == self.entry.type:
1013 need_typedef_indirection = True
1014 if need_typedef_indirection:
1015 # C can't handle typedef structs that refer to themselves.
1016 struct_entry = self.entry
1017 self.entry = env.declare_typedef(
1018 self.name, struct_entry.type, self.pos,
1019 cname = self.cname, visibility='ignore')
1020 struct_entry.type.typedef_flag = False
1021 # FIXME: this might be considered a hack ;-)
1022 struct_entry.cname = struct_entry.type.cname = \
1023 '_' + self.entry.type.typedef_cname
1025 def analyse_expressions(self, env):
1028 def generate_execution_code(self, code):
1032 class CppClassNode(CStructOrUnionDefNode):
1035 # cname string or None
1036 # visibility "extern"
1038 # attributes [CVarDefNode] or None
1040 # base_classes [string]
1041 # templates [string] or None
1043 def analyse_declarations(self, env):
1045 if self.attributes is not None:
1046 scope = CppClassScope(self.name, env)
1047 base_class_types = []
1048 for base_class_name in self.base_classes:
1049 base_class_entry = env.lookup(base_class_name)
1050 if base_class_entry is None:
1051 error(self.pos, "'%s' not found" % base_class_name)
1052 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1053 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1055 base_class_types.append(base_class_entry.type)
1056 if self.templates is None:
1057 template_types = None
1059 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1060 self.entry = env.declare_cpp_class(
1061 self.name, scope, self.pos,
1062 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1063 self.entry.is_cpp_class = 1
1064 if self.attributes is not None:
1065 if self.in_pxd and not env.in_cinclude:
1066 self.entry.defined_in_pxd = 1
1067 for attr in self.attributes:
1068 attr.analyse_declarations(scope)
1070 class CEnumDefNode(StatNode):
1071 # name string or None
1072 # cname string or None
1073 # items [CEnumDefItemNode]
1074 # typedef_flag boolean
1075 # visibility "public" or "private"
1079 child_attrs = ["items"]
1081 def analyse_declarations(self, env):
1082 self.entry = env.declare_enum(self.name, self.pos,
1083 cname = self.cname, typedef_flag = self.typedef_flag,
1084 visibility = self.visibility)
1085 if self.items is not None:
1086 if self.in_pxd and not env.in_cinclude:
1087 self.entry.defined_in_pxd = 1
1088 for item in self.items:
1089 item.analyse_declarations(env, self.entry)
1091 def analyse_expressions(self, env):
1094 def generate_execution_code(self, code):
1095 if self.visibility == 'public':
1096 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1097 for item in self.entry.enum_values:
1098 code.putln("%s = PyInt_FromLong(%s); %s" % (
1101 code.error_goto_if_null(temp, item.pos)))
1102 code.put_gotref(temp)
1103 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1104 Naming.module_cname,
1107 code.error_goto(item.pos)))
1108 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1109 code.funcstate.release_temp(temp)
1112 class CEnumDefItemNode(StatNode):
1114 # cname string or None
1115 # value ExprNode or None
1117 child_attrs = ["value"]
1119 def analyse_declarations(self, env, enum_entry):
1121 self.value.analyse_const_expression(env)
1122 if not self.value.type.is_int:
1123 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1124 self.value.analyse_const_expression(env)
1125 entry = env.declare_const(self.name, enum_entry.type,
1126 self.value, self.pos, cname = self.cname,
1127 visibility = enum_entry.visibility)
1128 enum_entry.enum_values.append(entry)
1131 class CTypeDefNode(StatNode):
1132 # base_type CBaseTypeNode
1133 # declarator CDeclaratorNode
1134 # visibility "public" or "private"
1137 child_attrs = ["base_type", "declarator"]
1139 def analyse_declarations(self, env):
1140 base = self.base_type.analyse(env)
1141 name_declarator, type = self.declarator.analyse(base, env)
1142 name = name_declarator.name
1143 cname = name_declarator.cname
1144 entry = env.declare_typedef(name, type, self.pos,
1145 cname = cname, visibility = self.visibility)
1146 if self.in_pxd and not env.in_cinclude:
1147 entry.defined_in_pxd = 1
1149 def analyse_expressions(self, env):
1151 def generate_execution_code(self, code):
1155 class FuncDefNode(StatNode, BlockNode):
1156 # Base class for function definition nodes.
1158 # return_type PyrexType
1159 # #filename string C name of filename string const
1160 # entry Symtab.Entry
1161 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1162 # needs_outer_scope boolean Whether or not this function requires outer scope
1163 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1167 needs_closure = False
1168 needs_outer_scope = False
1169 is_generator = False
1170 is_generator_body = False
1173 def analyse_default_values(self, env):
1174 genv = env.global_scope()
1176 for arg in self.args:
1180 arg.default.analyse_types(env)
1181 arg.default = arg.default.coerce_to(arg.type, genv)
1184 "This argument cannot have a default value")
1189 error(arg.pos, "Non-default argument following default argument")
1191 def need_gil_acquisition(self, lenv):
1194 def create_local_scope(self, env):
1196 while genv.is_py_class_scope or genv.is_c_class_scope:
1197 genv = genv.outer_scope
1198 if self.needs_closure:
1199 lenv = ClosureScope(name=self.entry.name,
1201 scope_name=self.entry.cname)
1203 lenv = LocalScope(name=self.entry.name,
1206 lenv.return_type = self.return_type
1207 type = self.entry.type
1208 if type.is_cfunction:
1209 lenv.nogil = type.nogil and not type.with_gil
1210 self.local_scope = lenv
1211 lenv.directives = env.directives
1214 def generate_function_body(self, env, code):
1215 self.body.generate_execution_code(code)
1217 def generate_function_definitions(self, env, code):
1220 lenv = self.local_scope
1221 if lenv.is_closure_scope and not lenv.is_passthrough:
1222 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1223 Naming.outer_scope_cname)
1225 outer_scope_cname = Naming.outer_scope_cname
1226 lenv.mangle_closure_cnames(outer_scope_cname)
1227 # Generate closure function definitions
1228 self.body.generate_function_definitions(lenv, code)
1229 # generate lambda function definitions
1230 self.generate_lambda_definitions(lenv, code)
1232 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1233 self.entry.scope.is_c_class_scope)
1234 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1235 self.entry.scope.is_c_class_scope)
1236 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1238 if 'cython_unused' not in self.modifiers:
1239 self.modifiers = self.modifiers + ['cython_unused']
1241 preprocessor_guard = None
1242 if self.entry.is_special and not is_buffer_slot:
1243 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1245 preprocessor_guard = slot.preprocessor_guard_code()
1246 if (self.entry.name == '__long__' and
1247 not self.entry.scope.lookup_here('__int__')):
1248 preprocessor_guard = None
1250 profile = code.globalstate.directives['profile']
1253 error(self.pos, "Cannot profile nogil function.")
1254 code.globalstate.use_utility_code(profile_utility_code)
1256 # Generate C code for header and body of function
1257 code.enter_cfunc_scope()
1258 code.return_from_error_cleanup_label = code.new_label()
1260 # ----- Top-level constants used by this function
1261 code.mark_pos(self.pos)
1262 self.generate_cached_builtins_decls(lenv, code)
1263 # ----- Function header
1266 if preprocessor_guard:
1267 code.putln(preprocessor_guard)
1269 with_pymethdef = self.needs_assignment_synthesis(env, code)
1271 self.py_func.generate_function_header(code,
1272 with_pymethdef = with_pymethdef,
1274 self.generate_function_header(code,
1275 with_pymethdef = with_pymethdef)
1276 # ----- Local variable declarations
1277 # Find function scope
1279 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1280 cenv = cenv.outer_scope
1281 if self.needs_closure:
1282 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1284 elif self.needs_outer_scope:
1285 if lenv.is_passthrough:
1286 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1288 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1290 self.generate_argument_declarations(lenv, code)
1291 for entry in lenv.var_entries:
1292 if not entry.in_closure:
1293 code.put_var_declaration(entry)
1295 if not self.return_type.is_void:
1296 if self.return_type.is_pyobject:
1300 (self.return_type.declaration_code(Naming.retval_cname),
1302 tempvardecl_code = code.insertion_point()
1303 code.put_declare_refcount_context()
1304 self.generate_keyword_list(code)
1306 code.put_trace_declarations()
1307 # ----- Extern library function declarations
1308 lenv.generate_library_function_declarations(code)
1309 # ----- GIL acquisition
1310 acquire_gil = self.acquire_gil
1312 env.use_utility_code(force_init_threads_utility_code)
1313 code.putln("#ifdef WITH_THREAD")
1314 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1315 code.putln("#endif")
1316 # ----- set up refnanny
1318 code.put_setup_refcount_context(self.entry.name)
1319 # ----- Automatic lead-ins for certain special functions
1320 if is_getbuffer_slot:
1321 self.getbuffer_init(code)
1322 # ----- Create closure scope object
1323 if self.needs_closure:
1324 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1325 Naming.cur_scope_cname,
1326 lenv.scope_class.type.declaration_code(''),
1327 lenv.scope_class.type.typeptr_cname,
1328 lenv.scope_class.type.typeptr_cname,
1329 Naming.empty_tuple))
1330 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1331 if is_getbuffer_slot:
1332 self.getbuffer_error_cleanup(code)
1334 code.put_finish_refcount_context()
1335 # FIXME: what if the error return value is a Python value?
1336 code.putln("return %s;" % self.error_value())
1338 code.put_gotref(Naming.cur_scope_cname)
1339 # Note that it is unsafe to decref the scope at this point.
1340 if self.needs_outer_scope:
1341 code.putln("%s = (%s)%s;" % (
1343 cenv.scope_class.type.declaration_code(''),
1345 if lenv.is_passthrough:
1346 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1347 elif self.needs_closure:
1348 # inner closures own a reference to their outer parent
1349 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1350 code.put_giveref(outer_scope_cname)
1351 # ----- Trace function call
1353 # this looks a bit late, but if we don't get here due to a
1354 # fatal error before hand, it's not really worth tracing
1355 code.put_trace_call(self.entry.name, self.pos)
1356 # ----- Fetch arguments
1357 self.generate_argument_parsing_code(env, code)
1358 # If an argument is assigned to in the body, we must
1359 # incref it to properly keep track of refcounts.
1360 for entry in lenv.arg_entries:
1361 if entry.type.is_pyobject:
1362 if (acquire_gil or entry.assignments) and not entry.in_closure:
1363 code.put_var_incref(entry)
1364 # ----- Initialise local variables
1365 for entry in lenv.var_entries:
1366 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1367 code.put_init_var_to_py_none(entry)
1368 # ----- Initialise local buffer auxiliary variables
1369 for entry in lenv.var_entries + lenv.arg_entries:
1370 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1371 code.putln("%s.buf = NULL;" %
1372 entry.buffer_aux.buffer_info_var.cname)
1373 # ----- Check and convert arguments
1374 self.generate_argument_type_tests(code)
1375 # ----- Acquire buffer arguments
1376 for entry in lenv.arg_entries:
1377 if entry.type.is_buffer:
1378 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1380 # -------------------------
1381 # ----- Function body -----
1382 # -------------------------
1383 self.generate_function_body(env, code)
1385 # ----- Default return value
1387 if self.return_type.is_pyobject:
1388 #if self.return_type.is_extension_type:
1389 # lhs = "(PyObject *)%s" % Naming.retval_cname
1391 lhs = Naming.retval_cname
1392 code.put_init_to_py_none(lhs, self.return_type)
1394 val = self.return_type.default_value
1396 code.putln("%s = %s;" % (Naming.retval_cname, val))
1397 # ----- Error cleanup
1398 if code.error_label in code.labels_used:
1399 code.put_goto(code.return_label)
1400 code.put_label(code.error_label)
1401 for cname, type in code.funcstate.all_managed_temps():
1402 code.put_xdecref(cname, type)
1404 # Clean up buffers -- this calls a Python function
1405 # so need to save and restore error state
1406 buffers_present = len(lenv.buffer_entries) > 0
1408 code.globalstate.use_utility_code(restore_exception_utility_code)
1409 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1410 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1411 for entry in lenv.buffer_entries:
1412 Buffer.put_release_buffer_code(code, entry)
1413 #code.putln("%s = 0;" % entry.cname)
1414 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1416 err_val = self.error_value()
1417 exc_check = self.caller_will_check_exceptions()
1418 if err_val is not None or exc_check:
1419 # TODO: Fix exception tracing (though currently unused by cProfile).
1420 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1421 # code.put_trace_exception()
1422 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1424 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1425 % self.entry.qualified_name, 0)
1427 '__Pyx_WriteUnraisable("%s");' %
1428 self.entry.qualified_name)
1429 env.use_utility_code(unraisable_exception_utility_code)
1430 env.use_utility_code(restore_exception_utility_code)
1431 default_retval = self.return_type.default_value
1432 if err_val is None and default_retval:
1433 err_val = default_retval
1434 if err_val is not None:
1435 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1437 if is_getbuffer_slot:
1438 self.getbuffer_error_cleanup(code)
1440 # If we are using the non-error cleanup section we should
1441 # jump past it if we have an error. The if-test below determine
1442 # whether this section is used.
1443 if buffers_present or is_getbuffer_slot:
1444 code.put_goto(code.return_from_error_cleanup_label)
1447 # ----- Non-error return cleanup
1448 code.put_label(code.return_label)
1449 for entry in lenv.buffer_entries:
1451 Buffer.put_release_buffer_code(code, entry)
1452 if is_getbuffer_slot:
1453 self.getbuffer_normal_cleanup(code)
1454 # ----- Return cleanup for both error and no-error return
1455 code.put_label(code.return_from_error_cleanup_label)
1456 if not Options.init_local_none:
1457 for entry in lenv.var_entries:
1458 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1459 entry.xdecref_cleanup = 1
1461 for entry in lenv.var_entries:
1462 if entry.type.is_pyobject:
1463 if entry.used and not entry.in_closure:
1464 code.put_var_decref(entry)
1465 # Decref any increfed args
1466 for entry in lenv.arg_entries:
1467 if entry.type.is_pyobject:
1468 if (acquire_gil or entry.assignments) and not entry.in_closure:
1469 code.put_var_decref(entry)
1470 if self.needs_closure:
1471 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1474 # This code is duplicated in ModuleNode.generate_module_init_func
1476 default_retval = self.return_type.default_value
1477 err_val = self.error_value()
1478 if err_val is None and default_retval:
1479 err_val = default_retval
1480 if self.return_type.is_pyobject:
1481 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1483 if self.entry.is_special and self.entry.name == "__hash__":
1484 # Returning -1 for __hash__ is supposed to signal an error
1485 # We do as Python instances and coerce -1 into -2.
1486 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1487 Naming.retval_cname, Naming.retval_cname))
1490 if self.return_type.is_pyobject:
1491 code.put_trace_return(Naming.retval_cname)
1493 code.put_trace_return("Py_None")
1495 code.put_finish_refcount_context()
1498 code.putln("#ifdef WITH_THREAD")
1499 code.putln("PyGILState_Release(_save);")
1500 code.putln("#endif")
1502 if not self.return_type.is_void:
1503 code.putln("return %s;" % Naming.retval_cname)
1507 if preprocessor_guard:
1508 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1510 # ----- Go back and insert temp variable declarations
1511 tempvardecl_code.put_temp_declarations(code.funcstate)
1512 # ----- Python version
1513 code.exit_cfunc_scope()
1515 self.py_func.generate_function_definitions(env, code)
1516 self.generate_wrapper_functions(code)
1518 def declare_argument(self, env, arg):
1519 if arg.type.is_void:
1520 error(arg.pos, "Invalid use of 'void'")
1521 elif not arg.type.is_complete() and not arg.type.is_array:
1523 "Argument type '%s' is incomplete" % arg.type)
1524 return env.declare_arg(arg.name, arg.type, arg.pos)
1526 def generate_arg_type_test(self, arg, code):
1527 # Generate type test for one argument.
1528 if arg.type.typeobj_is_available():
1529 code.globalstate.use_utility_code(arg_type_test_utility_code)
1530 typeptr_cname = arg.type.typeptr_cname
1531 arg_code = "((PyObject *)%s)" % arg.entry.cname
1533 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1538 arg.type.is_builtin_type,
1539 code.error_goto(arg.pos)))
1541 error(arg.pos, "Cannot test type of extern C class "
1542 "without type object name specification")
1544 def generate_arg_none_check(self, arg, code):
1545 # Generate None check for one argument.
1546 code.globalstate.use_utility_code(arg_type_test_utility_code)
1547 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1548 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1550 code.error_goto(arg.pos)))
1553 def generate_wrapper_functions(self, code):
1556 def generate_execution_code(self, code):
1557 # Evaluate and store argument default values
1558 for arg in self.args:
1559 default = arg.default
1561 if not default.is_literal:
1562 default.generate_evaluation_code(code)
1563 default.make_owned_reference(code)
1564 result = default.result_as(arg.type)
1567 arg.calculate_default_value_code(code),
1569 if arg.type.is_pyobject:
1570 code.put_giveref(default.result())
1571 default.generate_post_assignment_code(code)
1572 default.free_temps(code)
1573 # For Python class methods, create and store function object
1575 self.assmt.generate_execution_code(code)
1578 # Special code for the __getbuffer__ function
1580 def getbuffer_init(self, code):
1581 info = self.local_scope.arg_entries[1].cname
1582 # Python 3.0 betas have a bug in memoryview which makes it call
1583 # getbuffer with a NULL parameter. For now we work around this;
1584 # the following line should be removed when this bug is fixed.
1585 code.putln("if (%s == NULL) return 0;" % info)
1586 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1587 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1589 def getbuffer_error_cleanup(self, code):
1590 info = self.local_scope.arg_entries[1].cname
1591 code.put_gotref("%s->obj" % info)
1592 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1595 def getbuffer_normal_cleanup(self, code):
1596 info = self.local_scope.arg_entries[1].cname
1597 code.putln("if (%s->obj == Py_None) {" % info)
1598 code.put_gotref("Py_None")
1599 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1602 class CFuncDefNode(FuncDefNode):
1603 # C function definition.
1605 # modifiers ['inline']
1606 # visibility 'private' or 'public' or 'extern'
1607 # base_type CBaseTypeNode
1608 # declarator CDeclaratorNode
1611 # decorators [DecoratorNode] list of decorators
1613 # with_gil boolean Acquire GIL around body
1615 # py_func wrapper for calling from Python
1616 # overridable whether or not this is a cpdef function
1617 # inline_in_pxd whether this is an inline function in a pxd file
1619 child_attrs = ["base_type", "declarator", "body", "py_func"]
1621 inline_in_pxd = False
1623 directive_locals = {}
1625 def unqualified_name(self):
1626 return self.entry.name
1628 def analyse_declarations(self, env):
1629 self.directive_locals.update(env.directives['locals'])
1630 base_type = self.base_type.analyse(env)
1631 # The 2 here is because we need both function and argument names.
1632 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1633 if not type.is_cfunction:
1635 "Suite attached to non-function declaration")
1636 # Remember the actual type according to the function header
1637 # written here, because the type in the symbol table entry
1638 # may be different if we're overriding a C method inherited
1639 # from the base type of an extension type.
1641 type.is_overridable = self.overridable
1642 declarator = self.declarator
1643 while not hasattr(declarator, 'args'):
1644 declarator = declarator.base
1645 self.args = declarator.args
1646 for formal_arg, type_arg in zip(self.args, type.args):
1647 formal_arg.type = type_arg.type
1648 formal_arg.name = type_arg.name
1649 formal_arg.cname = type_arg.cname
1650 name = name_declarator.name
1651 cname = name_declarator.cname
1652 self.entry = env.declare_cfunction(
1653 name, type, self.pos,
1654 cname = cname, visibility = self.visibility,
1655 defining = self.body is not None,
1656 api = self.api, modifiers = self.modifiers)
1657 self.entry.inline_func_in_pxd = self.inline_in_pxd
1658 self.return_type = type.return_type
1660 if self.overridable and not env.is_module_scope:
1661 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1662 # An error will be produced in the cdef function
1663 self.overridable = False
1665 if self.overridable:
1667 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1668 self.py_func = DefNode(pos = self.pos,
1669 name = self.entry.name,
1672 starstar_arg = None,
1674 body = py_func_body,
1676 self.py_func.is_module_scope = env.is_module_scope
1677 self.py_func.analyse_declarations(env)
1678 self.entry.as_variable = self.py_func.entry
1679 # Reset scope entry the above cfunction
1680 env.entries[name] = self.entry
1681 if not env.is_module_scope or Options.lookup_module_cpdef:
1682 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1683 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1684 self.create_local_scope(env)
1686 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1688 args = self.type.args
1689 if omit_optional_args:
1690 args = args[:len(args) - self.type.optional_arg_count]
1691 arg_names = [arg.name for arg in args]
1693 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1695 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1696 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1697 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1698 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)
1699 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1701 def declare_arguments(self, env):
1702 for arg in self.type.args:
1704 error(arg.pos, "Missing argument name")
1705 self.declare_argument(env, arg)
1707 def need_gil_acquisition(self, lenv):
1708 return self.type.with_gil
1710 def nogil_check(self, env):
1712 with_gil = type.with_gil
1713 if type.nogil and not with_gil:
1714 if type.return_type.is_pyobject:
1716 "Function with Python return type cannot be declared nogil")
1717 for entry in self.local_scope.var_entries:
1718 if entry.type.is_pyobject:
1719 error(self.pos, "Function declared nogil has Python locals or temporaries")
1721 def analyse_expressions(self, env):
1722 self.local_scope.directives = env.directives
1723 if self.py_func is not None:
1724 # this will also analyse the default values
1725 self.py_func.analyse_expressions(env)
1727 self.analyse_default_values(env)
1728 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1730 def needs_assignment_synthesis(self, env, code=None):
1733 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1736 visibility = self.entry.visibility
1737 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1738 arg_decls.append(arg.declaration_code())
1739 if with_dispatch and self.overridable:
1740 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1741 if type.optional_arg_count and with_opt_args:
1742 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1743 if type.has_varargs:
1744 arg_decls.append("...")
1746 arg_decls = ["void"]
1748 cname = self.entry.func_cname
1749 entity = type.function_header_code(cname, ', '.join(arg_decls))
1750 if visibility == 'public':
1751 dll_linkage = "DL_EXPORT"
1754 header = self.return_type.declaration_code(entity,
1755 dll_linkage = dll_linkage)
1756 if visibility == 'extern':
1757 storage_class = "%s " % Naming.extern_c_macro
1758 elif visibility == 'public':
1761 storage_class = "static "
1762 if 'inline' in self.modifiers:
1763 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1764 code.putln("%s%s %s {" % (
1766 ' '.join(self.modifiers).upper(), # macro forms
1769 def generate_argument_declarations(self, env, code):
1770 for arg in self.args:
1772 result = arg.calculate_default_value_code(code)
1773 code.putln('%s = %s;' % (
1774 arg.type.declaration_code(arg.cname), result))
1776 def generate_keyword_list(self, code):
1779 def generate_argument_parsing_code(self, env, code):
1781 if self.type.optional_arg_count:
1782 code.putln('if (%s) {' % Naming.optional_args_cname)
1783 for arg in self.args:
1785 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1786 declarator = arg.declarator
1787 while not hasattr(declarator, 'name'):
1788 declarator = declarator.base
1789 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1791 for _ in range(self.type.optional_arg_count):
1795 def generate_argument_conversion_code(self, code):
1798 def generate_argument_type_tests(self, code):
1799 # Generate type tests for args whose type in a parent
1800 # class is a supertype of the declared type.
1801 for arg in self.type.args:
1802 if arg.needs_type_test:
1803 self.generate_arg_type_test(arg, code)
1804 elif arg.type.is_pyobject and not arg.accept_none:
1805 self.generate_arg_none_check(arg, code)
1807 def error_value(self):
1808 if self.return_type.is_pyobject:
1812 return self.entry.type.exception_value
1814 def caller_will_check_exceptions(self):
1815 return self.entry.type.exception_check
1817 def generate_wrapper_functions(self, code):
1818 # If the C signature of a function has changed, we need to generate
1819 # wrappers to put in the slots here.
1822 func_type = entry.type
1823 while entry.prev_entry is not None:
1825 entry = entry.prev_entry
1826 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1828 self.generate_function_header(code,
1830 with_dispatch = entry.type.is_overridable,
1831 with_opt_args = entry.type.optional_arg_count,
1832 cname = entry.func_cname)
1833 if not self.return_type.is_void:
1835 args = self.type.args
1836 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1837 if entry.type.is_overridable:
1838 arglist.append(Naming.skip_dispatch_cname)
1839 elif func_type.is_overridable:
1841 if entry.type.optional_arg_count:
1842 arglist.append(Naming.optional_args_cname)
1843 elif func_type.optional_arg_count:
1844 arglist.append('NULL')
1845 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1849 class PyArgDeclNode(Node):
1850 # Argument which must be a Python object (used
1851 # for * and ** arguments).
1854 # entry Symtab.Entry
1855 # annotation ExprNode or None Py3 argument annotation
1858 def generate_function_definitions(self, env, code):
1859 self.entry.generate_function_definitions(env, code)
1861 class DecoratorNode(Node):
1864 # decorator NameNode or CallNode or AttributeNode
1865 child_attrs = ['decorator']
1868 class DefNode(FuncDefNode):
1869 # A Python function definition.
1871 # name string the Python name of the function
1872 # lambda_name string the internal name of a lambda 'function'
1873 # decorators [DecoratorNode] list of decorators
1874 # args [CArgDeclNode] formal arguments
1875 # star_arg PyArgDeclNode or None * argument
1876 # starstar_arg PyArgDeclNode or None ** argument
1877 # doc EncodedString or None
1879 # return_type_annotation
1880 # ExprNode or None the Py3 return type annotation
1882 # The following subnode is constructed internally
1883 # when the def statement is inside a Python class definition.
1885 # assmt AssignmentNode Function construction/assignment
1887 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1892 num_required_kw_args = 0
1893 reqd_kw_flags_cname = "0"
1895 no_assignment_synthesis = 0
1897 return_type_annotation = None
1902 def __init__(self, pos, **kwds):
1903 FuncDefNode.__init__(self, pos, **kwds)
1905 for arg in self.args:
1912 self.num_kwonly_args = k
1913 self.num_required_kw_args = rk
1914 self.num_required_args = r
1916 def as_cfunction(self, cfunc=None, scope=None):
1918 error(self.star_arg.pos, "cdef function cannot have star argument")
1919 if self.starstar_arg:
1920 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1923 for formal_arg in self.args:
1924 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1925 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1927 type = py_object_type,
1928 pos = formal_arg.pos))
1929 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1931 has_varargs = False,
1932 exception_value = None,
1933 exception_check = False,
1936 is_overridable = True)
1937 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1941 cfunc_type = cfunc.type
1942 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1943 error(self.pos, "wrong number of arguments")
1944 error(cfunc.pos, "previous declaration here")
1945 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1946 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1947 is_self_arg = (i == 0 and scope.is_c_class_scope))
1948 if type is None or type is PyrexTypes.py_object_type:
1949 formal_arg.type = type_arg.type
1950 formal_arg.name_declarator = name_declarator
1952 if cfunc_type.exception_value is None:
1953 exception_value = None
1955 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1956 declarator = CFuncDeclaratorNode(self.pos,
1957 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1959 has_varargs = False,
1960 exception_check = cfunc_type.exception_check,
1961 exception_value = exception_value,
1962 with_gil = cfunc_type.with_gil,
1963 nogil = cfunc_type.nogil)
1964 return CFuncDefNode(self.pos,
1966 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1967 declarator = declarator,
1970 overridable = cfunc_type.is_overridable,
1972 with_gil = cfunc_type.with_gil,
1973 nogil = cfunc_type.nogil,
1974 visibility = 'private',
1976 directive_locals = getattr(cfunc, 'directive_locals', {}))
1978 def analyse_declarations(self, env):
1979 self.is_classmethod = self.is_staticmethod = False
1981 for decorator in self.decorators:
1982 func = decorator.decorator
1984 self.is_classmethod |= func.name == 'classmethod'
1985 self.is_staticmethod |= func.name == 'staticmethod'
1987 if self.is_classmethod and env.lookup_here('classmethod'):
1988 # classmethod() was overridden - not much we can do here ...
1989 self.is_classmethod = False
1990 if self.is_staticmethod and env.lookup_here('staticmethod'):
1991 # staticmethod() was overridden - not much we can do here ...
1992 self.is_staticmethod = False
1994 if self.name == '__new__' and env.is_py_class_scope:
1995 self.is_staticmethod = 1
1997 self.analyse_argument_types(env)
1998 if self.name == '<lambda>':
1999 self.declare_lambda_function(env)
2001 self.declare_pyfunction(env)
2002 self.analyse_signature(env)
2003 self.return_type = self.entry.signature.return_type()
2004 self.create_local_scope(env)
2006 def analyse_argument_types(self, env):
2007 directive_locals = self.directive_locals = env.directives['locals']
2008 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2009 for arg in self.args:
2010 if hasattr(arg, 'name'):
2012 name_declarator = None
2014 base_type = arg.base_type.analyse(env)
2015 name_declarator, type = \
2016 arg.declarator.analyse(base_type, env)
2017 arg.name = name_declarator.name
2018 if arg.name in directive_locals:
2019 type_node = directive_locals[arg.name]
2020 other_type = type_node.analyse_as_type(env)
2021 if other_type is None:
2022 error(type_node.pos, "Not a type")
2023 elif (type is not PyrexTypes.py_object_type
2024 and not type.same_as(other_type)):
2025 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2026 error(type_node.pos, "Previous declaration here")
2029 if name_declarator and name_declarator.cname:
2031 "Python function argument cannot have C name specification")
2032 arg.type = type.as_argument_type()
2034 arg.needs_conversion = 0
2035 arg.needs_type_test = 0
2037 if arg.type.is_pyobject:
2039 arg.accept_none = True
2041 arg.accept_none = False
2042 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2043 if arg.default and arg.default.constant_result is None:
2044 # special case: def func(MyType obj = None)
2045 arg.accept_none = True
2047 # default depends on compiler directive
2048 arg.accept_none = allow_none_for_extension_args
2050 # probably just a plain 'object'
2051 arg.accept_none = True
2053 arg.accept_none = True # won't be used, but must be there
2055 error(arg.pos, "Only Python type arguments can have 'not None'")
2057 error(arg.pos, "Only Python type arguments can have 'or None'")
2059 def analyse_signature(self, env):
2060 if self.entry.is_special:
2062 error(self.pos, "special functions of cdef classes cannot have decorators")
2063 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2064 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2065 # Use the simpler calling signature for zero- and one-argument functions.
2066 if self.entry.signature is TypeSlots.pyfunction_signature:
2067 if len(self.args) == 0:
2068 self.entry.signature = TypeSlots.pyfunction_noargs
2069 elif len(self.args) == 1:
2070 if self.args[0].default is None and not self.args[0].kw_only:
2071 self.entry.signature = TypeSlots.pyfunction_onearg
2072 elif self.entry.signature is TypeSlots.pymethod_signature:
2073 if len(self.args) == 1:
2074 self.entry.signature = TypeSlots.unaryfunc
2075 elif len(self.args) == 2:
2076 if self.args[1].default is None and not self.args[1].kw_only:
2077 self.entry.signature = TypeSlots.ibinaryfunc
2079 sig = self.entry.signature
2080 nfixed = sig.num_fixed_args()
2081 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2082 and len(self.args) == 0 and self.star_arg:
2083 # this is the only case where a diverging number of
2084 # arguments is not an error - when we have no explicit
2085 # 'self' parameter as in method(*args)
2086 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2087 self.self_in_stararg = 1
2090 for i in range(min(nfixed, len(self.args))):
2093 if sig.is_self_arg(i) and not self.is_staticmethod:
2094 if self.is_classmethod:
2096 arg.hdr_type = arg.type = Builtin.type_type
2099 arg.hdr_type = arg.type = env.parent_type
2100 arg.needs_conversion = 0
2102 arg.hdr_type = sig.fixed_arg_type(i)
2103 if not arg.type.same_as(arg.hdr_type):
2104 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2105 arg.needs_type_test = 1
2107 arg.needs_conversion = 1
2108 if arg.needs_conversion:
2109 arg.hdr_cname = Naming.arg_prefix + arg.name
2111 arg.hdr_cname = Naming.var_prefix + arg.name
2113 if nfixed > len(self.args):
2114 self.bad_signature()
2116 elif nfixed < len(self.args):
2117 if not sig.has_generic_args:
2118 self.bad_signature()
2119 for arg in self.args:
2120 if arg.is_generic and \
2121 (arg.type.is_extension_type or arg.type.is_builtin_type):
2122 arg.needs_type_test = 1
2124 def bad_signature(self):
2125 sig = self.entry.signature
2126 expected_str = "%d" % sig.num_fixed_args()
2127 if sig.has_generic_args:
2128 expected_str = expected_str + " or more"
2130 if name.startswith("__") and name.endswith("__"):
2131 desc = "Special method"
2135 "%s %s has wrong number of arguments "
2136 "(%d declared, %s expected)" % (
2137 desc, self.name, len(self.args), expected_str))
2139 def signature_has_nongeneric_args(self):
2140 argcount = len(self.args)
2141 if argcount == 0 or (
2142 argcount == 1 and (self.args[0].is_self_arg or
2143 self.args[0].is_type_arg)):
2147 def signature_has_generic_args(self):
2148 return self.entry.signature.has_generic_args
2150 def declare_pyfunction(self, env):
2151 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2153 entry = env.lookup_here(name)
2154 if entry and entry.type.is_cfunction and not self.is_wrapper:
2155 warning(self.pos, "Overriding cdef method with def method.", 5)
2156 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2158 prefix = env.next_id(env.scope_prefix)
2160 entry.func_cname = \
2161 Naming.pyfunc_prefix + prefix + name
2162 entry.pymethdef_cname = \
2163 Naming.pymethdef_prefix + prefix + name
2164 if Options.docstrings:
2165 entry.doc = embed_position(self.pos, self.doc)
2167 Naming.funcdoc_prefix + prefix + name
2168 if entry.is_special:
2169 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2170 entry.wrapperbase_cname = None
2172 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2176 def declare_lambda_function(self, env):
2178 prefix = env.scope_prefix
2180 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2181 entry = env.declare_lambda_function(func_cname, self.pos)
2182 entry.pymethdef_cname = \
2183 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2184 entry.qualified_name = env.qualify_name(self.lambda_name)
2188 def declare_arguments(self, env):
2189 for arg in self.args:
2191 error(arg.pos, "Missing argument name")
2193 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2194 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2195 if arg.needs_conversion:
2196 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2197 if arg.type.is_pyobject:
2198 arg.entry.init = "0"
2199 arg.entry.init_to_none = 0
2201 arg.entry = self.declare_argument(env, arg)
2203 arg.entry.is_self_arg = arg.is_self_arg
2205 if arg.is_self_arg or arg.is_type_arg or \
2206 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2207 arg.entry.is_declared_generic = 1
2208 self.declare_python_arg(env, self.star_arg)
2209 self.declare_python_arg(env, self.starstar_arg)
2211 def declare_python_arg(self, env, arg):
2213 if env.directives['infer_types'] != False:
2214 type = PyrexTypes.unspecified_type
2216 type = py_object_type
2217 entry = env.declare_var(arg.name, type, arg.pos)
2220 entry.init_to_none = 0
2221 entry.xdecref_cleanup = 1
2223 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2225 def analyse_expressions(self, env):
2226 self.local_scope.directives = env.directives
2227 self.analyse_default_values(env)
2228 if self.needs_assignment_synthesis(env):
2229 # Shouldn't we be doing this at the module level too?
2230 self.synthesize_assignment_node(env)
2232 def needs_assignment_synthesis(self, env, code=None):
2233 if self.no_assignment_synthesis:
2235 # Should enable for module level as well, that will require more testing...
2236 if self.entry.is_anonymous:
2238 if env.is_module_scope:
2240 return env.directives['binding']
2242 return code.globalstate.directives['binding']
2243 return env.is_py_class_scope or env.is_closure_scope
2245 def synthesize_assignment_node(self, env):
2248 while genv.is_py_class_scope or genv.is_c_class_scope:
2249 genv = genv.outer_scope
2251 if genv.is_closure_scope:
2252 rhs = ExprNodes.InnerFunctionNode(
2253 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2255 rhs = ExprNodes.PyCFunctionNode(
2256 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2258 if env.is_py_class_scope:
2259 if not self.is_staticmethod and not self.is_classmethod:
2262 self.assmt = SingleAssignmentNode(self.pos,
2263 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2265 self.assmt.analyse_declarations(env)
2266 self.assmt.analyse_expressions(env)
2268 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2270 sig = self.entry.signature
2271 if sig.has_dummy_arg or self.self_in_stararg:
2272 arg_code_list.append(
2273 "PyObject *%s" % Naming.self_cname)
2274 for arg in self.args:
2275 if not arg.is_generic:
2276 if arg.is_self_arg or arg.is_type_arg:
2277 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2279 arg_code_list.append(
2280 arg.hdr_type.declaration_code(arg.hdr_cname))
2281 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2282 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2283 if sig.has_generic_args:
2284 arg_code_list.append(
2285 "PyObject *%s, PyObject *%s"
2286 % (Naming.args_cname, Naming.kwds_cname))
2287 arg_code = ", ".join(arg_code_list)
2288 dc = self.return_type.declaration_code(self.entry.func_cname)
2289 mf = " ".join(self.modifiers).upper()
2291 header = "static %s%s(%s)" % (mf, dc, arg_code)
2292 code.putln("%s; /*proto*/" % header)
2295 if (Options.docstrings and self.entry.doc and
2296 not self.entry.scope.is_property_scope and
2297 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2298 docstr = self.entry.doc
2299 if docstr.is_unicode:
2300 docstr = docstr.utf8encode()
2302 'static char %s[] = "%s";' % (
2303 self.entry.doc_cname,
2304 split_string_literal(escape_byte_string(docstr))))
2305 if self.entry.is_special:
2307 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2310 "static PyMethodDef %s = " %
2311 self.entry.pymethdef_cname)
2312 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2313 code.putln("%s {" % header)
2315 def generate_argument_declarations(self, env, code):
2316 for arg in self.args:
2317 if arg.is_generic: # or arg.needs_conversion:
2318 if arg.needs_conversion:
2319 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2320 elif not arg.entry.in_closure:
2321 code.put_var_declaration(arg.entry)
2323 def generate_keyword_list(self, code):
2324 if self.signature_has_generic_args() and \
2325 self.signature_has_nongeneric_args():
2327 "static PyObject **%s[] = {" %
2328 Naming.pykwdlist_cname)
2329 for arg in self.args:
2331 pystring_cname = code.intern_identifier(arg.name)
2332 code.put('&%s,' % pystring_cname)
2335 def generate_argument_parsing_code(self, env, code):
2336 # Generate fast equivalent of PyArg_ParseTuple call for
2337 # generic arguments, if any, including args/kwargs
2338 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2339 # get rid of unused argument warning
2340 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2342 old_error_label = code.new_error_label()
2343 our_error_label = code.error_label
2344 end_label = code.new_label("argument_unpacking_done")
2346 has_kwonly_args = self.num_kwonly_args > 0
2347 has_star_or_kw_args = self.star_arg is not None \
2348 or self.starstar_arg is not None or has_kwonly_args
2350 for arg in self.args:
2351 if not arg.type.is_pyobject:
2352 done = arg.type.create_from_py_utility_code(env)
2353 if not done: pass # will fail later
2355 if not self.signature_has_generic_args():
2356 if has_star_or_kw_args:
2357 error(self.pos, "This method cannot have * or keyword arguments")
2358 self.generate_argument_conversion_code(code)
2360 elif not self.signature_has_nongeneric_args():
2361 # func(*args) or func(**kw) or func(*args, **kw)
2362 self.generate_stararg_copy_code(code)
2365 positional_args = []
2367 for arg in self.args:
2368 arg_entry = arg.entry
2371 if not arg.is_self_arg and not arg.is_type_arg:
2373 kw_only_args.append(arg)
2375 positional_args.append(arg)
2377 kw_only_args.append(arg)
2378 elif not arg.is_self_arg and not arg.is_type_arg:
2379 positional_args.append(arg)
2381 self.generate_tuple_and_keyword_parsing_code(
2382 positional_args, kw_only_args, end_label, code)
2384 code.error_label = old_error_label
2385 if code.label_used(our_error_label):
2386 if not code.label_used(end_label):
2387 code.put_goto(end_label)
2388 code.put_label(our_error_label)
2389 if has_star_or_kw_args:
2390 self.generate_arg_decref(self.star_arg, code)
2391 if self.starstar_arg:
2392 if self.starstar_arg.entry.xdecref_cleanup:
2393 code.put_var_xdecref_clear(self.starstar_arg.entry)
2395 code.put_var_decref_clear(self.starstar_arg.entry)
2396 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2397 # The arguments are put into the closure one after the
2398 # other, so when type errors are found, all references in
2399 # the closure instance must be properly ref-counted to
2400 # facilitate generic closure instance deallocation. In
2401 # the case of an argument type error, it's best to just
2402 # DECREF+clear the already handled references, as this
2403 # frees their references as early as possible.
2404 for arg in self.args:
2405 if arg.type.is_pyobject and arg.entry.in_closure:
2406 code.put_var_xdecref_clear(arg.entry)
2407 if self.needs_closure:
2408 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2409 code.put_finish_refcount_context()
2410 code.putln("return %s;" % self.error_value())
2411 if code.label_used(end_label):
2412 code.put_label(end_label)
2414 # fix refnanny view on closure variables here, instead of
2415 # doing it separately for each arg parsing special case
2416 if self.star_arg and self.star_arg.entry.in_closure:
2417 code.put_var_giveref(self.star_arg.entry)
2418 if self.starstar_arg and self.starstar_arg.entry.in_closure:
2419 code.put_var_giveref(self.starstar_arg.entry)
2420 for arg in self.args:
2421 if arg.type.is_pyobject and arg.entry.in_closure:
2422 code.put_var_giveref(arg.entry)
2424 def generate_arg_assignment(self, arg, item, code):
2425 if arg.type.is_pyobject:
2427 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2429 if entry.in_closure:
2430 code.put_incref(item, PyrexTypes.py_object_type)
2431 code.putln("%s = %s;" % (entry.cname, item))
2433 func = arg.type.from_py_function
2435 code.putln("%s = %s(%s); %s" % (
2439 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2441 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2443 def generate_arg_xdecref(self, arg, code):
2445 code.put_var_xdecref_clear(arg.entry)
2447 def generate_arg_decref(self, arg, code):
2449 code.put_var_decref_clear(arg.entry)
2451 def generate_stararg_copy_code(self, code):
2452 if not self.star_arg:
2453 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2454 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2456 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2457 self.name, Naming.args_cname, self.error_value()))
2460 if self.starstar_arg:
2462 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2464 kwarg_check = "%s" % Naming.kwds_cname
2466 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2467 Naming.kwds_cname, Naming.kwds_cname)
2468 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2470 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2471 kwarg_check, Naming.kwds_cname, self.name,
2472 bool(self.starstar_arg), self.error_value()))
2474 if self.starstar_arg:
2475 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2476 self.starstar_arg.entry.cname,
2479 code.putln("if (unlikely(!%s)) return %s;" % (
2480 self.starstar_arg.entry.cname, self.error_value()))
2481 self.starstar_arg.entry.xdecref_cleanup = 0
2482 code.put_gotref(self.starstar_arg.entry.cname)
2484 if self.self_in_stararg:
2485 # need to create a new tuple with 'self' inserted as first item
2486 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2487 self.star_arg.entry.cname,
2489 self.star_arg.entry.cname))
2490 if self.starstar_arg:
2492 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2493 code.putln("return %s;" % self.error_value())
2496 code.putln("return %s;" % self.error_value())
2497 code.put_gotref(self.star_arg.entry.cname)
2498 code.put_incref(Naming.self_cname, py_object_type)
2499 code.put_giveref(Naming.self_cname)
2500 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2501 self.star_arg.entry.cname, Naming.self_cname))
2502 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2503 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2504 temp, temp, Naming.args_cname, temp))
2505 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2506 Naming.args_cname, temp))
2507 code.put_incref("item", py_object_type)
2508 code.put_giveref("item")
2509 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2510 self.star_arg.entry.cname, temp))
2512 code.funcstate.release_temp(temp)
2513 self.star_arg.entry.xdecref_cleanup = 0
2515 code.put_incref(Naming.args_cname, py_object_type)
2516 code.putln("%s = %s;" % (
2517 self.star_arg.entry.cname,
2519 self.star_arg.entry.xdecref_cleanup = 0
2521 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2522 kw_only_args, success_label, code):
2523 argtuple_error_label = code.new_label("argtuple_error")
2525 min_positional_args = self.num_required_args - self.num_required_kw_args
2526 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2527 min_positional_args -= 1
2528 max_positional_args = len(positional_args)
2529 has_fixed_positional_count = not self.star_arg and \
2530 min_positional_args == max_positional_args
2532 if self.num_required_kw_args:
2533 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2535 if self.starstar_arg or self.star_arg:
2536 self.generate_stararg_init_code(max_positional_args, code)
2538 # --- optimised code when we receive keyword arguments
2539 if self.num_required_kw_args:
2540 likely_hint = "likely"
2542 likely_hint = "unlikely"
2543 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2544 self.generate_keyword_unpacking_code(
2545 min_positional_args, max_positional_args,
2546 has_fixed_positional_count,
2547 positional_args, kw_only_args, argtuple_error_label, code)
2549 # --- optimised code when we do not receive any keyword arguments
2550 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2551 # Python raises arg tuple related errors first, so we must
2552 # check the length here
2553 if min_positional_args == max_positional_args and not self.star_arg:
2557 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2558 Naming.args_cname, compare, min_positional_args))
2559 code.put_goto(argtuple_error_label)
2561 if self.num_required_kw_args:
2562 # pure error case: keywords required but not passed
2563 if max_positional_args > min_positional_args and not self.star_arg:
2564 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2565 Naming.args_cname, max_positional_args))
2566 code.put_goto(argtuple_error_label)
2567 code.putln('} else {')
2568 for i, arg in enumerate(kw_only_args):
2570 pystring_cname = code.intern_identifier(arg.name)
2571 # required keyword-only argument missing
2572 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2575 code.putln(code.error_goto(self.pos))
2578 elif min_positional_args == max_positional_args:
2579 # parse the exact number of positional arguments from the
2581 code.putln('} else {')
2582 for i, arg in enumerate(positional_args):
2583 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2584 self.generate_arg_assignment(arg, item, code)
2585 self.generate_arg_default_assignments(code)
2588 # parse the positional arguments from the variable length
2590 code.putln('} else {')
2591 self.generate_arg_default_assignments(code)
2592 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2594 code.putln('default:')
2595 reversed_args = list(enumerate(positional_args))[::-1]
2596 for i, arg in reversed_args:
2597 if i >= min_positional_args-1:
2598 if min_positional_args > 1:
2599 code.putln('case %2d:' % (i+1)) # pure code beautification
2601 code.put('case %2d: ' % (i+1))
2602 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2603 self.generate_arg_assignment(arg, item, code)
2604 if min_positional_args == 0:
2605 code.put('case 0: ')
2606 code.putln('break;')
2608 if min_positional_args:
2609 for i in range(min_positional_args-1, -1, -1):
2610 code.putln('case %2d:' % i)
2611 code.put_goto(argtuple_error_label)
2613 code.put('default: ')
2614 code.put_goto(argtuple_error_label)
2619 if code.label_used(argtuple_error_label):
2620 code.put_goto(success_label)
2621 code.put_label(argtuple_error_label)
2622 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2623 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2624 self.name, has_fixed_positional_count,
2625 min_positional_args, max_positional_args,
2627 code.putln(code.error_goto(self.pos))
2629 def generate_arg_default_assignments(self, code):
2630 for arg in self.args:
2631 if arg.is_generic and arg.default:
2635 arg.calculate_default_value_code(code)))
2637 def generate_stararg_init_code(self, max_positional_args, code):
2638 if self.starstar_arg:
2639 self.starstar_arg.entry.xdecref_cleanup = 0
2640 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2641 self.starstar_arg.entry.cname,
2642 self.starstar_arg.entry.cname,
2643 self.error_value()))
2644 code.put_gotref(self.starstar_arg.entry.cname)
2646 self.star_arg.entry.xdecref_cleanup = 0
2647 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2649 max_positional_args))
2650 code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2651 self.star_arg.entry.cname, Naming.args_cname,
2652 max_positional_args, Naming.args_cname))
2653 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2654 if self.starstar_arg:
2655 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2656 if self.needs_closure:
2657 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2658 code.put_finish_refcount_context()
2659 code.putln('return %s;' % self.error_value())
2661 code.put_gotref(self.star_arg.entry.cname)
2662 code.putln('} else {')
2663 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2664 code.put_incref(Naming.empty_tuple, py_object_type)
2667 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2668 has_fixed_positional_count, positional_args,
2669 kw_only_args, argtuple_error_label, code):
2670 all_args = tuple(positional_args) + tuple(kw_only_args)
2671 max_args = len(all_args)
2673 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2675 # the 'values' array collects borrowed references to arguments
2676 # before doing any type coercion etc.
2677 code.putln("PyObject* values[%d] = {%s};" % (
2678 max_args, ','.join('0'*max_args)))
2680 # assign borrowed Python default values to the values array,
2681 # so that they can be overwritten by received arguments below
2682 for i, arg in enumerate(all_args):
2683 if arg.default and arg.type.is_pyobject:
2684 default_value = arg.calculate_default_value_code(code)
2685 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2687 # parse the args tuple and check that it's not too long
2688 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2690 code.putln('default:')
2691 for i in range(max_positional_args-1, -1, -1):
2692 code.put('case %2d: ' % (i+1))
2693 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2694 i, Naming.args_cname, i))
2695 code.putln('case 0: break;')
2696 if not self.star_arg:
2697 code.put('default: ') # more arguments than allowed
2698 code.put_goto(argtuple_error_label)
2701 # now fill up the positional/required arguments with values
2703 if self.num_required_args or max_positional_args > 0:
2704 last_required_arg = -1
2705 for i, arg in enumerate(all_args):
2707 last_required_arg = i
2708 if last_required_arg < max_positional_args:
2709 last_required_arg = max_positional_args-1
2710 num_required_args = self.num_required_args
2711 if max_positional_args > 0:
2712 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2713 for i, arg in enumerate(all_args[:last_required_arg+1]):
2714 if max_positional_args > 0 and i <= max_positional_args:
2715 if self.star_arg and i == max_positional_args:
2716 code.putln('default:')
2718 code.putln('case %2d:' % i)
2719 pystring_cname = code.intern_identifier(arg.name)
2722 # handled separately below
2724 code.putln('if (kw_args > 0) {')
2725 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2726 Naming.kwds_cname, pystring_cname))
2727 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2730 num_required_args -= 1
2731 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2732 i, Naming.kwds_cname, pystring_cname))
2733 code.putln('if (likely(values[%d])) kw_args--;' % i);
2734 if i < min_positional_args:
2736 # special case: we know arg 0 is missing
2738 code.put_goto(argtuple_error_label)
2740 # print the correct number of values (args or
2741 # kwargs) that were passed into positional
2742 # arguments up to this point
2743 code.putln('else {')
2744 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2745 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2746 self.name, has_fixed_positional_count,
2747 min_positional_args, max_positional_args, i))
2748 code.putln(code.error_goto(self.pos))
2751 code.putln('else {')
2752 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2753 self.name, pystring_cname))
2754 code.putln(code.error_goto(self.pos))
2756 if max_positional_args > 0:
2759 if kw_only_args and not self.starstar_arg:
2760 # unpack optional keyword-only arguments
2761 # checking for interned strings in a dict is faster than iterating
2762 # but it's too likely that we must iterate if we expect **kwargs
2764 for i, arg in enumerate(all_args[max_positional_args:]):
2765 if not arg.kw_only or not arg.default:
2767 optional_args.append((i+max_positional_args, arg))
2769 # this mimics an unrolled loop so that we can "break" out of it
2770 code.putln('while (kw_args > 0) {')
2771 code.putln('PyObject* value;')
2772 for i, arg in optional_args:
2773 pystring_cname = code.intern_identifier(arg.name)
2775 'value = PyDict_GetItem(%s, %s);' % (
2776 Naming.kwds_cname, pystring_cname))
2778 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2779 code.putln('break;')
2782 code.putln('if (unlikely(kw_args > 0)) {')
2783 # non-positional/-required kw args left in dict: default args,
2784 # kw-only args, **kwargs or error
2786 # This is sort of a catch-all: except for checking required
2787 # arguments, this will always do the right thing for unpacking
2788 # keyword arguments, so that we can concentrate on optimising
2789 # common cases above.
2790 if max_positional_args == 0:
2793 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2794 Naming.args_cname, max_positional_args,
2795 Naming.args_cname, max_positional_args))
2796 pos_arg_count = "used_pos_args"
2798 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2799 code.globalstate.use_utility_code(parse_keywords_utility_code)
2801 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2803 Naming.pykwdlist_cname,
2804 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2807 code.putln(code.error_goto(self.pos))
2810 # convert arg values to their final type and assign them
2811 for i, arg in enumerate(all_args):
2812 if arg.default and not arg.type.is_pyobject:
2813 code.putln("if (values[%d]) {" % i)
2814 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2815 if arg.default and not arg.type.is_pyobject:
2816 code.putln('} else {')
2820 arg.calculate_default_value_code(code)))
2823 def generate_argument_conversion_code(self, code):
2824 # Generate code to convert arguments from signature type to
2825 # declared type, if needed. Also copies signature arguments
2826 # into closure fields.
2827 for arg in self.args:
2828 if arg.needs_conversion:
2829 self.generate_arg_conversion(arg, code)
2830 elif arg.entry.in_closure:
2831 if arg.type.is_pyobject:
2832 code.put_incref(arg.hdr_cname, py_object_type)
2833 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2835 def generate_arg_conversion(self, arg, code):
2836 # Generate conversion code for one argument.
2837 old_type = arg.hdr_type
2839 if old_type.is_pyobject:
2841 code.putln("if (%s) {" % arg.hdr_cname)
2843 code.putln("assert(%s); {" % arg.hdr_cname)
2844 self.generate_arg_conversion_from_pyobject(arg, code)
2846 elif new_type.is_pyobject:
2847 self.generate_arg_conversion_to_pyobject(arg, code)
2849 if new_type.assignable_from(old_type):
2851 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2854 "Cannot convert 1 argument from '%s' to '%s'" %
2855 (old_type, new_type))
2857 def generate_arg_conversion_from_pyobject(self, arg, code):
2859 func = new_type.from_py_function
2860 # copied from CoerceFromPyTypeNode
2862 lhs = arg.entry.cname
2863 rhs = "%s(%s)" % (func, arg.hdr_cname)
2864 if new_type.is_enum:
2865 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2866 code.putln("%s = %s; %s" % (
2869 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2872 "Cannot convert Python object argument to type '%s'"
2875 def generate_arg_conversion_to_pyobject(self, arg, code):
2876 old_type = arg.hdr_type
2877 func = old_type.to_py_function
2879 code.putln("%s = %s(%s); %s" % (
2883 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2884 code.put_var_gotref(arg.entry)
2887 "Cannot convert argument of type '%s' to Python object"
2890 def generate_argument_type_tests(self, code):
2891 # Generate type tests for args whose signature
2892 # type is PyObject * and whose declared type is
2893 # a subtype thereof.
2894 for arg in self.args:
2895 if arg.needs_type_test:
2896 self.generate_arg_type_test(arg, code)
2897 elif not arg.accept_none and arg.type.is_pyobject:
2898 self.generate_arg_none_check(arg, code)
2900 def error_value(self):
2901 return self.entry.signature.error_value
2903 def caller_will_check_exceptions(self):
2907 class GeneratorDefNode(DefNode):
2908 # Generator DefNode.
2910 # gbody GeneratorBodyDefNode
2914 needs_closure = True
2916 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators", "gbody"]
2918 def __init__(self, **kwargs):
2919 # XXX: don't actually needs a body
2920 kwargs['body'] = StatListNode(kwargs['pos'], stats=[])
2921 super(GeneratorDefNode, self).__init__(**kwargs)
2923 def analyse_declarations(self, env):
2924 super(GeneratorDefNode, self).analyse_declarations(env)
2925 self.gbody.local_scope = self.local_scope
2926 self.gbody.analyse_declarations(env)
2928 def generate_function_body(self, env, code):
2929 body_cname = self.gbody.entry.func_cname
2930 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
2932 code.putln('%s.resume_label = 0;' % generator_cname)
2933 code.putln('%s.body = (__pyx_generator_body_t) %s;' % (generator_cname, body_cname))
2934 code.put_giveref(Naming.cur_scope_cname)
2935 code.put_finish_refcount_context()
2936 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
2938 def generate_function_definitions(self, env, code):
2939 self.gbody.generate_function_header(code, proto=True)
2940 super(GeneratorDefNode, self).generate_function_definitions(env, code)
2941 self.gbody.generate_function_definitions(env, code)
2944 class GeneratorBodyDefNode(DefNode):
2945 # Generator body DefNode.
2948 is_generator_body = True
2950 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
2952 def __init__(self, pos=None, name=None, body=None):
2953 super(GeneratorBodyDefNode, self).__init__(pos=pos, body=body, name=name, doc=None,
2955 star_arg=None, starstar_arg=None)
2957 def declare_generator_body(self, env):
2958 prefix = env.next_id(env.scope_prefix)
2959 name = env.next_id('generator')
2960 entry = env.declare_var(prefix + name, py_object_type, self.pos, visibility='private')
2961 entry.func_cname = Naming.genbody_prefix + prefix + name
2962 entry.qualified_name = EncodedString(self.name)
2965 def analyse_declarations(self, env):
2966 self.analyse_argument_types(env)
2967 self.declare_generator_body(env)
2969 def generate_function_header(self, code, proto=False):
2970 header = "static PyObject *%s(%s, PyObject *%s)" % (
2971 self.entry.func_cname,
2972 self.local_scope.scope_class.type.declaration_code(Naming.cur_scope_cname),
2973 Naming.sent_value_cname)
2975 code.putln('%s; /* proto */' % header)
2977 code.putln('%s /* generator body */\n{' % header);
2979 def generate_function_definitions(self, env, code):
2980 lenv = self.local_scope
2982 # Generate closure function definitions
2983 self.body.generate_function_definitions(lenv, code)
2984 # generate lambda function definitions
2985 self.generate_lambda_definitions(lenv, code)
2987 # Generate C code for header and body of function
2988 code.enter_cfunc_scope()
2989 code.return_from_error_cleanup_label = code.new_label()
2991 # ----- Top-level constants used by this function
2992 code.mark_pos(self.pos)
2993 self.generate_cached_builtins_decls(lenv, code)
2994 # ----- Function header
2996 self.generate_function_header(code)
2997 # ----- Local variables
2998 code.putln("PyObject *%s = NULL;" % Naming.retval_cname)
2999 tempvardecl_code = code.insertion_point()
3000 code.put_declare_refcount_context()
3001 code.put_setup_refcount_context(self.entry.name)
3003 # ----- Resume switch point.
3004 code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
3005 resume_code = code.insertion_point()
3006 first_run_label = code.new_label('first_run')
3007 code.use_label(first_run_label)
3008 code.put_label(first_run_label)
3010 (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
3012 # ----- Function body
3013 self.generate_function_body(env, code)
3014 code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
3015 # ----- Error cleanup
3016 if code.error_label in code.labels_used:
3017 code.put_goto(code.return_label)
3018 code.put_label(code.error_label)
3019 for cname, type in code.funcstate.all_managed_temps():
3020 code.put_xdecref(cname, type)
3021 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
3022 # XXX: ^^^ is this enough?
3024 # ----- Non-error return cleanup
3025 code.put_label(code.return_label)
3026 code.put_xdecref(Naming.retval_cname, py_object_type)
3027 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
3028 code.put_finish_refcount_context()
3029 code.putln('return NULL;');
3032 # ----- Go back and insert temp variable declarations
3033 tempvardecl_code.put_temp_declarations(code.funcstate)
3034 # ----- Generator resume code
3035 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
3036 resume_code.putln("case 0: goto %s;" % first_run_label)
3038 from ParseTreeTransforms import YieldNodeCollector
3039 collector = YieldNodeCollector()
3040 collector.visitchildren(self)
3041 for yield_expr in collector.yields:
3042 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
3043 resume_code.putln("default: /* CPython raises the right error here */");
3044 resume_code.put_finish_refcount_context()
3045 resume_code.putln("return NULL;");
3046 resume_code.putln("}");
3048 code.exit_cfunc_scope()
3051 class OverrideCheckNode(StatNode):
3052 # A Node for dispatching to the def method if it
3061 child_attrs = ['body']
3065 def analyse_expressions(self, env):
3066 self.args = env.arg_entries
3067 if self.py_func.is_module_scope:
3072 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3073 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3074 call_node = ExprNodes.SimpleCallNode(self.pos,
3075 function=self.func_node,
3076 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3077 self.body = ReturnStatNode(self.pos, value=call_node)
3078 self.body.analyse_expressions(env)
3080 def generate_execution_code(self, code):
3081 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3082 # Check to see if we are an extension type
3083 if self.py_func.is_module_scope:
3084 self_arg = "((PyObject *)%s)" % Naming.module_cname
3086 self_arg = "((PyObject *)%s)" % self.args[0].cname
3087 code.putln("/* Check if called by wrapper */")
3088 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3089 code.putln("/* Check if overriden in Python */")
3090 if self.py_func.is_module_scope:
3091 code.putln("else {")
3093 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3094 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3095 self.func_node.set_cname(func_node_temp)
3096 # need to get attribute manually--scope would return cdef method
3097 err = code.error_goto_if_null(func_node_temp, self.pos)
3098 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3099 func_node_temp, self_arg, interned_attr_cname, err))
3100 code.put_gotref(func_node_temp)
3101 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3102 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3103 func_node_temp, self.py_func.entry.func_cname)
3104 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3105 self.body.generate_execution_code(code)
3107 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3108 code.funcstate.release_temp(func_node_temp)
3111 class ClassDefNode(StatNode, BlockNode):
3114 class PyClassDefNode(ClassDefNode):
3115 # A Python class definition.
3117 # name EncodedString Name of the class
3118 # doc string or None
3119 # body StatNode Attribute definition code
3120 # entry Symtab.Entry
3121 # scope PyClassScope
3122 # decorators [DecoratorNode] list of decorators or None
3124 # The following subnodes are constructed internally:
3126 # dict DictNode Class dictionary or Py3 namespace
3127 # classobj ClassNode Class object
3128 # target NameNode Variable to assign class object to
3130 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3132 py3_style_class = False # Python3 style class (bases+kwargs)
3134 def __init__(self, pos, name, bases, doc, body, decorators = None,
3135 keyword_args = None, starstar_arg = None):
3136 StatNode.__init__(self, pos)
3140 self.decorators = decorators
3142 if self.doc and Options.docstrings:
3143 doc = embed_position(self.pos, self.doc)
3144 doc_node = ExprNodes.StringNode(pos, value = doc)
3147 if keyword_args or starstar_arg:
3148 self.py3_style_class = True
3150 self.metaclass = None
3151 if keyword_args and not starstar_arg:
3152 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3153 if item.key.value == 'metaclass':
3154 if self.metaclass is not None:
3155 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3156 # special case: we already know the metaclass,
3157 # so we don't need to do the "build kwargs,
3158 # find metaclass" dance at runtime
3159 self.metaclass = item.value
3160 del keyword_args.key_value_pairs[i]
3161 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3162 self.mkw = ExprNodes.KeywordArgsNode(
3163 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3165 self.mkw = ExprNodes.NullNode(pos)
3166 if self.metaclass is None:
3167 self.metaclass = ExprNodes.PyClassMetaclassNode(
3168 pos, mkw = self.mkw, bases = self.bases)
3169 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3170 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3172 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3173 bases = self.bases, dict = self.dict, doc = doc_node,
3174 metaclass = self.metaclass, mkw = self.mkw)
3176 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3177 self.metaclass = None
3180 self.classobj = ExprNodes.ClassNode(pos, name = name,
3181 bases = bases, dict = self.dict, doc = doc_node)
3182 self.target = ExprNodes.NameNode(pos, name = name)
3184 def as_cclass(self):
3186 Return this node as if it were declared as an extension class
3188 if self.py3_style_class:
3189 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3191 bases = self.classobj.bases.args
3193 base_class_name = None
3194 base_class_module = None
3195 elif len(bases) == 1:
3198 from ExprNodes import AttributeNode, NameNode
3199 while isinstance(base, AttributeNode):
3200 path.insert(0, base.attribute)
3202 if isinstance(base, NameNode):
3203 path.insert(0, base.name)
3204 base_class_name = path[-1]
3206 base_class_module = u'.'.join(path[:-1])
3208 base_class_module = None
3210 error(self.classobj.bases.args.pos, "Invalid base class")
3212 error(self.classobj.bases.args.pos, "C class may only have one base class")
3215 return CClassDefNode(self.pos,
3216 visibility = 'private',
3218 class_name = self.name,
3219 base_class_module = base_class_module,
3220 base_class_name = base_class_name,
3221 decorators = self.decorators,
3226 def create_scope(self, env):
3228 while genv.is_py_class_scope or genv.is_c_class_scope:
3229 genv = genv.outer_scope
3230 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3233 def analyse_declarations(self, env):
3234 self.target.analyse_target_declaration(env)
3235 cenv = self.create_scope(env)
3236 cenv.directives = env.directives
3237 cenv.class_obj_cname = self.target.entry.cname
3238 self.body.analyse_declarations(cenv)
3240 def analyse_expressions(self, env):
3241 if self.py3_style_class:
3242 self.bases.analyse_expressions(env)
3243 self.metaclass.analyse_expressions(env)
3244 self.mkw.analyse_expressions(env)
3245 self.dict.analyse_expressions(env)
3246 self.classobj.analyse_expressions(env)
3247 genv = env.global_scope()
3249 self.body.analyse_expressions(cenv)
3250 self.target.analyse_target_expression(env, self.classobj)
3252 def generate_function_definitions(self, env, code):
3253 self.generate_lambda_definitions(self.scope, code)
3254 self.body.generate_function_definitions(self.scope, code)
3256 def generate_execution_code(self, code):
3257 code.pyclass_stack.append(self)
3259 if self.py3_style_class:
3260 self.bases.generate_evaluation_code(code)
3261 self.mkw.generate_evaluation_code(code)
3262 self.metaclass.generate_evaluation_code(code)
3263 self.dict.generate_evaluation_code(code)
3264 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3265 self.body.generate_execution_code(code)
3266 self.classobj.generate_evaluation_code(code)
3267 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3268 self.target.generate_assignment_code(self.classobj, code)
3269 self.dict.generate_disposal_code(code)
3270 self.dict.free_temps(code)
3271 if self.py3_style_class:
3272 self.mkw.generate_disposal_code(code)
3273 self.mkw.free_temps(code)
3274 self.metaclass.generate_disposal_code(code)
3275 self.metaclass.free_temps(code)
3276 self.bases.generate_disposal_code(code)
3277 self.bases.free_temps(code)
3278 code.pyclass_stack.pop()
3280 class CClassDefNode(ClassDefNode):
3281 # An extension type definition.
3283 # visibility 'private' or 'public' or 'extern'
3284 # typedef_flag boolean
3286 # module_name string or None For import of extern type objects
3287 # class_name string Unqualified name of class
3288 # as_name string or None Name to declare as in this scope
3289 # base_class_module string or None Module containing the base class
3290 # base_class_name string or None Name of the base class
3291 # objstruct_name string or None Specified C name of object struct
3292 # typeobj_name string or None Specified C name of type object
3293 # in_pxd boolean Is in a .pxd file
3294 # decorators [DecoratorNode] list of decorators or None
3295 # doc string or None
3296 # body StatNode or None
3297 # entry Symtab.Entry
3298 # base_type PyExtensionType or None
3299 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3300 # buffer_defaults_pos
3302 child_attrs = ["body"]
3303 buffer_defaults_node = None
3304 buffer_defaults_pos = None
3305 typedef_flag = False
3307 objstruct_name = None
3311 def analyse_declarations(self, env):
3312 #print "CClassDefNode.analyse_declarations:", self.class_name
3313 #print "...visibility =", self.visibility
3314 #print "...module_name =", self.module_name
3317 if self.buffer_defaults_node:
3318 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3319 env, [], self.buffer_defaults_node,
3320 need_complete=False)
3322 buffer_defaults = None
3324 if env.in_cinclude and not self.objstruct_name:
3325 error(self.pos, "Object struct name specification required for "
3326 "C class defined in 'extern from' block")
3327 self.base_type = None
3328 # Now that module imports are cached, we need to
3329 # import the modules for extern classes.
3330 if self.module_name:
3332 for module in env.cimported_modules:
3333 if module.name == self.module_name:
3334 self.module = module
3335 if self.module is None:
3336 self.module = ModuleScope(self.module_name, None, env.context)
3337 self.module.has_extern_class = 1
3338 env.add_imported_module(self.module)
3340 if self.base_class_name:
3341 if self.base_class_module:
3342 base_class_scope = env.find_module(self.base_class_module, self.pos)
3344 base_class_scope = env
3345 if self.base_class_name == 'object':
3346 # extension classes are special and don't need to inherit from object
3347 if base_class_scope is None or base_class_scope.lookup('object') is None:
3348 self.base_class_name = None
3349 self.base_class_module = None
3350 base_class_scope = None
3351 if base_class_scope:
3352 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3353 if base_class_entry:
3354 if not base_class_entry.is_type:
3355 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3356 elif not base_class_entry.type.is_extension_type and \
3357 not (base_class_entry.type.is_builtin_type and \
3358 base_class_entry.type.objstruct_cname):
3359 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3360 elif not base_class_entry.type.is_complete():
3361 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3362 self.base_class_name, self.class_name))
3363 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3364 base_class_entry.type.scope.directives['final']:
3365 error(self.pos, "Base class '%s' of type '%s' is final" % (
3366 self.base_class_name, self.class_name))
3367 elif base_class_entry.type.is_builtin_type and \
3368 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3369 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3370 % base_class_entry.type.name)
3372 self.base_type = base_class_entry.type
3373 has_body = self.body is not None
3374 if self.module_name and self.visibility != 'extern':
3375 module_path = self.module_name.split(".")
3376 home_scope = env.find_imported_module(module_path, self.pos)
3382 if self.visibility == 'extern':
3383 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3384 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3386 self.entry = home_scope.declare_c_class(
3387 name = self.class_name,
3389 defining = has_body and self.in_pxd,
3390 implementing = has_body and not self.in_pxd,
3391 module_name = self.module_name,
3392 base_type = self.base_type,
3393 objstruct_cname = self.objstruct_name,
3394 typeobj_cname = self.typeobj_name,
3395 visibility = self.visibility,
3396 typedef_flag = self.typedef_flag,
3398 buffer_defaults = buffer_defaults)
3399 if home_scope is not env and self.visibility == 'extern':
3400 env.add_imported_entry(self.class_name, self.entry, self.pos)
3401 self.scope = scope = self.entry.type.scope
3402 if scope is not None:
3403 scope.directives = env.directives
3405 if self.doc and Options.docstrings:
3406 scope.doc = embed_position(self.pos, self.doc)
3409 self.body.analyse_declarations(scope)
3413 scope.implemented = 1
3414 env.allocate_vtable_names(self.entry)
3416 def analyse_expressions(self, env):
3418 scope = self.entry.type.scope
3419 self.body.analyse_expressions(scope)
3421 def generate_function_definitions(self, env, code):
3423 self.generate_lambda_definitions(self.scope, code)
3424 self.body.generate_function_definitions(self.scope, code)
3426 def generate_execution_code(self, code):
3427 # This is needed to generate evaluation code for
3428 # default values of method arguments.
3430 self.body.generate_execution_code(code)
3432 def annotate(self, code):
3434 self.body.annotate(code)
3437 class PropertyNode(StatNode):
3438 # Definition of a property in an extension type.
3441 # doc EncodedString or None Doc string
3444 child_attrs = ["body"]
3446 def analyse_declarations(self, env):
3447 entry = env.declare_property(self.name, self.doc, self.pos)
3449 entry.scope.directives = env.directives
3450 self.body.analyse_declarations(entry.scope)
3452 def analyse_expressions(self, env):
3453 self.body.analyse_expressions(env)
3455 def generate_function_definitions(self, env, code):
3456 self.body.generate_function_definitions(env, code)
3458 def generate_execution_code(self, code):
3461 def annotate(self, code):
3462 self.body.annotate(code)
3465 class GlobalNode(StatNode):
3466 # Global variable declaration.
3472 def analyse_declarations(self, env):
3473 for name in self.names:
3474 env.declare_global(name, self.pos)
3476 def analyse_expressions(self, env):
3479 def generate_execution_code(self, code):
3483 class NonlocalNode(StatNode):
3484 # Nonlocal variable declaration via the 'nonlocal' keyword.
3490 def analyse_declarations(self, env):
3491 for name in self.names:
3492 env.declare_nonlocal(name, self.pos)
3494 def analyse_expressions(self, env):
3497 def generate_execution_code(self, code):
3501 class ExprStatNode(StatNode):
3502 # Expression used as a statement.
3506 child_attrs = ["expr"]
3508 def analyse_declarations(self, env):
3510 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3511 func = self.expr.function.as_cython_attribute()
3512 if func == u'declare':
3513 args, kwds = self.expr.explicit_args_kwds()
3515 error(self.expr.pos, "Variable names must be specified.")
3516 for var, type_node in kwds.key_value_pairs:
3517 type = type_node.analyse_as_type(env)
3519 error(type_node.pos, "Unknown type")
3521 env.declare_var(var.value, type, var.pos, is_cdef = True)
3522 self.__class__ = PassStatNode
3524 def analyse_expressions(self, env):
3525 self.expr.result_is_used = False # hint that .result() may safely be left empty
3526 self.expr.analyse_expressions(env)
3528 def nogil_check(self, env):
3529 if self.expr.type.is_pyobject and self.expr.is_temp:
3532 gil_message = "Discarding owned Python object"
3534 def generate_execution_code(self, code):
3535 self.expr.generate_evaluation_code(code)
3536 if not self.expr.is_temp and self.expr.result():
3537 code.putln("%s;" % self.expr.result())
3538 self.expr.generate_disposal_code(code)
3539 self.expr.free_temps(code)
3541 def generate_function_definitions(self, env, code):
3542 self.expr.generate_function_definitions(env, code)
3544 def annotate(self, code):
3545 self.expr.annotate(code)
3548 class AssignmentNode(StatNode):
3549 # Abstract base class for assignment nodes.
3551 # The analyse_expressions and generate_execution_code
3552 # phases of assignments are split into two sub-phases
3553 # each, to enable all the right hand sides of a
3554 # parallel assignment to be evaluated before assigning
3555 # to any of the left hand sides.
3557 def analyse_expressions(self, env):
3558 self.analyse_types(env)
3560 # def analyse_expressions(self, env):
3561 # self.analyse_expressions_1(env)
3562 # self.analyse_expressions_2(env)
3564 def generate_execution_code(self, code):
3565 self.generate_rhs_evaluation_code(code)
3566 self.generate_assignment_code(code)
3569 class SingleAssignmentNode(AssignmentNode):
3570 # The simplest case:
3574 # lhs ExprNode Left hand side
3575 # rhs ExprNode Right hand side
3576 # first bool Is this guaranteed the first assignment to lhs?
3578 child_attrs = ["lhs", "rhs"]
3580 declaration_only = False
3582 def analyse_declarations(self, env):
3585 # handle declarations of the form x = cython.foo()
3586 if isinstance(self.rhs, ExprNodes.CallNode):
3587 func_name = self.rhs.function.as_cython_attribute()
3589 args, kwds = self.rhs.explicit_args_kwds()
3591 if func_name in ['declare', 'typedef']:
3592 if len(args) > 2 or kwds is not None:
3593 error(self.rhs.pos, "Can only declare one type at a time.")
3595 type = args[0].analyse_as_type(env)
3597 error(args[0].pos, "Unknown type")
3600 if func_name == 'declare':
3601 if isinstance(lhs, ExprNodes.NameNode):
3602 vars = [(lhs.name, lhs.pos)]
3603 elif isinstance(lhs, ExprNodes.TupleNode):
3604 vars = [(var.name, var.pos) for var in lhs.args]
3606 error(lhs.pos, "Invalid declaration")
3608 for var, pos in vars:
3609 env.declare_var(var, type, pos, is_cdef = True)
3614 self.declaration_only = True
3616 self.declaration_only = True
3617 if not isinstance(lhs, ExprNodes.NameNode):
3618 error(lhs.pos, "Invalid declaration.")
3619 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3621 elif func_name in ['struct', 'union']:
3622 self.declaration_only = True
3623 if len(args) > 0 or kwds is None:
3624 error(self.rhs.pos, "Struct or union members must be given by name.")
3627 for member, type_node in kwds.key_value_pairs:
3628 type = type_node.analyse_as_type(env)
3630 error(type_node.pos, "Unknown type")
3632 members.append((member.value, type, member.pos))
3633 if len(members) < len(kwds.key_value_pairs):
3635 if not isinstance(self.lhs, ExprNodes.NameNode):
3636 error(self.lhs.pos, "Invalid declaration.")
3637 name = self.lhs.name
3638 scope = StructOrUnionScope(name)
3639 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3640 for member, type, pos in members:
3641 scope.declare_var(member, type, pos)
3643 if self.declaration_only:
3646 self.lhs.analyse_target_declaration(env)
3648 def analyse_types(self, env, use_temp = 0):
3649 self.rhs.analyse_types(env)
3650 self.lhs.analyse_target_types(env)
3651 self.lhs.gil_assignment_check(env)
3652 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3654 self.rhs = self.rhs.coerce_to_temp(env)
3656 def generate_rhs_evaluation_code(self, code):
3657 self.rhs.generate_evaluation_code(code)
3659 def generate_assignment_code(self, code):
3660 self.lhs.generate_assignment_code(self.rhs, code)
3662 def generate_function_definitions(self, env, code):
3663 self.rhs.generate_function_definitions(env, code)
3665 def annotate(self, code):
3666 self.lhs.annotate(code)
3667 self.rhs.annotate(code)
3670 class CascadedAssignmentNode(AssignmentNode):
3671 # An assignment with multiple left hand sides:
3675 # lhs_list [ExprNode] Left hand sides
3676 # rhs ExprNode Right hand sides
3680 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3682 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3683 coerced_rhs_list = None
3685 def analyse_declarations(self, env):
3686 for lhs in self.lhs_list:
3687 lhs.analyse_target_declaration(env)
3689 def analyse_types(self, env, use_temp = 0):
3690 self.rhs.analyse_types(env)
3691 if not self.rhs.is_simple():
3693 self.rhs = self.rhs.coerce_to_temp(env)
3695 self.rhs = self.rhs.coerce_to_simple(env)
3696 from ExprNodes import CloneNode
3697 self.coerced_rhs_list = []
3698 for lhs in self.lhs_list:
3699 lhs.analyse_target_types(env)
3700 lhs.gil_assignment_check(env)
3701 rhs = CloneNode(self.rhs)
3702 rhs = rhs.coerce_to(lhs.type, env)
3703 self.coerced_rhs_list.append(rhs)
3705 def generate_rhs_evaluation_code(self, code):
3706 self.rhs.generate_evaluation_code(code)
3708 def generate_assignment_code(self, code):
3709 for i in range(len(self.lhs_list)):
3710 lhs = self.lhs_list[i]
3711 rhs = self.coerced_rhs_list[i]
3712 rhs.generate_evaluation_code(code)
3713 lhs.generate_assignment_code(rhs, code)
3714 # Assignment has disposed of the cloned RHS
3715 self.rhs.generate_disposal_code(code)
3716 self.rhs.free_temps(code)
3718 def generate_function_definitions(self, env, code):
3719 self.rhs.generate_function_definitions(env, code)
3721 def annotate(self, code):
3722 for i in range(len(self.lhs_list)):
3723 lhs = self.lhs_list[i].annotate(code)
3724 rhs = self.coerced_rhs_list[i].annotate(code)
3725 self.rhs.annotate(code)
3728 class ParallelAssignmentNode(AssignmentNode):
3729 # A combined packing/unpacking assignment:
3733 # This has been rearranged by the parser into
3735 # a = d ; b = e ; c = f
3737 # but we must evaluate all the right hand sides
3738 # before assigning to any of the left hand sides.
3740 # stats [AssignmentNode] The constituent assignments
3742 child_attrs = ["stats"]
3744 def analyse_declarations(self, env):
3745 for stat in self.stats:
3746 stat.analyse_declarations(env)
3748 def analyse_expressions(self, env):
3749 for stat in self.stats:
3750 stat.analyse_types(env, use_temp = 1)
3752 # def analyse_expressions(self, env):
3753 # for stat in self.stats:
3754 # stat.analyse_expressions_1(env, use_temp = 1)
3755 # for stat in self.stats:
3756 # stat.analyse_expressions_2(env)
3758 def generate_execution_code(self, code):
3759 for stat in self.stats:
3760 stat.generate_rhs_evaluation_code(code)
3761 for stat in self.stats:
3762 stat.generate_assignment_code(code)
3764 def generate_function_definitions(self, env, code):
3765 for stat in self.stats:
3766 stat.generate_function_definitions(env, code)
3768 def annotate(self, code):
3769 for stat in self.stats:
3773 class InPlaceAssignmentNode(AssignmentNode):
3774 # An in place arithmetic operand:
3780 # lhs ExprNode Left hand side
3781 # rhs ExprNode Right hand side
3782 # op char one of "+-*/%^&|"
3783 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3785 # This code is a bit tricky because in order to obey Python
3786 # semantics the sub-expressions (e.g. indices) of the lhs must
3787 # not be evaluated twice. So we must re-use the values calculated
3788 # in evaluation phase for the assignment phase as well.
3789 # Fortunately, the type of the lhs node is fairly constrained
3790 # (it must be a NameNode, AttributeNode, or IndexNode).
3792 child_attrs = ["lhs", "rhs"]
3794 def analyse_declarations(self, env):
3795 self.lhs.analyse_target_declaration(env)
3797 def analyse_types(self, env):
3798 self.rhs.analyse_types(env)
3799 self.lhs.analyse_target_types(env)
3801 def generate_execution_code(self, code):
3803 self.rhs.generate_evaluation_code(code)
3804 self.lhs.generate_subexpr_evaluation_code(code)
3805 c_op = self.operator
3809 error(self.pos, "No C inplace power operator")
3810 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3811 if self.lhs.type.is_pyobject:
3812 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3813 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3814 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3815 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3818 # TODO: make sure overload is declared
3819 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3820 self.lhs.generate_subexpr_disposal_code(code)
3821 self.lhs.free_subexpr_temps(code)
3822 self.rhs.generate_disposal_code(code)
3823 self.rhs.free_temps(code)
3825 def annotate(self, code):
3826 self.lhs.annotate(code)
3827 self.rhs.annotate(code)
3829 def create_binop_node(self):
3831 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3834 class PrintStatNode(StatNode):
3837 # arg_tuple TupleNode
3838 # stream ExprNode or None (stdout)
3839 # append_newline boolean
3841 child_attrs = ["arg_tuple", "stream"]
3843 def analyse_expressions(self, env):
3845 self.stream.analyse_expressions(env)
3846 self.stream = self.stream.coerce_to_pyobject(env)
3847 self.arg_tuple.analyse_expressions(env)
3848 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3849 env.use_utility_code(printing_utility_code)
3850 if len(self.arg_tuple.args) == 1 and self.append_newline:
3851 env.use_utility_code(printing_one_utility_code)
3853 nogil_check = Node.gil_error
3854 gil_message = "Python print statement"
3856 def generate_execution_code(self, code):
3858 self.stream.generate_evaluation_code(code)
3859 stream_result = self.stream.py_result()
3862 if len(self.arg_tuple.args) == 1 and self.append_newline:
3863 arg = self.arg_tuple.args[0]
3864 arg.generate_evaluation_code(code)
3867 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3870 code.error_goto(self.pos)))
3871 arg.generate_disposal_code(code)
3872 arg.free_temps(code)
3874 self.arg_tuple.generate_evaluation_code(code)
3876 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3878 self.arg_tuple.py_result(),
3879 self.append_newline,
3880 code.error_goto(self.pos)))
3881 self.arg_tuple.generate_disposal_code(code)
3882 self.arg_tuple.free_temps(code)
3885 self.stream.generate_disposal_code(code)
3886 self.stream.free_temps(code)
3888 def generate_function_definitions(self, env, code):
3890 self.stream.generate_function_definitions(env, code)
3891 self.arg_tuple.generate_function_definitions(env, code)
3893 def annotate(self, code):
3895 self.stream.annotate(code)
3896 self.arg_tuple.annotate(code)
3899 class ExecStatNode(StatNode):
3904 child_attrs = ["args"]
3906 def analyse_expressions(self, env):
3907 for i, arg in enumerate(self.args):
3908 arg.analyse_expressions(env)
3909 arg = arg.coerce_to_pyobject(env)
3911 env.use_utility_code(Builtin.pyexec_utility_code)
3913 nogil_check = Node.gil_error
3914 gil_message = "Python exec statement"
3916 def generate_execution_code(self, code):
3918 for arg in self.args:
3919 arg.generate_evaluation_code(code)
3920 args.append( arg.py_result() )
3921 args = tuple(args + ['0', '0'][:3-len(args)])
3922 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3923 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3924 (temp_result,) + args))
3925 for arg in self.args:
3926 arg.generate_disposal_code(code)
3927 arg.free_temps(code)
3929 code.error_goto_if_null(temp_result, self.pos))
3930 code.put_gotref(temp_result)
3931 code.put_decref_clear(temp_result, py_object_type)
3932 code.funcstate.release_temp(temp_result)
3934 def annotate(self, code):
3935 for arg in self.args:
3939 class DelStatNode(StatNode):
3944 child_attrs = ["args"]
3946 def analyse_declarations(self, env):
3947 for arg in self.args:
3948 arg.analyse_target_declaration(env)
3950 def analyse_expressions(self, env):
3951 for arg in self.args:
3952 arg.analyse_target_expression(env, None)
3953 if arg.type.is_pyobject:
3955 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3957 elif arg.type.is_cpp_class:
3958 error(arg.pos, "Deletion of non-heap C++ object")
3960 error(arg.pos, "Deletion of non-Python, non-C++ object")
3961 #arg.release_target_temp(env)
3963 def nogil_check(self, env):
3964 for arg in self.args:
3965 if arg.type.is_pyobject:
3968 gil_message = "Deleting Python object"
3970 def generate_execution_code(self, code):
3971 for arg in self.args:
3972 if arg.type.is_pyobject:
3973 arg.generate_deletion_code(code)
3974 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3975 arg.generate_result_code(code)
3976 code.putln("delete %s;" % arg.result())
3977 # else error reported earlier
3979 def annotate(self, code):
3980 for arg in self.args:
3984 class PassStatNode(StatNode):
3989 def analyse_expressions(self, env):
3992 def generate_execution_code(self, code):
3996 class BreakStatNode(StatNode):
4000 def analyse_expressions(self, env):
4003 def generate_execution_code(self, code):
4004 if not code.break_label:
4005 error(self.pos, "break statement not inside loop")
4007 code.put_goto(code.break_label)
4010 class ContinueStatNode(StatNode):
4014 def analyse_expressions(self, env):
4017 def generate_execution_code(self, code):
4018 if code.funcstate.in_try_finally:
4019 error(self.pos, "continue statement inside try of try...finally")
4020 elif not code.continue_label:
4021 error(self.pos, "continue statement not inside loop")
4023 code.put_goto(code.continue_label)
4026 class ReturnStatNode(StatNode):
4029 # value ExprNode or None
4030 # return_type PyrexType
4032 child_attrs = ["value"]
4034 def analyse_expressions(self, env):
4035 return_type = env.return_type
4036 self.return_type = return_type
4038 error(self.pos, "Return not inside a function body")
4041 self.value.analyse_types(env)
4042 if return_type.is_void or return_type.is_returncode:
4043 error(self.value.pos,
4044 "Return with value in void function")
4046 self.value = self.value.coerce_to(env.return_type, env)
4048 if (not return_type.is_void
4049 and not return_type.is_pyobject
4050 and not return_type.is_returncode):
4051 error(self.pos, "Return value required")
4053 def nogil_check(self, env):
4054 if self.return_type.is_pyobject:
4057 gil_message = "Returning Python object"
4059 def generate_execution_code(self, code):
4060 code.mark_pos(self.pos)
4061 if not self.return_type:
4062 # error reported earlier
4064 if self.return_type.is_pyobject:
4065 code.put_xdecref(Naming.retval_cname,
4068 self.value.generate_evaluation_code(code)
4069 self.value.make_owned_reference(code)
4072 Naming.retval_cname,
4073 self.value.result_as(self.return_type)))
4074 self.value.generate_post_assignment_code(code)
4075 self.value.free_temps(code)
4077 if self.return_type.is_pyobject:
4078 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4079 elif self.return_type.is_returncode:
4082 Naming.retval_cname,
4083 self.return_type.default_value))
4084 for cname, type in code.funcstate.temps_holding_reference():
4085 code.put_decref_clear(cname, type)
4086 code.put_goto(code.return_label)
4088 def generate_function_definitions(self, env, code):
4089 if self.value is not None:
4090 self.value.generate_function_definitions(env, code)
4092 def annotate(self, code):
4094 self.value.annotate(code)
4097 class RaiseStatNode(StatNode):
4100 # exc_type ExprNode or None
4101 # exc_value ExprNode or None
4102 # exc_tb ExprNode or None
4104 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4106 def analyse_expressions(self, env):
4108 self.exc_type.analyse_types(env)
4109 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4111 self.exc_value.analyse_types(env)
4112 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4114 self.exc_tb.analyse_types(env)
4115 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4116 env.use_utility_code(raise_utility_code)
4118 nogil_check = Node.gil_error
4119 gil_message = "Raising exception"
4121 def generate_execution_code(self, code):
4123 self.exc_type.generate_evaluation_code(code)
4124 type_code = self.exc_type.py_result()
4128 self.exc_value.generate_evaluation_code(code)
4129 value_code = self.exc_value.py_result()
4133 self.exc_tb.generate_evaluation_code(code)
4134 tb_code = self.exc_tb.py_result()
4138 "__Pyx_Raise(%s, %s, %s);" % (
4142 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4144 obj.generate_disposal_code(code)
4145 obj.free_temps(code)
4147 code.error_goto(self.pos))
4149 def generate_function_definitions(self, env, code):
4150 if self.exc_type is not None:
4151 self.exc_type.generate_function_definitions(env, code)
4152 if self.exc_value is not None:
4153 self.exc_value.generate_function_definitions(env, code)
4154 if self.exc_tb is not None:
4155 self.exc_tb.generate_function_definitions(env, code)
4157 def annotate(self, code):
4159 self.exc_type.annotate(code)
4161 self.exc_value.annotate(code)
4163 self.exc_tb.annotate(code)
4166 class ReraiseStatNode(StatNode):
4170 def analyse_expressions(self, env):
4171 env.use_utility_code(restore_exception_utility_code)
4173 nogil_check = Node.gil_error
4174 gil_message = "Raising exception"
4176 def generate_execution_code(self, code):
4177 vars = code.funcstate.exc_vars
4179 for varname in vars:
4180 code.put_giveref(varname)
4181 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4182 for varname in vars:
4183 code.put("%s = 0; " % varname)
4185 code.putln(code.error_goto(self.pos))
4187 error(self.pos, "Reraise not inside except clause")
4190 class AssertStatNode(StatNode):
4194 # value ExprNode or None
4196 child_attrs = ["cond", "value"]
4198 def analyse_expressions(self, env):
4199 self.cond = self.cond.analyse_boolean_expression(env)
4201 self.value.analyse_types(env)
4202 self.value = self.value.coerce_to_pyobject(env)
4204 nogil_check = Node.gil_error
4205 gil_message = "Raising exception"
4207 def generate_execution_code(self, code):
4208 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4209 self.cond.generate_evaluation_code(code)
4211 "if (unlikely(!%s)) {" %
4214 self.value.generate_evaluation_code(code)
4216 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4217 self.value.py_result())
4218 self.value.generate_disposal_code(code)
4219 self.value.free_temps(code)
4222 "PyErr_SetNone(PyExc_AssertionError);")
4224 code.error_goto(self.pos))
4227 self.cond.generate_disposal_code(code)
4228 self.cond.free_temps(code)
4229 code.putln("#endif")
4231 def generate_function_definitions(self, env, code):
4232 self.cond.generate_function_definitions(env, code)
4233 if self.value is not None:
4234 self.value.generate_function_definitions(env, code)
4236 def annotate(self, code):
4237 self.cond.annotate(code)
4239 self.value.annotate(code)
4242 class IfStatNode(StatNode):
4245 # if_clauses [IfClauseNode]
4246 # else_clause StatNode or None
4248 child_attrs = ["if_clauses", "else_clause"]
4250 def analyse_control_flow(self, env):
4251 env.start_branching(self.pos)
4252 for if_clause in self.if_clauses:
4253 if_clause.analyse_control_flow(env)
4254 env.next_branch(if_clause.end_pos())
4255 if self.else_clause:
4256 self.else_clause.analyse_control_flow(env)
4257 env.finish_branching(self.end_pos())
4259 def analyse_declarations(self, env):
4260 for if_clause in self.if_clauses:
4261 if_clause.analyse_declarations(env)
4262 if self.else_clause:
4263 self.else_clause.analyse_declarations(env)
4265 def analyse_expressions(self, env):
4266 for if_clause in self.if_clauses:
4267 if_clause.analyse_expressions(env)
4268 if self.else_clause:
4269 self.else_clause.analyse_expressions(env)
4271 def generate_execution_code(self, code):
4272 code.mark_pos(self.pos)
4273 end_label = code.new_label()
4274 for if_clause in self.if_clauses:
4275 if_clause.generate_execution_code(code, end_label)
4276 if self.else_clause:
4277 code.putln("/*else*/ {")
4278 self.else_clause.generate_execution_code(code)
4280 code.put_label(end_label)
4282 def generate_function_definitions(self, env, code):
4283 for clause in self.if_clauses:
4284 clause.generate_function_definitions(env, code)
4285 if self.else_clause is not None:
4286 self.else_clause.generate_function_definitions(env, code)
4288 def annotate(self, code):
4289 for if_clause in self.if_clauses:
4290 if_clause.annotate(code)
4291 if self.else_clause:
4292 self.else_clause.annotate(code)
4295 class IfClauseNode(Node):
4296 # if or elif clause in an if statement
4298 # condition ExprNode
4301 child_attrs = ["condition", "body"]
4303 def analyse_control_flow(self, env):
4304 self.body.analyse_control_flow(env)
4306 def analyse_declarations(self, env):
4307 self.body.analyse_declarations(env)
4309 def analyse_expressions(self, env):
4311 self.condition.analyse_temp_boolean_expression(env)
4312 self.body.analyse_expressions(env)
4314 def get_constant_condition_result(self):
4315 if self.condition.has_constant_result():
4316 return bool(self.condition.constant_result)
4320 def generate_execution_code(self, code, end_label):
4321 self.condition.generate_evaluation_code(code)
4324 self.condition.result())
4325 self.condition.generate_disposal_code(code)
4326 self.condition.free_temps(code)
4327 self.body.generate_execution_code(code)
4328 code.put_goto(end_label)
4331 def generate_function_definitions(self, env, code):
4332 self.condition.generate_function_definitions(env, code)
4333 self.body.generate_function_definitions(env, code)
4335 def annotate(self, code):
4336 self.condition.annotate(code)
4337 self.body.annotate(code)
4340 class SwitchCaseNode(StatNode):
4341 # Generated in the optimization of an if-elif-else node
4343 # conditions [ExprNode]
4346 child_attrs = ['conditions', 'body']
4348 def generate_execution_code(self, code):
4349 for cond in self.conditions:
4350 code.mark_pos(cond.pos)
4351 cond.generate_evaluation_code(code)
4352 code.putln("case %s:" % cond.result())
4353 self.body.generate_execution_code(code)
4354 code.putln("break;")
4356 def generate_function_definitions(self, env, code):
4357 for cond in self.conditions:
4358 cond.generate_function_definitions(env, code)
4359 self.body.generate_function_definitions(env, code)
4361 def annotate(self, code):
4362 for cond in self.conditions:
4364 self.body.annotate(code)
4366 class SwitchStatNode(StatNode):
4367 # Generated in the optimization of an if-elif-else node
4370 # cases [SwitchCaseNode]
4371 # else_clause StatNode or None
4373 child_attrs = ['test', 'cases', 'else_clause']
4375 def generate_execution_code(self, code):
4376 self.test.generate_evaluation_code(code)
4377 code.putln("switch (%s) {" % self.test.result())
4378 for case in self.cases:
4379 case.generate_execution_code(code)
4380 if self.else_clause is not None:
4381 code.putln("default:")
4382 self.else_clause.generate_execution_code(code)
4383 code.putln("break;")
4386 def generate_function_definitions(self, env, code):
4387 self.test.generate_function_definitions(env, code)
4388 for case in self.cases:
4389 case.generate_function_definitions(env, code)
4390 if self.else_clause is not None:
4391 self.else_clause.generate_function_definitions(env, code)
4393 def annotate(self, code):
4394 self.test.annotate(code)
4395 for case in self.cases:
4397 if self.else_clause is not None:
4398 self.else_clause.annotate(code)
4400 class LoopNode(object):
4402 def analyse_control_flow(self, env):
4403 env.start_branching(self.pos)
4404 self.body.analyse_control_flow(env)
4405 env.next_branch(self.body.end_pos())
4406 if self.else_clause:
4407 self.else_clause.analyse_control_flow(env)
4408 env.finish_branching(self.end_pos())
4411 class WhileStatNode(LoopNode, StatNode):
4414 # condition ExprNode
4416 # else_clause StatNode
4418 child_attrs = ["condition", "body", "else_clause"]
4420 def analyse_declarations(self, env):
4421 self.body.analyse_declarations(env)
4422 if self.else_clause:
4423 self.else_clause.analyse_declarations(env)
4425 def analyse_expressions(self, env):
4427 self.condition.analyse_temp_boolean_expression(env)
4428 self.body.analyse_expressions(env)
4429 if self.else_clause:
4430 self.else_clause.analyse_expressions(env)
4432 def generate_execution_code(self, code):
4433 old_loop_labels = code.new_loop_labels()
4436 self.condition.generate_evaluation_code(code)
4437 self.condition.generate_disposal_code(code)
4440 self.condition.result())
4441 self.condition.free_temps(code)
4442 self.body.generate_execution_code(code)
4443 code.put_label(code.continue_label)
4445 break_label = code.break_label
4446 code.set_loop_labels(old_loop_labels)
4447 if self.else_clause:
4448 code.putln("/*else*/ {")
4449 self.else_clause.generate_execution_code(code)
4451 code.put_label(break_label)
4453 def generate_function_definitions(self, env, code):
4454 self.condition.generate_function_definitions(env, code)
4455 self.body.generate_function_definitions(env, code)
4456 if self.else_clause is not None:
4457 self.else_clause.generate_function_definitions(env, code)
4459 def annotate(self, code):
4460 self.condition.annotate(code)
4461 self.body.annotate(code)
4462 if self.else_clause:
4463 self.else_clause.annotate(code)
4466 def ForStatNode(pos, **kw):
4467 if 'iterator' in kw:
4468 return ForInStatNode(pos, **kw)
4470 return ForFromStatNode(pos, **kw)
4472 class ForInStatNode(LoopNode, StatNode):
4476 # iterator IteratorNode
4478 # else_clause StatNode
4479 # item NextNode used internally
4481 child_attrs = ["target", "iterator", "body", "else_clause"]
4484 def analyse_declarations(self, env):
4485 self.target.analyse_target_declaration(env)
4486 self.body.analyse_declarations(env)
4487 if self.else_clause:
4488 self.else_clause.analyse_declarations(env)
4490 def analyse_expressions(self, env):
4492 self.target.analyse_target_types(env)
4493 self.iterator.analyse_expressions(env)
4494 self.item = ExprNodes.NextNode(self.iterator, env)
4495 self.item = self.item.coerce_to(self.target.type, env)
4496 self.body.analyse_expressions(env)
4497 if self.else_clause:
4498 self.else_clause.analyse_expressions(env)
4500 def generate_execution_code(self, code):
4501 old_loop_labels = code.new_loop_labels()
4502 self.iterator.allocate_counter_temp(code)
4503 self.iterator.generate_evaluation_code(code)
4506 self.item.generate_evaluation_code(code)
4507 self.target.generate_assignment_code(self.item, code)
4508 self.body.generate_execution_code(code)
4509 code.put_label(code.continue_label)
4512 break_label = code.break_label
4513 code.set_loop_labels(old_loop_labels)
4515 if self.else_clause:
4516 # in nested loops, the 'else' block can contain a
4517 # 'continue' statement for the outer loop, but we may need
4518 # to generate cleanup code before taking that path, so we
4520 orig_continue_label = code.continue_label
4521 code.continue_label = code.new_label('outer_continue')
4523 code.putln("/*else*/ {")
4524 self.else_clause.generate_execution_code(code)
4527 if code.label_used(code.continue_label):
4528 code.put_goto(break_label)
4529 code.put_label(code.continue_label)
4530 self.iterator.generate_disposal_code(code)
4531 code.put_goto(orig_continue_label)
4532 code.set_loop_labels(old_loop_labels)
4534 if code.label_used(break_label):
4535 code.put_label(break_label)
4536 self.iterator.release_counter_temp(code)
4537 self.iterator.generate_disposal_code(code)
4538 self.iterator.free_temps(code)
4540 def generate_function_definitions(self, env, code):
4541 self.target.generate_function_definitions(env, code)
4542 self.iterator.generate_function_definitions(env, code)
4543 self.body.generate_function_definitions(env, code)
4544 if self.else_clause is not None:
4545 self.else_clause.generate_function_definitions(env, code)
4547 def annotate(self, code):
4548 self.target.annotate(code)
4549 self.iterator.annotate(code)
4550 self.body.annotate(code)
4551 if self.else_clause:
4552 self.else_clause.annotate(code)
4553 self.item.annotate(code)
4556 class ForFromStatNode(LoopNode, StatNode):
4557 # for name from expr rel name rel expr
4564 # step ExprNode or None
4566 # else_clause StatNode or None
4572 # loopvar_node ExprNode (usually a NameNode or temp node)
4573 # py_loopvar_node PyTempNode or None
4574 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4576 is_py_target = False
4578 py_loopvar_node = None
4581 gil_message = "For-loop using object bounds or target"
4583 def nogil_check(self, env):
4584 for x in (self.target, self.bound1, self.bound2):
4585 if x.type.is_pyobject:
4588 def analyse_declarations(self, env):
4589 self.target.analyse_target_declaration(env)
4590 self.body.analyse_declarations(env)
4591 if self.else_clause:
4592 self.else_clause.analyse_declarations(env)
4594 def analyse_expressions(self, env):
4596 self.target.analyse_target_types(env)
4597 self.bound1.analyse_types(env)
4598 self.bound2.analyse_types(env)
4599 if self.step is not None:
4600 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4601 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4602 self.step.analyse_types(env)
4604 target_type = self.target.type
4605 if self.target.type.is_numeric:
4606 loop_type = self.target.type
4608 loop_type = PyrexTypes.c_int_type
4609 if not self.bound1.type.is_pyobject:
4610 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4611 if not self.bound2.type.is_pyobject:
4612 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4613 if self.step is not None and not self.step.type.is_pyobject:
4614 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4615 self.bound1 = self.bound1.coerce_to(loop_type, env)
4616 self.bound2 = self.bound2.coerce_to(loop_type, env)
4617 if not self.bound2.is_literal:
4618 self.bound2 = self.bound2.coerce_to_temp(env)
4619 if self.step is not None:
4620 self.step = self.step.coerce_to(loop_type, env)
4621 if not self.step.is_literal:
4622 self.step = self.step.coerce_to_temp(env)
4624 target_type = self.target.type
4625 if not (target_type.is_pyobject or target_type.is_numeric):
4626 error(self.target.pos,
4627 "for-from loop variable must be c numeric type or Python object")
4628 if target_type.is_numeric:
4629 self.is_py_target = False
4630 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4631 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4632 self.loopvar_node = self.target
4633 self.py_loopvar_node = None
4635 self.is_py_target = True
4636 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4637 self.loopvar_node = c_loopvar_node
4638 self.py_loopvar_node = \
4639 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4640 self.body.analyse_expressions(env)
4641 if self.else_clause:
4642 self.else_clause.analyse_expressions(env)
4644 def generate_execution_code(self, code):
4645 old_loop_labels = code.new_loop_labels()
4646 from_range = self.from_range
4647 self.bound1.generate_evaluation_code(code)
4648 self.bound2.generate_evaluation_code(code)
4649 offset, incop = self.relation_table[self.relation1]
4650 if self.step is not None:
4651 self.step.generate_evaluation_code(code)
4652 step = self.step.result()
4653 incop = "%s=%s" % (incop[0], step)
4655 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4656 self.loopvar_node.allocate(code)
4657 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4658 self.py_loopvar_node.allocate(code)
4660 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4662 loopvar_name = self.loopvar_node.result()
4664 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4666 self.bound1.result(), offset,
4667 loopvar_name, self.relation2, self.bound2.result(),
4668 loopvar_name, incop))
4669 if self.py_loopvar_node:
4670 self.py_loopvar_node.generate_evaluation_code(code)
4671 self.target.generate_assignment_code(self.py_loopvar_node, code)
4673 code.putln("%s = %s;" % (
4674 self.target.result(), loopvar_name))
4675 self.body.generate_execution_code(code)
4676 code.put_label(code.continue_label)
4677 if self.py_loopvar_node:
4678 # This mess is to make for..from loops with python targets behave
4679 # exactly like those with C targets with regards to re-assignment
4680 # of the loop variable.
4682 if self.target.entry.is_pyglobal:
4683 # We know target is a NameNode, this is the only ugly case.
4684 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4685 target_node.allocate(code)
4686 interned_cname = code.intern_identifier(self.target.entry.name)
4687 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4688 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4689 target_node.result(),
4690 Naming.module_cname,
4692 code.error_goto_if_null(target_node.result(), self.target.pos)))
4693 code.put_gotref(target_node.result())
4695 target_node = self.target
4696 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4697 from_py_node.temp_code = loopvar_name
4698 from_py_node.generate_result_code(code)
4699 if self.target.entry.is_pyglobal:
4700 code.put_decref(target_node.result(), target_node.type)
4701 target_node.release(code)
4703 if self.py_loopvar_node:
4704 # This is potentially wasteful, but we don't want the semantics to
4705 # depend on whether or not the loop is a python type.
4706 self.py_loopvar_node.generate_evaluation_code(code)
4707 self.target.generate_assignment_code(self.py_loopvar_node, code)
4709 code.funcstate.release_temp(loopvar_name)
4710 break_label = code.break_label
4711 code.set_loop_labels(old_loop_labels)
4712 if self.else_clause:
4713 code.putln("/*else*/ {")
4714 self.else_clause.generate_execution_code(code)
4716 code.put_label(break_label)
4717 self.bound1.generate_disposal_code(code)
4718 self.bound1.free_temps(code)
4719 self.bound2.generate_disposal_code(code)
4720 self.bound2.free_temps(code)
4721 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4722 self.loopvar_node.release(code)
4723 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4724 self.py_loopvar_node.release(code)
4725 if self.step is not None:
4726 self.step.generate_disposal_code(code)
4727 self.step.free_temps(code)
4730 # {relop : (initial offset, increment op)}
4737 def generate_function_definitions(self, env, code):
4738 self.target.generate_function_definitions(env, code)
4739 self.bound1.generate_function_definitions(env, code)
4740 self.bound2.generate_function_definitions(env, code)
4741 if self.step is not None:
4742 self.step.generate_function_definitions(env, code)
4743 self.body.generate_function_definitions(env, code)
4744 if self.else_clause is not None:
4745 self.else_clause.generate_function_definitions(env, code)
4747 def annotate(self, code):
4748 self.target.annotate(code)
4749 self.bound1.annotate(code)
4750 self.bound2.annotate(code)
4752 self.step.annotate(code)
4753 self.body.annotate(code)
4754 if self.else_clause:
4755 self.else_clause.annotate(code)
4758 class WithStatNode(StatNode):
4760 Represents a Python with statement.
4762 This is only used at parse tree level; and is not present in
4763 analysis or generation phases.
4765 # manager The with statement manager object
4766 # target Node (lhs expression)
4768 child_attrs = ["manager", "target", "body"]
4770 class TryExceptStatNode(StatNode):
4771 # try .. except statement
4774 # except_clauses [ExceptClauseNode]
4775 # else_clause StatNode or None
4777 child_attrs = ["body", "except_clauses", "else_clause"]
4779 def analyse_control_flow(self, env):
4780 env.start_branching(self.pos)
4781 self.body.analyse_control_flow(env)
4782 successful_try = env.control_flow # grab this for later
4783 env.next_branch(self.body.end_pos())
4784 env.finish_branching(self.body.end_pos())
4786 env.start_branching(self.except_clauses[0].pos)
4787 for except_clause in self.except_clauses:
4788 except_clause.analyse_control_flow(env)
4789 env.next_branch(except_clause.end_pos())
4791 # the else cause it executed only when the try clause finishes
4792 env.control_flow.incoming = successful_try
4793 if self.else_clause:
4794 self.else_clause.analyse_control_flow(env)
4795 env.finish_branching(self.end_pos())
4797 def analyse_declarations(self, env):
4798 self.body.analyse_declarations(env)
4799 for except_clause in self.except_clauses:
4800 except_clause.analyse_declarations(env)
4801 if self.else_clause:
4802 self.else_clause.analyse_declarations(env)
4803 env.use_utility_code(reset_exception_utility_code)
4805 def analyse_expressions(self, env):
4806 self.body.analyse_expressions(env)
4807 default_clause_seen = 0
4808 for except_clause in self.except_clauses:
4809 except_clause.analyse_expressions(env)
4810 if default_clause_seen:
4811 error(except_clause.pos, "default 'except:' must be last")
4812 if not except_clause.pattern:
4813 default_clause_seen = 1
4814 self.has_default_clause = default_clause_seen
4815 if self.else_clause:
4816 self.else_clause.analyse_expressions(env)
4818 nogil_check = Node.gil_error
4819 gil_message = "Try-except statement"
4821 def generate_execution_code(self, code):
4822 old_return_label = code.return_label
4823 old_break_label = code.break_label
4824 old_continue_label = code.continue_label
4825 old_error_label = code.new_error_label()
4826 our_error_label = code.error_label
4827 except_end_label = code.new_label('exception_handled')
4828 except_error_label = code.new_label('except_error')
4829 except_return_label = code.new_label('except_return')
4830 try_return_label = code.new_label('try_return')
4831 try_break_label = code.new_label('try_break')
4832 try_continue_label = code.new_label('try_continue')
4833 try_end_label = code.new_label('try_end')
4835 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4838 code.putln("__Pyx_ExceptionSave(%s);" %
4839 ', '.join(['&%s' % var for var in exc_save_vars]))
4840 for var in exc_save_vars:
4841 code.put_xgotref(var)
4844 code.return_label = try_return_label
4845 code.break_label = try_break_label
4846 code.continue_label = try_continue_label
4847 self.body.generate_execution_code(code)
4850 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4851 code.error_label = except_error_label
4852 code.return_label = except_return_label
4853 if self.else_clause:
4856 self.else_clause.generate_execution_code(code)
4859 for var in exc_save_vars:
4860 code.put_xdecref_clear(var, py_object_type)
4861 code.put_goto(try_end_label)
4862 if code.label_used(try_return_label):
4863 code.put_label(try_return_label)
4864 for var in exc_save_vars: code.put_xgiveref(var)
4865 code.putln("__Pyx_ExceptionReset(%s);" %
4866 ', '.join(exc_save_vars))
4867 code.put_goto(old_return_label)
4868 code.put_label(our_error_label)
4869 for temp_name, type in temps_to_clean_up:
4870 code.put_xdecref_clear(temp_name, type)
4871 for except_clause in self.except_clauses:
4872 except_clause.generate_handling_code(code, except_end_label)
4874 error_label_used = code.label_used(except_error_label)
4875 if error_label_used or not self.has_default_clause:
4876 if error_label_used:
4877 code.put_label(except_error_label)
4878 for var in exc_save_vars: code.put_xgiveref(var)
4879 code.putln("__Pyx_ExceptionReset(%s);" %
4880 ', '.join(exc_save_vars))
4881 code.put_goto(old_error_label)
4883 for exit_label, old_label in zip(
4884 [try_break_label, try_continue_label, except_return_label],
4885 [old_break_label, old_continue_label, old_return_label]):
4887 if code.label_used(exit_label):
4888 code.put_label(exit_label)
4889 for var in exc_save_vars: code.put_xgiveref(var)
4890 code.putln("__Pyx_ExceptionReset(%s);" %
4891 ', '.join(exc_save_vars))
4892 code.put_goto(old_label)
4894 if code.label_used(except_end_label):
4895 code.put_label(except_end_label)
4896 for var in exc_save_vars: code.put_xgiveref(var)
4897 code.putln("__Pyx_ExceptionReset(%s);" %
4898 ', '.join(exc_save_vars))
4899 code.put_label(try_end_label)
4902 for cname in exc_save_vars:
4903 code.funcstate.release_temp(cname)
4905 code.return_label = old_return_label
4906 code.break_label = old_break_label
4907 code.continue_label = old_continue_label
4908 code.error_label = old_error_label
4910 def generate_function_definitions(self, env, code):
4911 self.body.generate_function_definitions(env, code)
4912 for except_clause in self.except_clauses:
4913 except_clause.generate_function_definitions(env, code)
4914 if self.else_clause is not None:
4915 self.else_clause.generate_function_definitions(env, code)
4917 def annotate(self, code):
4918 self.body.annotate(code)
4919 for except_node in self.except_clauses:
4920 except_node.annotate(code)
4921 if self.else_clause:
4922 self.else_clause.annotate(code)
4925 class ExceptClauseNode(Node):
4926 # Part of try ... except statement.
4928 # pattern [ExprNode]
4929 # target ExprNode or None
4931 # excinfo_target NameNode or None optional target for exception info
4932 # match_flag string result of exception match
4933 # exc_value ExcValueNode used internally
4934 # function_name string qualified name of enclosing function
4935 # exc_vars (string * 3) local exception variables
4937 # excinfo_target is never set by the parser, but can be set by a transform
4938 # in order to extract more extensive information about the exception as a
4939 # sys.exc_info()-style tuple into a target variable
4941 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4944 excinfo_target = None
4946 def analyse_declarations(self, env):
4948 self.target.analyse_target_declaration(env)
4949 if self.excinfo_target is not None:
4950 self.excinfo_target.analyse_target_declaration(env)
4951 self.body.analyse_declarations(env)
4953 def analyse_expressions(self, env):
4955 genv = env.global_scope()
4956 self.function_name = env.qualified_name
4958 # normalise/unpack self.pattern into a list
4959 for i, pattern in enumerate(self.pattern):
4960 pattern.analyse_expressions(env)
4961 self.pattern[i] = pattern.coerce_to_pyobject(env)
4964 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4965 self.target.analyse_target_expression(env, self.exc_value)
4966 if self.excinfo_target is not None:
4968 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4969 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4970 self.excinfo_tuple.analyse_expressions(env)
4971 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4973 self.body.analyse_expressions(env)
4975 def generate_handling_code(self, code, end_label):
4976 code.mark_pos(self.pos)
4979 for pattern in self.pattern:
4980 pattern.generate_evaluation_code(code)
4981 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4983 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4985 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4986 for pattern in self.pattern:
4987 pattern.generate_disposal_code(code)
4988 pattern.free_temps(code)
4992 code.funcstate.release_temp(match_flag)
4994 code.putln("/*except:*/ {")
4996 if not getattr(self.body, 'stats', True) and \
4997 self.excinfo_target is None and self.target is None:
4998 # most simple case: no exception variable, empty body (pass)
4999 # => reset the exception state, done
5000 code.putln("PyErr_Restore(0,0,0);")
5001 code.put_goto(end_label)
5005 exc_vars = [code.funcstate.allocate_temp(py_object_type,
5008 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
5009 # We always have to fetch the exception value even if
5010 # there is no target, because this also normalises the
5011 # exception and stores it in the thread state.
5012 code.globalstate.use_utility_code(get_exception_utility_code)
5013 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
5014 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
5015 code.error_goto(self.pos)))
5019 self.exc_value.set_var(exc_vars[1])
5020 self.exc_value.generate_evaluation_code(code)
5021 self.target.generate_assignment_code(self.exc_value, code)
5022 if self.excinfo_target is not None:
5023 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
5024 node.set_var(tempvar)
5025 self.excinfo_tuple.generate_evaluation_code(code)
5026 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
5028 old_break_label, old_continue_label = code.break_label, code.continue_label
5029 code.break_label = code.new_label('except_break')
5030 code.continue_label = code.new_label('except_continue')
5032 old_exc_vars = code.funcstate.exc_vars
5033 code.funcstate.exc_vars = exc_vars
5034 self.body.generate_execution_code(code)
5035 code.funcstate.exc_vars = old_exc_vars
5036 for var in exc_vars:
5037 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5038 code.put_goto(end_label)
5040 if code.label_used(code.break_label):
5041 code.put_label(code.break_label)
5042 for var in exc_vars:
5043 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5044 code.put_goto(old_break_label)
5045 code.break_label = old_break_label
5047 if code.label_used(code.continue_label):
5048 code.put_label(code.continue_label)
5049 for var in exc_vars:
5050 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5051 code.put_goto(old_continue_label)
5052 code.continue_label = old_continue_label
5054 for temp in exc_vars:
5055 code.funcstate.release_temp(temp)
5060 def generate_function_definitions(self, env, code):
5061 if self.target is not None:
5062 self.target.generate_function_definitions(env, code)
5063 self.body.generate_function_definitions(env, code)
5065 def annotate(self, code):
5067 for pattern in self.pattern:
5068 pattern.annotate(code)
5070 self.target.annotate(code)
5071 self.body.annotate(code)
5074 class TryFinallyStatNode(StatNode):
5075 # try ... finally statement
5078 # finally_clause StatNode
5080 # The plan is that we funnel all continue, break
5081 # return and error gotos into the beginning of the
5082 # finally block, setting a variable to remember which
5083 # one we're doing. At the end of the finally block, we
5084 # switch on the variable to figure out where to go.
5085 # In addition, if we're doing an error, we save the
5086 # exception on entry to the finally block and restore
5089 child_attrs = ["body", "finally_clause"]
5091 preserve_exception = 1
5093 disallow_continue_in_try_finally = 0
5094 # There doesn't seem to be any point in disallowing
5095 # continue in the try block, since we have no problem
5098 def create_analysed(pos, env, body, finally_clause):
5099 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5101 create_analysed = staticmethod(create_analysed)
5103 def analyse_control_flow(self, env):
5104 env.start_branching(self.pos)
5105 self.body.analyse_control_flow(env)
5106 env.next_branch(self.body.end_pos())
5107 env.finish_branching(self.body.end_pos())
5108 self.finally_clause.analyse_control_flow(env)
5110 def analyse_declarations(self, env):
5111 self.body.analyse_declarations(env)
5112 self.finally_clause.analyse_declarations(env)
5114 def analyse_expressions(self, env):
5115 self.body.analyse_expressions(env)
5116 self.finally_clause.analyse_expressions(env)
5118 nogil_check = Node.gil_error
5119 gil_message = "Try-finally statement"
5121 def generate_execution_code(self, code):
5122 old_error_label = code.error_label
5123 old_labels = code.all_new_labels()
5124 new_labels = code.get_all_labels()
5125 new_error_label = code.error_label
5126 catch_label = code.new_label()
5129 if self.disallow_continue_in_try_finally:
5130 was_in_try_finally = code.funcstate.in_try_finally
5131 code.funcstate.in_try_finally = 1
5132 self.body.generate_execution_code(code)
5133 if self.disallow_continue_in_try_finally:
5134 code.funcstate.in_try_finally = was_in_try_finally
5137 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5138 code.mark_pos(self.finally_clause.pos)
5142 error_label_used = 0
5143 for i, new_label in enumerate(new_labels):
5144 if new_label in code.labels_used:
5145 cases_used.append(i)
5146 if new_label == new_error_label:
5147 error_label_used = 1
5148 error_label_case = i
5152 if error_label_used and self.preserve_exception:
5154 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5156 "int %s;" % Naming.exc_lineno_name)
5157 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5158 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5159 code.putln(exc_var_init_zero)
5161 exc_var_init_zero = None
5162 code.use_label(catch_label)
5164 "__pyx_why = 0; goto %s;" % catch_label)
5165 for i in cases_used:
5166 new_label = new_labels[i]
5167 #if new_label and new_label != "<try>":
5168 if new_label == new_error_label and self.preserve_exception:
5169 self.put_error_catcher(code,
5170 new_error_label, i+1, catch_label, temps_to_clean_up)
5172 code.put('%s: ' % new_label)
5173 if exc_var_init_zero:
5174 code.putln(exc_var_init_zero)
5175 code.putln("__pyx_why = %s; goto %s;" % (
5178 code.put_label(catch_label)
5179 code.set_all_labels(old_labels)
5180 if error_label_used:
5181 code.new_error_label()
5182 finally_error_label = code.error_label
5183 self.finally_clause.generate_execution_code(code)
5184 if error_label_used:
5185 if finally_error_label in code.labels_used and self.preserve_exception:
5186 over_label = code.new_label()
5187 code.put_goto(over_label);
5188 code.put_label(finally_error_label)
5189 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5190 for var in Naming.exc_vars:
5191 code.putln("Py_XDECREF(%s);" % var)
5193 code.put_goto(old_error_label)
5194 code.put_label(over_label)
5195 code.error_label = old_error_label
5198 "switch (__pyx_why) {")
5199 for i in cases_used:
5200 old_label = old_labels[i]
5201 if old_label == old_error_label and self.preserve_exception:
5202 self.put_error_uncatcher(code, i+1, old_error_label)
5204 code.use_label(old_label)
5206 "case %s: goto %s;" % (
5214 def generate_function_definitions(self, env, code):
5215 self.body.generate_function_definitions(env, code)
5216 self.finally_clause.generate_function_definitions(env, code)
5218 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5219 code.globalstate.use_utility_code(restore_exception_utility_code)
5226 for temp_name, type in temps_to_clean_up:
5227 code.put_xdecref_clear(temp_name, type)
5229 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5233 Naming.exc_lineno_name, Naming.lineno_cname))
5234 code.put_goto(catch_label)
5237 def put_error_uncatcher(self, code, i, error_label):
5238 code.globalstate.use_utility_code(restore_exception_utility_code)
5243 "__Pyx_ErrRestore(%s, %s, %s);" %
5247 Naming.lineno_cname, Naming.exc_lineno_name))
5248 for var in Naming.exc_vars:
5252 code.put_goto(error_label)
5256 def annotate(self, code):
5257 self.body.annotate(code)
5258 self.finally_clause.annotate(code)
5261 class GILStatNode(TryFinallyStatNode):
5262 # 'with gil' or 'with nogil' statement
5264 # state string 'gil' or 'nogil'
5268 preserve_exception = 0
5270 def __init__(self, pos, state, body):
5272 TryFinallyStatNode.__init__(self, pos,
5274 finally_clause = GILExitNode(pos, state = state))
5276 def analyse_expressions(self, env):
5277 env.use_utility_code(force_init_threads_utility_code)
5278 was_nogil = env.nogil
5280 TryFinallyStatNode.analyse_expressions(self, env)
5281 env.nogil = was_nogil
5285 def generate_execution_code(self, code):
5286 code.mark_pos(self.pos)
5288 if self.state == 'gil':
5289 code.putln("#ifdef WITH_THREAD")
5290 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5291 code.putln("#endif")
5293 code.putln("#ifdef WITH_THREAD")
5294 code.putln("PyThreadState *_save;")
5295 code.putln("#endif")
5296 code.putln("Py_UNBLOCK_THREADS")
5297 TryFinallyStatNode.generate_execution_code(self, code)
5301 class GILExitNode(StatNode):
5302 # Used as the 'finally' block in a GILStatNode
5304 # state string 'gil' or 'nogil'
5308 def analyse_expressions(self, env):
5311 def generate_execution_code(self, code):
5312 if self.state == 'gil':
5313 code.putln("#ifdef WITH_THREAD")
5314 code.putln("PyGILState_Release(_save);")
5315 code.putln("#endif")
5317 code.putln("Py_BLOCK_THREADS")
5320 class CImportStatNode(StatNode):
5323 # module_name string Qualified name of module being imported
5324 # as_name string or None Name specified in "as" clause, if any
5328 def analyse_declarations(self, env):
5329 if not env.is_module_scope:
5330 error(self.pos, "cimport only allowed at module level")
5332 module_scope = env.find_module(self.module_name, self.pos)
5333 if "." in self.module_name:
5334 names = [EncodedString(name) for name in self.module_name.split(".")]
5336 top_module_scope = env.context.find_submodule(top_name)
5337 module_scope = top_module_scope
5338 for name in names[1:]:
5339 submodule_scope = module_scope.find_submodule(name)
5340 module_scope.declare_module(name, submodule_scope, self.pos)
5341 module_scope = submodule_scope
5343 env.declare_module(self.as_name, module_scope, self.pos)
5345 env.declare_module(top_name, top_module_scope, self.pos)
5347 name = self.as_name or self.module_name
5348 env.declare_module(name, module_scope, self.pos)
5350 def analyse_expressions(self, env):
5353 def generate_execution_code(self, code):
5357 class FromCImportStatNode(StatNode):
5358 # from ... cimport statement
5360 # module_name string Qualified name of module
5361 # imported_names [(pos, name, as_name, kind)] Names to be imported
5365 def analyse_declarations(self, env):
5366 if not env.is_module_scope:
5367 error(self.pos, "cimport only allowed at module level")
5369 module_scope = env.find_module(self.module_name, self.pos)
5370 env.add_imported_module(module_scope)
5371 for pos, name, as_name, kind in self.imported_names:
5373 for local_name, entry in module_scope.entries.items():
5374 env.add_imported_entry(local_name, entry, pos)
5376 entry = module_scope.lookup(name)
5378 if kind and not self.declaration_matches(entry, kind):
5379 entry.redeclared(pos)
5381 if kind == 'struct' or kind == 'union':
5382 entry = module_scope.declare_struct_or_union(name,
5383 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5384 elif kind == 'class':
5385 entry = module_scope.declare_c_class(name, pos = pos,
5386 module_name = self.module_name)
5388 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5389 if submodule_scope.parent_module is module_scope:
5390 env.declare_module(as_name or name, submodule_scope, self.pos)
5392 error(pos, "Name '%s' not declared in module '%s'"
5393 % (name, self.module_name))
5396 local_name = as_name or name
5397 env.add_imported_entry(local_name, entry, pos)
5399 def declaration_matches(self, entry, kind):
5400 if not entry.is_type:
5404 if not type.is_extension_type:
5407 if not type.is_struct_or_union:
5409 if kind != type.kind:
5413 def analyse_expressions(self, env):
5416 def generate_execution_code(self, code):
5420 class FromImportStatNode(StatNode):
5421 # from ... import statement
5424 # items [(string, NameNode)]
5425 # interned_items [(string, NameNode, ExprNode)]
5426 # item PyTempNode used internally
5427 # import_star boolean used internally
5429 child_attrs = ["module"]
5432 def analyse_declarations(self, env):
5433 for name, target in self.items:
5435 if not env.is_module_scope:
5436 error(self.pos, "import * only allowed at module level")
5438 env.has_import_star = 1
5439 self.import_star = 1
5441 target.analyse_target_declaration(env)
5443 def analyse_expressions(self, env):
5445 self.module.analyse_expressions(env)
5446 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5447 self.interned_items = []
5448 for name, target in self.items:
5450 for _, entry in env.entries.items():
5451 if not entry.is_type and entry.type.is_extension_type:
5452 env.use_utility_code(ExprNodes.type_test_utility_code)
5455 entry = env.lookup(target.name)
5456 # check whether or not entry is already cimported
5457 if (entry.is_type and entry.type.name == name
5458 and hasattr(entry.type, 'module_name')):
5459 if entry.type.module_name == self.module.module_name.value:
5460 # cimported with absolute name
5463 # cimported with relative name
5464 module = env.find_module(self.module.module_name.value,
5466 if entry.type.module_name == module.qualified_name:
5468 except AttributeError:
5470 target.analyse_target_expression(env, None)
5471 if target.type is py_object_type:
5474 coerced_item = self.item.coerce_to(target.type, env)
5475 self.interned_items.append((name, target, coerced_item))
5477 def generate_execution_code(self, code):
5478 self.module.generate_evaluation_code(code)
5479 if self.import_star:
5481 'if (%s(%s) < 0) %s;' % (
5483 self.module.py_result(),
5484 code.error_goto(self.pos)))
5485 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5486 self.item.set_cname(item_temp)
5487 for name, target, coerced_item in self.interned_items:
5488 cname = code.intern_identifier(name)
5490 '%s = PyObject_GetAttr(%s, %s); %s' % (
5492 self.module.py_result(),
5494 code.error_goto_if_null(item_temp, self.pos)))
5495 code.put_gotref(item_temp)
5496 if coerced_item is None:
5497 target.generate_assignment_code(self.item, code)
5499 coerced_item.allocate_temp_result(code)
5500 coerced_item.generate_result_code(code)
5501 target.generate_assignment_code(coerced_item, code)
5502 code.put_decref_clear(item_temp, py_object_type)
5503 code.funcstate.release_temp(item_temp)
5504 self.module.generate_disposal_code(code)
5505 self.module.free_temps(code)
5509 #------------------------------------------------------------------------------------
5511 # Runtime support code
5513 #------------------------------------------------------------------------------------
5515 utility_function_predeclarations = \
5517 /* inline attribute */
5518 #ifndef CYTHON_INLINE
5519 #if defined(__GNUC__)
5520 #define CYTHON_INLINE __inline__
5521 #elif defined(_MSC_VER)
5522 #define CYTHON_INLINE __inline
5523 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5524 #define CYTHON_INLINE inline
5526 #define CYTHON_INLINE
5530 /* unused attribute */
5531 #ifndef CYTHON_UNUSED
5532 # if defined(__GNUC__)
5533 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5534 # define CYTHON_UNUSED __attribute__ ((__unused__))
5536 # define CYTHON_UNUSED
5538 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5539 # define CYTHON_UNUSED __attribute__ ((__unused__))
5541 # define CYTHON_UNUSED
5545 typedef struct {PyObject **p; char *s; const long n; const char* encoding; const char is_unicode; const char is_str; const char intern; } __Pyx_StringTabEntry; /*proto*/
5549 if Options.gcc_branch_hints:
5550 branch_prediction_macros = \
5553 /* Test for GCC > 2.95 */
5554 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5555 #define likely(x) __builtin_expect(!!(x), 1)
5556 #define unlikely(x) __builtin_expect(!!(x), 0)
5557 #else /* __GNUC__ > 2 ... */
5558 #define likely(x) (x)
5559 #define unlikely(x) (x)
5560 #endif /* __GNUC__ > 2 ... */
5561 #else /* __GNUC__ */
5562 #define likely(x) (x)
5563 #define unlikely(x) (x)
5564 #endif /* __GNUC__ */
5567 branch_prediction_macros = \
5569 #define likely(x) (x)
5570 #define unlikely(x) (x)
5573 #get_name_predeclaration = \
5574 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5576 #get_name_interned_predeclaration = \
5577 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5579 #------------------------------------------------------------------------------------
5581 printing_utility_code = UtilityCode(
5583 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5584 #if PY_MAJOR_VERSION >= 3
5585 static PyObject* %s = 0;
5586 static PyObject* %s = 0;
5588 """ % (Naming.print_function, Naming.print_function_kwargs),
5590 #if PY_MAJOR_VERSION >= 3
5594 """ % (Naming.print_function, Naming.print_function_kwargs),
5596 #if PY_MAJOR_VERSION < 3
5597 static PyObject *__Pyx_GetStdout(void) {
5598 PyObject *f = PySys_GetObject((char *)"stdout");
5600 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5605 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5610 if (!(f = __Pyx_GetStdout()))
5613 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5614 if (PyFile_SoftSpace(f, 1)) {
5615 if (PyFile_WriteString(" ", f) < 0)
5618 v = PyTuple_GET_ITEM(arg_tuple, i);
5619 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5621 if (PyString_Check(v)) {
5622 char *s = PyString_AsString(v);
5623 Py_ssize_t len = PyString_Size(v);
5625 isspace(Py_CHARMASK(s[len-1])) &&
5627 PyFile_SoftSpace(f, 0);
5631 if (PyFile_WriteString("\n", f) < 0)
5633 PyFile_SoftSpace(f, 0);
5638 #else /* Python 3 has a print function */
5640 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5641 PyObject* kwargs = 0;
5642 PyObject* result = 0;
5643 PyObject* end_string;
5644 if (unlikely(!%(PRINT_FUNCTION)s)) {
5645 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5646 if (!%(PRINT_FUNCTION)s)
5650 kwargs = PyDict_New();
5651 if (unlikely(!kwargs))
5653 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5656 end_string = PyUnicode_FromStringAndSize(" ", 1);
5657 if (unlikely(!end_string))
5659 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5660 Py_DECREF(end_string);
5663 Py_DECREF(end_string);
5665 } else if (!newline) {
5666 if (unlikely(!%(PRINT_KWARGS)s)) {
5667 %(PRINT_KWARGS)s = PyDict_New();
5668 if (unlikely(!%(PRINT_KWARGS)s))
5670 end_string = PyUnicode_FromStringAndSize(" ", 1);
5671 if (unlikely(!end_string))
5673 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5674 Py_DECREF(end_string);
5677 Py_DECREF(end_string);
5679 kwargs = %(PRINT_KWARGS)s;
5681 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5682 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5689 if (kwargs != %(PRINT_KWARGS)s)
5695 """ % {'BUILTINS' : Naming.builtins_cname,
5696 'PRINT_FUNCTION' : Naming.print_function,
5697 'PRINT_KWARGS' : Naming.print_function_kwargs}
5701 printing_one_utility_code = UtilityCode(
5703 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5706 #if PY_MAJOR_VERSION < 3
5708 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5710 if (!(f = __Pyx_GetStdout()))
5713 if (PyFile_SoftSpace(f, 0)) {
5714 if (PyFile_WriteString(" ", f) < 0)
5717 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5719 if (PyFile_WriteString("\n", f) < 0)
5722 /* the line below is just to avoid compiler
5723 * compiler warnings about unused functions */
5724 return __Pyx_Print(f, NULL, 0);
5727 #else /* Python 3 has a print function */
5729 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5731 PyObject* arg_tuple = PyTuple_New(1);
5732 if (unlikely(!arg_tuple))
5735 PyTuple_SET_ITEM(arg_tuple, 0, o);
5736 res = __Pyx_Print(stream, arg_tuple, 1);
5737 Py_DECREF(arg_tuple);
5743 requires=[printing_utility_code])
5747 #------------------------------------------------------------------------------------
5749 # Exception raising code
5751 # Exceptions are raised by __Pyx_Raise() and stored as plain
5752 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5753 # 'except' statement, curexc_* is moved over to exc_* by
5754 # __Pyx_GetException()
5756 restore_exception_utility_code = UtilityCode(
5758 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5759 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5762 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5763 PyObject *tmp_type, *tmp_value, *tmp_tb;
5764 PyThreadState *tstate = PyThreadState_GET();
5766 tmp_type = tstate->curexc_type;
5767 tmp_value = tstate->curexc_value;
5768 tmp_tb = tstate->curexc_traceback;
5769 tstate->curexc_type = type;
5770 tstate->curexc_value = value;
5771 tstate->curexc_traceback = tb;
5772 Py_XDECREF(tmp_type);
5773 Py_XDECREF(tmp_value);
5777 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5778 PyThreadState *tstate = PyThreadState_GET();
5779 *type = tstate->curexc_type;
5780 *value = tstate->curexc_value;
5781 *tb = tstate->curexc_traceback;
5783 tstate->curexc_type = 0;
5784 tstate->curexc_value = 0;
5785 tstate->curexc_traceback = 0;
5790 # The following function is based on do_raise() from ceval.c. There
5791 # are separate versions for Python2 and Python3 as exception handling
5792 # has changed quite a lot between the two versions.
5794 raise_utility_code = UtilityCode(
5796 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5799 #if PY_MAJOR_VERSION < 3
5800 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5804 /* First, check the traceback argument, replacing None with NULL. */
5805 if (tb == Py_None) {
5809 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5810 PyErr_SetString(PyExc_TypeError,
5811 "raise: arg 3 must be a traceback or None");
5814 /* Next, replace a missing value with None */
5815 if (value == NULL) {
5819 #if PY_VERSION_HEX < 0x02050000
5820 if (!PyClass_Check(type))
5822 if (!PyType_Check(type))
5825 /* Raising an instance. The value should be a dummy. */
5826 if (value != Py_None) {
5827 PyErr_SetString(PyExc_TypeError,
5828 "instance exception may not have a separate value");
5831 /* Normalize to raise <class>, <instance> */
5834 #if PY_VERSION_HEX < 0x02050000
5835 if (PyInstance_Check(type)) {
5836 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5841 PyErr_SetString(PyExc_TypeError,
5842 "raise: exception must be an old-style class or instance");
5846 type = (PyObject*) Py_TYPE(type);
5848 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5849 PyErr_SetString(PyExc_TypeError,
5850 "raise: exception class must be a subclass of BaseException");
5856 __Pyx_ErrRestore(type, value, tb);
5865 #else /* Python 3+ */
5867 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5868 if (tb == Py_None) {
5870 } else if (tb && !PyTraceBack_Check(tb)) {
5871 PyErr_SetString(PyExc_TypeError,
5872 "raise: arg 3 must be a traceback or None");
5875 if (value == Py_None)
5878 if (PyExceptionInstance_Check(type)) {
5880 PyErr_SetString(PyExc_TypeError,
5881 "instance exception may not have a separate value");
5885 type = (PyObject*) Py_TYPE(value);
5886 } else if (!PyExceptionClass_Check(type)) {
5887 PyErr_SetString(PyExc_TypeError,
5888 "raise: exception class must be a subclass of BaseException");
5892 PyErr_SetObject(type, value);
5895 PyThreadState *tstate = PyThreadState_GET();
5896 PyObject* tmp_tb = tstate->curexc_traceback;
5899 tstate->curexc_traceback = tb;
5909 requires=[restore_exception_utility_code])
5911 #------------------------------------------------------------------------------------
5913 get_exception_utility_code = UtilityCode(
5915 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5918 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5919 PyObject *local_type, *local_value, *local_tb;
5920 PyObject *tmp_type, *tmp_value, *tmp_tb;
5921 PyThreadState *tstate = PyThreadState_GET();
5922 local_type = tstate->curexc_type;
5923 local_value = tstate->curexc_value;
5924 local_tb = tstate->curexc_traceback;
5925 tstate->curexc_type = 0;
5926 tstate->curexc_value = 0;
5927 tstate->curexc_traceback = 0;
5928 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5929 if (unlikely(tstate->curexc_type))
5931 #if PY_MAJOR_VERSION >= 3
5932 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5936 *value = local_value;
5938 Py_INCREF(local_type);
5939 Py_INCREF(local_value);
5940 Py_INCREF(local_tb);
5941 tmp_type = tstate->exc_type;
5942 tmp_value = tstate->exc_value;
5943 tmp_tb = tstate->exc_traceback;
5944 tstate->exc_type = local_type;
5945 tstate->exc_value = local_value;
5946 tstate->exc_traceback = local_tb;
5947 /* Make sure tstate is in a consistent state when we XDECREF
5948 these objects (XDECREF may run arbitrary code). */
5949 Py_XDECREF(tmp_type);
5950 Py_XDECREF(tmp_value);
5957 Py_XDECREF(local_type);
5958 Py_XDECREF(local_value);
5959 Py_XDECREF(local_tb);
5965 #------------------------------------------------------------------------------------
5967 get_exception_tuple_utility_code = UtilityCode(proto="""
5968 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5970 # I doubt that calling __Pyx_GetException() here is correct as it moves
5971 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5972 # exception handlers later on from receiving it.
5974 static PyObject *__Pyx_GetExceptionTuple(void) {
5975 PyObject *type = NULL, *value = NULL, *tb = NULL;
5976 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5977 PyObject* exc_info = PyTuple_New(3);
5982 PyTuple_SET_ITEM(exc_info, 0, type);
5983 PyTuple_SET_ITEM(exc_info, 1, value);
5984 PyTuple_SET_ITEM(exc_info, 2, tb);
5991 requires=[get_exception_utility_code])
5993 #------------------------------------------------------------------------------------
5995 reset_exception_utility_code = UtilityCode(
5997 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5998 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
6001 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
6002 PyThreadState *tstate = PyThreadState_GET();
6003 *type = tstate->exc_type;
6004 *value = tstate->exc_value;
6005 *tb = tstate->exc_traceback;
6011 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
6012 PyObject *tmp_type, *tmp_value, *tmp_tb;
6013 PyThreadState *tstate = PyThreadState_GET();
6014 tmp_type = tstate->exc_type;
6015 tmp_value = tstate->exc_value;
6016 tmp_tb = tstate->exc_traceback;
6017 tstate->exc_type = type;
6018 tstate->exc_value = value;
6019 tstate->exc_traceback = tb;
6020 Py_XDECREF(tmp_type);
6021 Py_XDECREF(tmp_value);
6026 #------------------------------------------------------------------------------------
6028 arg_type_test_utility_code = UtilityCode(
6030 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6031 const char *name, int exact); /*proto*/
6034 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
6035 const char *name, int exact)
6038 PyErr_Format(PyExc_SystemError, "Missing type object");
6041 if (none_allowed && obj == Py_None) return 1;
6043 if (Py_TYPE(obj) == type) return 1;
6046 if (PyObject_TypeCheck(obj, type)) return 1;
6048 PyErr_Format(PyExc_TypeError,
6049 "Argument '%s' has incorrect type (expected %s, got %s)",
6050 name, type->tp_name, Py_TYPE(obj)->tp_name);
6055 #------------------------------------------------------------------------------------
6057 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
6058 # many or too few positional arguments were found. This handles
6059 # Py_ssize_t formatting correctly.
6061 raise_argtuple_invalid_utility_code = UtilityCode(
6063 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
6064 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
6067 static void __Pyx_RaiseArgtupleInvalid(
6068 const char* func_name,
6072 Py_ssize_t num_found)
6074 Py_ssize_t num_expected;
6075 const char *number, *more_or_less;
6077 if (num_found < num_min) {
6078 num_expected = num_min;
6079 more_or_less = "at least";
6081 num_expected = num_max;
6082 more_or_less = "at most";
6085 more_or_less = "exactly";
6087 number = (num_expected == 1) ? "" : "s";
6088 PyErr_Format(PyExc_TypeError,
6089 #if PY_VERSION_HEX < 0x02050000
6090 "%s() takes %s %d positional argument%s (%d given)",
6092 "%s() takes %s %zd positional argument%s (%zd given)",
6094 func_name, more_or_less, num_expected, number, num_found);
6098 raise_keyword_required_utility_code = UtilityCode(
6100 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6103 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6104 const char* func_name,
6107 PyErr_Format(PyExc_TypeError,
6108 #if PY_MAJOR_VERSION >= 3
6109 "%s() needs keyword-only argument %U", func_name, kw_name);
6111 "%s() needs keyword-only argument %s", func_name,
6112 PyString_AS_STRING(kw_name));
6117 raise_double_keywords_utility_code = UtilityCode(
6119 static void __Pyx_RaiseDoubleKeywordsError(
6120 const char* func_name, PyObject* kw_name); /*proto*/
6123 static void __Pyx_RaiseDoubleKeywordsError(
6124 const char* func_name,
6127 PyErr_Format(PyExc_TypeError,
6128 #if PY_MAJOR_VERSION >= 3
6129 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6131 "%s() got multiple values for keyword argument '%s'", func_name,
6132 PyString_AS_STRING(kw_name));
6137 #------------------------------------------------------------------------------------
6139 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6140 # were passed to a function, or if any keywords were passed to a
6141 # function that does not accept them.
6143 keyword_string_check_utility_code = UtilityCode(
6145 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6146 const char* function_name, int kw_allowed); /*proto*/
6149 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6151 const char* function_name,
6156 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6157 #if PY_MAJOR_VERSION < 3
6158 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6160 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6162 goto invalid_keyword_type;
6164 if ((!kw_allowed) && unlikely(key))
6165 goto invalid_keyword;
6167 invalid_keyword_type:
6168 PyErr_Format(PyExc_TypeError,
6169 "%s() keywords must be strings", function_name);
6172 PyErr_Format(PyExc_TypeError,
6173 #if PY_MAJOR_VERSION < 3
6174 "%s() got an unexpected keyword argument '%s'",
6175 function_name, PyString_AsString(key));
6177 "%s() got an unexpected keyword argument '%U'",
6178 function_name, key);
6184 #------------------------------------------------------------------------------------
6186 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6187 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6188 # keywords will raise an invalid keyword error.
6190 # Three kinds of errors are checked: 1) non-string keywords, 2)
6191 # unexpected keywords and 3) overlap with positional arguments.
6193 # If num_posargs is greater 0, it denotes the number of positional
6194 # arguments that were passed and that must therefore not appear
6195 # amongst the keywords as well.
6197 # This method does not check for required keyword arguments.
6200 parse_keywords_utility_code = UtilityCode(
6202 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6203 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6204 const char* function_name); /*proto*/
6207 static int __Pyx_ParseOptionalKeywords(
6209 PyObject **argnames[],
6212 Py_ssize_t num_pos_args,
6213 const char* function_name)
6215 PyObject *key = 0, *value = 0;
6218 PyObject*** first_kw_arg = argnames + num_pos_args;
6220 while (PyDict_Next(kwds, &pos, &key, &value)) {
6221 name = first_kw_arg;
6222 while (*name && (**name != key)) name++;
6224 values[name-argnames] = value;
6226 #if PY_MAJOR_VERSION < 3
6227 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6229 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6231 goto invalid_keyword_type;
6233 for (name = first_kw_arg; *name; name++) {
6234 #if PY_MAJOR_VERSION >= 3
6235 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6236 PyUnicode_Compare(**name, key) == 0) break;
6238 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6239 _PyString_Eq(**name, key)) break;
6243 values[name-argnames] = value;
6245 /* unexpected keyword found */
6246 for (name=argnames; name != first_kw_arg; name++) {
6247 if (**name == key) goto arg_passed_twice;
6248 #if PY_MAJOR_VERSION >= 3
6249 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6250 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6252 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6253 _PyString_Eq(**name, key)) goto arg_passed_twice;
6257 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6259 goto invalid_keyword;
6267 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6269 invalid_keyword_type:
6270 PyErr_Format(PyExc_TypeError,
6271 "%s() keywords must be strings", function_name);
6274 PyErr_Format(PyExc_TypeError,
6275 #if PY_MAJOR_VERSION < 3
6276 "%s() got an unexpected keyword argument '%s'",
6277 function_name, PyString_AsString(key));
6279 "%s() got an unexpected keyword argument '%U'",
6280 function_name, key);
6286 requires=[raise_double_keywords_utility_code])
6288 #------------------------------------------------------------------------------------
6290 traceback_utility_code = UtilityCode(
6292 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6295 #include "compile.h"
6296 #include "frameobject.h"
6297 #include "traceback.h"
6299 static void __Pyx_AddTraceback(const char *funcname) {
6300 PyObject *py_srcfile = 0;
6301 PyObject *py_funcname = 0;
6302 PyObject *py_globals = 0;
6303 PyCodeObject *py_code = 0;
6304 PyFrameObject *py_frame = 0;
6306 #if PY_MAJOR_VERSION < 3
6307 py_srcfile = PyString_FromString(%(FILENAME)s);
6309 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6311 if (!py_srcfile) goto bad;
6313 #if PY_MAJOR_VERSION < 3
6314 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6316 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6320 #if PY_MAJOR_VERSION < 3
6321 py_funcname = PyString_FromString(funcname);
6323 py_funcname = PyUnicode_FromString(funcname);
6326 if (!py_funcname) goto bad;
6327 py_globals = PyModule_GetDict(%(GLOBALS)s);
6328 if (!py_globals) goto bad;
6329 py_code = PyCode_New(
6330 0, /*int argcount,*/
6331 #if PY_MAJOR_VERSION >= 3
6332 0, /*int kwonlyargcount,*/
6335 0, /*int stacksize,*/
6337 %(EMPTY_BYTES)s, /*PyObject *code,*/
6338 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6339 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6340 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6341 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6342 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6343 py_srcfile, /*PyObject *filename,*/
6344 py_funcname, /*PyObject *name,*/
6345 %(LINENO)s, /*int firstlineno,*/
6346 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6348 if (!py_code) goto bad;
6349 py_frame = PyFrame_New(
6350 PyThreadState_GET(), /*PyThreadState *tstate,*/
6351 py_code, /*PyCodeObject *code,*/
6352 py_globals, /*PyObject *globals,*/
6353 0 /*PyObject *locals*/
6355 if (!py_frame) goto bad;
6356 py_frame->f_lineno = %(LINENO)s;
6357 PyTraceBack_Here(py_frame);
6359 Py_XDECREF(py_srcfile);
6360 Py_XDECREF(py_funcname);
6361 Py_XDECREF(py_code);
6362 Py_XDECREF(py_frame);
6365 'FILENAME': Naming.filename_cname,
6366 'LINENO': Naming.lineno_cname,
6367 'CFILENAME': Naming.cfilenm_cname,
6368 'CLINENO': Naming.clineno_cname,
6369 'GLOBALS': Naming.module_cname,
6370 'EMPTY_TUPLE' : Naming.empty_tuple,
6371 'EMPTY_BYTES' : Naming.empty_bytes,
6374 #------------------------------------------------------------------------------------
6376 unraisable_exception_utility_code = UtilityCode(
6378 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6381 static void __Pyx_WriteUnraisable(const char *name) {
6382 PyObject *old_exc, *old_val, *old_tb;
6384 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6385 #if PY_MAJOR_VERSION < 3
6386 ctx = PyString_FromString(name);
6388 ctx = PyUnicode_FromString(name);
6390 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6392 PyErr_WriteUnraisable(Py_None);
6394 PyErr_WriteUnraisable(ctx);
6399 requires=[restore_exception_utility_code])
6401 #------------------------------------------------------------------------------------
6403 set_vtable_utility_code = UtilityCode(
6405 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6408 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6409 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6410 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6412 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6416 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6426 #------------------------------------------------------------------------------------
6428 get_vtable_utility_code = UtilityCode(
6430 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6433 static void* __Pyx_GetVtable(PyObject *dict) {
6435 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6438 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6439 ptr = PyCapsule_GetPointer(ob, 0);
6441 ptr = PyCObject_AsVoidPtr(ob);
6443 if (!ptr && !PyErr_Occurred())
6444 PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6453 #------------------------------------------------------------------------------------
6455 init_string_tab_utility_code = UtilityCode(
6457 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6460 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6462 #if PY_MAJOR_VERSION < 3
6463 if (t->is_unicode) {
6464 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6465 } else if (t->intern) {
6466 *t->p = PyString_InternFromString(t->s);
6468 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6470 #else /* Python 3+ has unicode identifiers */
6471 if (t->is_unicode | t->is_str) {
6473 *t->p = PyUnicode_InternFromString(t->s);
6474 } else if (t->encoding) {
6475 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6477 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6480 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6491 #------------------------------------------------------------------------------------
6493 force_init_threads_utility_code = UtilityCode(
6495 #ifndef __PYX_FORCE_INIT_THREADS
6496 #if PY_VERSION_HEX < 0x02040200
6497 #define __PYX_FORCE_INIT_THREADS 1
6499 #define __PYX_FORCE_INIT_THREADS 0
6504 #------------------------------------------------------------------------------------
6506 # Note that cPython ignores PyTrace_EXCEPTION,
6507 # but maybe some other profilers don't.
6509 profile_utility_code = UtilityCode(proto="""
6510 #ifndef CYTHON_PROFILE
6511 #define CYTHON_PROFILE 1
6514 #ifndef CYTHON_PROFILE_REUSE_FRAME
6515 #define CYTHON_PROFILE_REUSE_FRAME 0
6520 #include "compile.h"
6521 #include "frameobject.h"
6522 #include "traceback.h"
6524 #if CYTHON_PROFILE_REUSE_FRAME
6525 #define CYTHON_FRAME_MODIFIER static
6526 #define CYTHON_FRAME_DEL
6528 #define CYTHON_FRAME_MODIFIER
6529 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6532 #define __Pyx_TraceDeclarations \\
6533 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6534 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6535 int __Pyx_use_tracing = 0;
6537 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6538 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6539 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6542 #define __Pyx_TraceException() \\
6543 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6544 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6546 PyThreadState_GET()->c_profilefunc( \\
6547 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6548 Py_DECREF(exc_info); \\
6552 #define __Pyx_TraceReturn(result) \\
6553 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6554 PyThreadState_GET()->c_profilefunc( \\
6555 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6556 CYTHON_FRAME_DEL; \\
6559 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6560 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6564 #define __Pyx_TraceDeclarations
6565 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6566 #define __Pyx_TraceException()
6567 #define __Pyx_TraceReturn(result)
6569 #endif /* CYTHON_PROFILE */
6572 "FRAME": Naming.frame_cname,
6573 "FRAME_CODE": Naming.frame_code_cname,
6579 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6580 PyFrameObject** frame,
6581 const char *funcname,
6582 const char *srcfile,
6584 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6585 if (*code == NULL) {
6586 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6587 if (*code == NULL) return 0;
6589 *frame = PyFrame_New(
6590 PyThreadState_GET(), /*PyThreadState *tstate*/
6591 *code, /*PyCodeObject *code*/
6592 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6593 0 /*PyObject *locals*/
6595 if (*frame == NULL) return 0;
6598 (*frame)->f_tstate = PyThreadState_GET();
6600 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6603 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6604 PyObject *py_srcfile = 0;
6605 PyObject *py_funcname = 0;
6606 PyCodeObject *py_code = 0;
6608 #if PY_MAJOR_VERSION < 3
6609 py_funcname = PyString_FromString(funcname);
6610 py_srcfile = PyString_FromString(srcfile);
6612 py_funcname = PyUnicode_FromString(funcname);
6613 py_srcfile = PyUnicode_FromString(srcfile);
6615 if (!py_funcname | !py_srcfile) goto bad;
6617 py_code = PyCode_New(
6618 0, /*int argcount,*/
6619 #if PY_MAJOR_VERSION >= 3
6620 0, /*int kwonlyargcount,*/
6623 0, /*int stacksize,*/
6625 %(EMPTY_BYTES)s, /*PyObject *code,*/
6626 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6627 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6628 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6629 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6630 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6631 py_srcfile, /*PyObject *filename,*/
6632 py_funcname, /*PyObject *name,*/
6633 firstlineno, /*int firstlineno,*/
6634 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6638 Py_XDECREF(py_srcfile);
6639 Py_XDECREF(py_funcname);
6644 #endif /* CYTHON_PROFILE */
6646 'EMPTY_TUPLE' : Naming.empty_tuple,
6647 'EMPTY_BYTES' : Naming.empty_bytes,
6648 "MODULE": Naming.module_cname,