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
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
1172 def analyse_default_values(self, env):
1173 genv = env.global_scope()
1175 for arg in self.args:
1179 arg.default.analyse_types(env)
1180 arg.default = arg.default.coerce_to(arg.type, genv)
1183 "This argument cannot have a default value")
1188 error(arg.pos, "Non-default argument following default argument")
1190 def need_gil_acquisition(self, lenv):
1193 def create_local_scope(self, env):
1195 while genv.is_py_class_scope or genv.is_c_class_scope:
1196 genv = genv.outer_scope
1197 if self.needs_closure:
1198 lenv = ClosureScope(name=self.entry.name,
1200 scope_name=self.entry.cname)
1202 lenv = LocalScope(name=self.entry.name,
1205 lenv.return_type = self.return_type
1206 type = self.entry.type
1207 if type.is_cfunction:
1208 lenv.nogil = type.nogil and not type.with_gil
1209 self.local_scope = lenv
1210 lenv.directives = env.directives
1213 def generate_function_definitions(self, env, code):
1216 lenv = self.local_scope
1217 if lenv.is_closure_scope and not lenv.is_passthrough:
1218 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1219 Naming.outer_scope_cname)
1221 outer_scope_cname = Naming.outer_scope_cname
1222 lenv.mangle_closure_cnames(outer_scope_cname)
1223 # Generate closure function definitions
1224 self.body.generate_function_definitions(lenv, code)
1225 # generate lambda function definitions
1226 self.generate_lambda_definitions(lenv, code)
1228 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1229 self.entry.scope.is_c_class_scope)
1230 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1231 self.entry.scope.is_c_class_scope)
1232 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1234 if 'cython_unused' not in self.modifiers:
1235 self.modifiers = self.modifiers + ['cython_unused']
1237 preprocessor_guard = None
1238 if self.entry.is_special and not is_buffer_slot:
1239 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1241 preprocessor_guard = slot.preprocessor_guard_code()
1242 if (self.entry.name == '__long__' and
1243 not self.entry.scope.lookup_here('__int__')):
1244 preprocessor_guard = None
1246 profile = code.globalstate.directives['profile']
1249 error(self.pos, "Cannot profile nogil function.")
1250 code.globalstate.use_utility_code(profile_utility_code)
1252 # Generate C code for header and body of function
1253 code.enter_cfunc_scope()
1254 code.return_from_error_cleanup_label = code.new_label()
1256 # ----- Top-level constants used by this function
1257 code.mark_pos(self.pos)
1258 self.generate_cached_builtins_decls(lenv, code)
1259 # ----- Function header
1262 if preprocessor_guard:
1263 code.putln(preprocessor_guard)
1265 with_pymethdef = self.needs_assignment_synthesis(env, code)
1267 self.py_func.generate_function_header(code,
1268 with_pymethdef = with_pymethdef,
1270 self.generate_function_header(code,
1271 with_pymethdef = with_pymethdef)
1272 # ----- Local variable declarations
1273 # Find function scope
1275 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1276 cenv = cenv.outer_scope
1277 if self.needs_closure:
1278 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1280 elif self.needs_outer_scope:
1281 if lenv.is_passthrough:
1282 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1284 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1286 self.generate_argument_declarations(lenv, code)
1287 for entry in lenv.var_entries:
1288 if not entry.in_closure:
1289 code.put_var_declaration(entry)
1291 if not self.return_type.is_void:
1292 if self.return_type.is_pyobject:
1296 (self.return_type.declaration_code(Naming.retval_cname),
1298 tempvardecl_code = code.insertion_point()
1299 if not self.is_generator:
1300 self.generate_keyword_list(code)
1302 code.put_trace_declarations()
1303 # ----- Extern library function declarations
1304 lenv.generate_library_function_declarations(code)
1305 # ----- GIL acquisition
1306 acquire_gil = self.acquire_gil
1308 env.use_utility_code(force_init_threads_utility_code)
1309 code.putln("#ifdef WITH_THREAD")
1310 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1311 code.putln("#endif")
1312 # ----- set up refnanny
1314 code.put_setup_refcount_context(self.entry.name)
1315 # ----- Automatic lead-ins for certain special functions
1316 if is_getbuffer_slot:
1317 self.getbuffer_init(code)
1318 # ----- Create closure scope object
1319 if self.is_generator:
1320 code.putln("%s = (%s) %s;" % (
1321 Naming.cur_scope_cname,
1322 lenv.scope_class.type.declaration_code(''),
1324 gotref_code = code.insertion_point()
1326 elif self.needs_closure:
1327 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1328 Naming.cur_scope_cname,
1329 lenv.scope_class.type.declaration_code(''),
1330 lenv.scope_class.type.typeptr_cname,
1331 lenv.scope_class.type.typeptr_cname,
1332 Naming.empty_tuple))
1333 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1334 if is_getbuffer_slot:
1335 self.getbuffer_error_cleanup(code)
1337 code.put_finish_refcount_context()
1338 # FIXME: what if the error return value is a Python value?
1339 code.putln("return %s;" % self.error_value())
1341 code.put_gotref(Naming.cur_scope_cname)
1342 # Note that it is unsafe to decref the scope at this point.
1343 if self.needs_outer_scope and not self.is_generator:
1344 code.putln("%s = (%s)%s;" % (
1346 cenv.scope_class.type.declaration_code(''),
1348 if lenv.is_passthrough:
1349 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1350 elif self.needs_closure:
1351 # inner closures own a reference to their outer parent
1352 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1353 code.put_giveref(outer_scope_cname)
1354 # ----- Trace function call
1356 # this looks a bit late, but if we don't get here due to a
1357 # fatal error before hand, it's not really worth tracing
1358 code.put_trace_call(self.entry.name, self.pos)
1359 # ----- Fetch arguments
1360 if self.is_generator:
1361 resume_code = code.insertion_point()
1362 first_run_label = code.new_label('first_run')
1363 code.use_label(first_run_label)
1364 code.put_label(first_run_label)
1366 (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
1367 if not self.is_generator:
1368 self.generate_argument_parsing_code(env, code)
1369 # If an argument is assigned to in the body, we must
1370 # incref it to properly keep track of refcounts.
1371 for entry in lenv.arg_entries:
1372 if entry.type.is_pyobject:
1373 if entry.assignments and not entry.in_closure:
1374 code.put_var_incref(entry)
1375 # ----- Initialise local variables
1376 for entry in lenv.var_entries:
1377 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1378 code.put_init_var_to_py_none(entry)
1379 # ----- Initialise local buffer auxiliary variables
1380 for entry in lenv.var_entries + lenv.arg_entries:
1381 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1382 code.putln("%s.buf = NULL;" %
1383 entry.buffer_aux.buffer_info_var.cname)
1384 # ----- Check and convert arguments
1385 self.generate_argument_type_tests(code)
1386 # ----- Acquire buffer arguments
1387 for entry in lenv.arg_entries:
1388 if entry.type.is_buffer:
1389 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1391 # -------------------------
1392 # ----- Function body -----
1393 # -------------------------
1394 self.body.generate_execution_code(code)
1396 # ----- Default return value
1398 if self.return_type.is_pyobject:
1399 #if self.return_type.is_extension_type:
1400 # lhs = "(PyObject *)%s" % Naming.retval_cname
1402 lhs = Naming.retval_cname
1403 code.put_init_to_py_none(lhs, self.return_type)
1405 val = self.return_type.default_value
1407 code.putln("%s = %s;" % (Naming.retval_cname, val))
1408 # ----- Error cleanup
1409 if code.error_label in code.labels_used:
1410 code.put_goto(code.return_label)
1411 code.put_label(code.error_label)
1412 for cname, type in code.funcstate.all_managed_temps():
1413 code.put_xdecref(cname, type)
1415 # Clean up buffers -- this calls a Python function
1416 # so need to save and restore error state
1417 buffers_present = len(lenv.buffer_entries) > 0
1419 code.globalstate.use_utility_code(restore_exception_utility_code)
1420 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1421 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1422 for entry in lenv.buffer_entries:
1423 Buffer.put_release_buffer_code(code, entry)
1424 #code.putln("%s = 0;" % entry.cname)
1425 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1427 err_val = self.error_value()
1428 exc_check = self.caller_will_check_exceptions()
1429 if err_val is not None or exc_check:
1430 # TODO: Fix exception tracing (though currently unused by cProfile).
1431 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1432 # code.put_trace_exception()
1433 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1435 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1436 % self.entry.qualified_name, 0)
1438 '__Pyx_WriteUnraisable("%s");' %
1439 self.entry.qualified_name)
1440 env.use_utility_code(unraisable_exception_utility_code)
1441 env.use_utility_code(restore_exception_utility_code)
1442 default_retval = self.return_type.default_value
1443 if err_val is None and default_retval:
1444 err_val = default_retval
1445 if err_val is not None:
1446 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1448 if is_getbuffer_slot:
1449 self.getbuffer_error_cleanup(code)
1451 # If we are using the non-error cleanup section we should
1452 # jump past it if we have an error. The if-test below determine
1453 # whether this section is used.
1454 if buffers_present or is_getbuffer_slot:
1455 code.put_goto(code.return_from_error_cleanup_label)
1458 # ----- Non-error return cleanup
1459 code.put_label(code.return_label)
1460 for entry in lenv.buffer_entries:
1462 Buffer.put_release_buffer_code(code, entry)
1463 if is_getbuffer_slot:
1464 self.getbuffer_normal_cleanup(code)
1465 # ----- Return cleanup for both error and no-error return
1466 code.put_label(code.return_from_error_cleanup_label)
1467 if not Options.init_local_none:
1468 for entry in lenv.var_entries:
1469 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1470 entry.xdecref_cleanup = 1
1472 for entry in lenv.var_entries:
1473 if entry.type.is_pyobject:
1474 if entry.used and not entry.in_closure:
1475 code.put_var_decref(entry)
1476 elif entry.in_closure and self.needs_closure:
1477 code.put_giveref(entry.cname)
1478 # Decref any increfed args
1479 for entry in lenv.arg_entries:
1480 if entry.type.is_pyobject:
1481 if entry.in_closure:
1482 code.put_var_giveref(entry)
1483 elif entry.assignments:
1484 code.put_var_decref(entry)
1485 if self.needs_closure and not self.is_generator:
1486 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1487 if self.is_generator:
1488 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
1491 # This code is duplicated in ModuleNode.generate_module_init_func
1493 default_retval = self.return_type.default_value
1494 err_val = self.error_value()
1495 if err_val is None and default_retval:
1496 err_val = default_retval
1497 if self.return_type.is_pyobject:
1498 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1500 if self.entry.is_special and self.entry.name == "__hash__":
1501 # Returning -1 for __hash__ is supposed to signal an error
1502 # We do as Python instances and coerce -1 into -2.
1503 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1504 Naming.retval_cname, Naming.retval_cname))
1507 if self.return_type.is_pyobject:
1508 code.put_trace_return(Naming.retval_cname)
1510 code.put_trace_return("Py_None")
1512 code.put_finish_refcount_context()
1515 code.putln("#ifdef WITH_THREAD")
1516 code.putln("PyGILState_Release(_save);")
1517 code.putln("#endif")
1519 if not self.return_type.is_void:
1520 code.putln("return %s;" % Naming.retval_cname)
1524 if preprocessor_guard:
1525 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1526 # ----- Go back and insert temp variable declarations
1527 tempvardecl_code.put_temp_declarations(code.funcstate)
1528 # ----- Generator resume code
1529 if self.is_generator:
1530 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
1531 resume_code.putln("case 0: goto %s;" % first_run_label)
1532 for yield_expr in self.yields:
1533 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
1534 resume_code.putln("default: /* raise error here */");
1535 resume_code.putln("return NULL;");
1536 resume_code.putln("}");
1537 # ----- Python version
1538 code.exit_cfunc_scope()
1540 self.py_func.generate_function_definitions(env, code)
1541 self.generate_wrapper_functions(code)
1543 if self.is_generator:
1544 gotref_code.putln('/* Make refnanny happy */')
1545 self.temp_allocator.put_gotref(gotref_code)
1546 self.generator.generate_function_body(self.local_scope, code)
1548 def declare_argument(self, env, arg):
1549 if arg.type.is_void:
1550 error(arg.pos, "Invalid use of 'void'")
1551 elif not arg.type.is_complete() and not arg.type.is_array:
1553 "Argument type '%s' is incomplete" % arg.type)
1554 return env.declare_arg(arg.name, arg.type, arg.pos)
1556 def generate_arg_type_test(self, arg, code):
1557 # Generate type test for one argument.
1558 if arg.type.typeobj_is_available():
1559 code.globalstate.use_utility_code(arg_type_test_utility_code)
1560 typeptr_cname = arg.type.typeptr_cname
1561 arg_code = "((PyObject *)%s)" % arg.entry.cname
1563 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1568 arg.type.is_builtin_type,
1569 code.error_goto(arg.pos)))
1571 error(arg.pos, "Cannot test type of extern C class "
1572 "without type object name specification")
1574 def generate_arg_none_check(self, arg, code):
1575 # Generate None check for one argument.
1576 code.globalstate.use_utility_code(arg_type_test_utility_code)
1577 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1578 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1580 code.error_goto(arg.pos)))
1583 def generate_wrapper_functions(self, code):
1586 def generate_execution_code(self, code):
1587 # Evaluate and store argument default values
1588 for arg in self.args:
1589 default = arg.default
1591 if not default.is_literal:
1592 default.generate_evaluation_code(code)
1593 default.make_owned_reference(code)
1594 result = default.result_as(arg.type)
1597 arg.calculate_default_value_code(code),
1599 if arg.type.is_pyobject:
1600 code.put_giveref(default.result())
1601 default.generate_post_assignment_code(code)
1602 default.free_temps(code)
1603 # For Python class methods, create and store function object
1605 self.assmt.generate_execution_code(code)
1608 # Special code for the __getbuffer__ function
1610 def getbuffer_init(self, code):
1611 info = self.local_scope.arg_entries[1].cname
1612 # Python 3.0 betas have a bug in memoryview which makes it call
1613 # getbuffer with a NULL parameter. For now we work around this;
1614 # the following line should be removed when this bug is fixed.
1615 code.putln("if (%s == NULL) return 0;" % info)
1616 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1617 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1619 def getbuffer_error_cleanup(self, code):
1620 info = self.local_scope.arg_entries[1].cname
1621 code.put_gotref("%s->obj" % info)
1622 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1625 def getbuffer_normal_cleanup(self, code):
1626 info = self.local_scope.arg_entries[1].cname
1627 code.putln("if (%s->obj == Py_None) {" % info)
1628 code.put_gotref("Py_None")
1629 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1632 class CFuncDefNode(FuncDefNode):
1633 # C function definition.
1635 # modifiers ['inline']
1636 # visibility 'private' or 'public' or 'extern'
1637 # base_type CBaseTypeNode
1638 # declarator CDeclaratorNode
1641 # decorators [DecoratorNode] list of decorators
1643 # with_gil boolean Acquire GIL around body
1645 # py_func wrapper for calling from Python
1646 # overridable whether or not this is a cpdef function
1647 # inline_in_pxd whether this is an inline function in a pxd file
1649 child_attrs = ["base_type", "declarator", "body", "py_func"]
1651 inline_in_pxd = False
1653 directive_locals = {}
1655 def unqualified_name(self):
1656 return self.entry.name
1658 def analyse_declarations(self, env):
1659 self.directive_locals.update(env.directives['locals'])
1660 base_type = self.base_type.analyse(env)
1661 # The 2 here is because we need both function and argument names.
1662 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1663 if not type.is_cfunction:
1665 "Suite attached to non-function declaration")
1666 # Remember the actual type according to the function header
1667 # written here, because the type in the symbol table entry
1668 # may be different if we're overriding a C method inherited
1669 # from the base type of an extension type.
1671 type.is_overridable = self.overridable
1672 declarator = self.declarator
1673 while not hasattr(declarator, 'args'):
1674 declarator = declarator.base
1675 self.args = declarator.args
1676 for formal_arg, type_arg in zip(self.args, type.args):
1677 formal_arg.type = type_arg.type
1678 formal_arg.name = type_arg.name
1679 formal_arg.cname = type_arg.cname
1680 name = name_declarator.name
1681 cname = name_declarator.cname
1682 self.entry = env.declare_cfunction(
1683 name, type, self.pos,
1684 cname = cname, visibility = self.visibility,
1685 defining = self.body is not None,
1686 api = self.api, modifiers = self.modifiers)
1687 self.entry.inline_func_in_pxd = self.inline_in_pxd
1688 self.return_type = type.return_type
1690 if self.overridable and not env.is_module_scope:
1691 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1692 # An error will be produced in the cdef function
1693 self.overridable = False
1695 if self.overridable:
1697 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1698 self.py_func = DefNode(pos = self.pos,
1699 name = self.entry.name,
1702 starstar_arg = None,
1704 body = py_func_body,
1706 self.py_func.is_module_scope = env.is_module_scope
1707 self.py_func.analyse_declarations(env)
1708 self.entry.as_variable = self.py_func.entry
1709 # Reset scope entry the above cfunction
1710 env.entries[name] = self.entry
1711 if not env.is_module_scope or Options.lookup_module_cpdef:
1712 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1713 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1714 self.create_local_scope(env)
1716 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1718 args = self.type.args
1719 if omit_optional_args:
1720 args = args[:len(args) - self.type.optional_arg_count]
1721 arg_names = [arg.name for arg in args]
1723 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1725 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1726 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1727 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1728 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)
1729 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1731 def declare_arguments(self, env):
1732 for arg in self.type.args:
1734 error(arg.pos, "Missing argument name")
1735 self.declare_argument(env, arg)
1737 def need_gil_acquisition(self, lenv):
1738 return self.type.with_gil
1740 def nogil_check(self, env):
1742 with_gil = type.with_gil
1743 if type.nogil and not with_gil:
1744 if type.return_type.is_pyobject:
1746 "Function with Python return type cannot be declared nogil")
1747 for entry in self.local_scope.var_entries:
1748 if entry.type.is_pyobject:
1749 error(self.pos, "Function declared nogil has Python locals or temporaries")
1751 def analyse_expressions(self, env):
1752 self.local_scope.directives = env.directives
1753 if self.py_func is not None:
1754 # this will also analyse the default values
1755 self.py_func.analyse_expressions(env)
1757 self.analyse_default_values(env)
1758 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1760 def needs_assignment_synthesis(self, env, code=None):
1763 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1766 visibility = self.entry.visibility
1767 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1768 arg_decls.append(arg.declaration_code())
1769 if with_dispatch and self.overridable:
1770 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1771 if type.optional_arg_count and with_opt_args:
1772 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1773 if type.has_varargs:
1774 arg_decls.append("...")
1776 arg_decls = ["void"]
1778 cname = self.entry.func_cname
1779 entity = type.function_header_code(cname, ', '.join(arg_decls))
1780 if visibility == 'public':
1781 dll_linkage = "DL_EXPORT"
1784 header = self.return_type.declaration_code(entity,
1785 dll_linkage = dll_linkage)
1786 if visibility == 'extern':
1787 storage_class = "%s " % Naming.extern_c_macro
1788 elif visibility == 'public':
1791 storage_class = "static "
1792 if 'inline' in self.modifiers:
1793 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1794 code.putln("%s%s %s {" % (
1796 ' '.join(self.modifiers).upper(), # macro forms
1799 def generate_argument_declarations(self, env, code):
1800 for arg in self.args:
1802 result = arg.calculate_default_value_code(code)
1803 code.putln('%s = %s;' % (
1804 arg.type.declaration_code(arg.cname), result))
1806 def generate_keyword_list(self, code):
1809 def generate_argument_parsing_code(self, env, code):
1811 if self.type.optional_arg_count:
1812 code.putln('if (%s) {' % Naming.optional_args_cname)
1813 for arg in self.args:
1815 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1816 declarator = arg.declarator
1817 while not hasattr(declarator, 'name'):
1818 declarator = declarator.base
1819 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1821 for _ in range(self.type.optional_arg_count):
1825 def generate_argument_conversion_code(self, code):
1828 def generate_argument_type_tests(self, code):
1829 # Generate type tests for args whose type in a parent
1830 # class is a supertype of the declared type.
1831 for arg in self.type.args:
1832 if arg.needs_type_test:
1833 self.generate_arg_type_test(arg, code)
1834 elif arg.type.is_pyobject and not arg.accept_none:
1835 self.generate_arg_none_check(arg, code)
1837 def error_value(self):
1838 if self.return_type.is_pyobject:
1842 return self.entry.type.exception_value
1844 def caller_will_check_exceptions(self):
1845 return self.entry.type.exception_check
1847 def generate_wrapper_functions(self, code):
1848 # If the C signature of a function has changed, we need to generate
1849 # wrappers to put in the slots here.
1852 func_type = entry.type
1853 while entry.prev_entry is not None:
1855 entry = entry.prev_entry
1856 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1858 self.generate_function_header(code,
1860 with_dispatch = entry.type.is_overridable,
1861 with_opt_args = entry.type.optional_arg_count,
1862 cname = entry.func_cname)
1863 if not self.return_type.is_void:
1865 args = self.type.args
1866 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1867 if entry.type.is_overridable:
1868 arglist.append(Naming.skip_dispatch_cname)
1869 elif func_type.is_overridable:
1871 if entry.type.optional_arg_count:
1872 arglist.append(Naming.optional_args_cname)
1873 elif func_type.optional_arg_count:
1874 arglist.append('NULL')
1875 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1879 class PyArgDeclNode(Node):
1880 # Argument which must be a Python object (used
1881 # for * and ** arguments).
1884 # entry Symtab.Entry
1885 # annotation ExprNode or None Py3 argument annotation
1888 def generate_function_definitions(self, env, code):
1889 self.entry.generate_function_definitions(env, code)
1891 class DecoratorNode(Node):
1894 # decorator NameNode or CallNode or AttributeNode
1895 child_attrs = ['decorator']
1898 class GeneratorWrapperNode(object):
1900 def __init__(self, def_node, func_cname=None, body_cname=None, header=None):
1901 self.def_node = def_node
1902 self.func_cname = func_cname
1903 self.body_cname = body_cname
1904 self.header = header
1906 def generate_function_body(self, env, code):
1907 cenv = env.outer_scope # XXX: correct?
1908 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1909 cenv = cenv.outer_scope
1910 lenv = self.def_node.local_scope
1911 code.enter_cfunc_scope()
1913 code.putln('%s {' % self.header)
1914 self.def_node.generate_keyword_list(code)
1915 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1917 code.put_setup_refcount_context(self.def_node.entry.name)
1918 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1919 Naming.cur_scope_cname,
1920 lenv.scope_class.type.declaration_code(''),
1921 lenv.scope_class.type.typeptr_cname,
1922 lenv.scope_class.type.typeptr_cname,
1923 Naming.empty_tuple))
1924 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1925 code.put_finish_refcount_context()
1926 code.putln("return NULL;");
1928 code.put_gotref(Naming.cur_scope_cname)
1930 if self.def_node.needs_outer_scope:
1931 outer_scope_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.outer_scope_cname)
1932 code.putln("%s = (%s)%s;" % (
1934 cenv.scope_class.type.declaration_code(''),
1936 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1938 self.def_node.generate_argument_parsing_code(env, code)
1940 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
1942 code.putln('%s.resume_label = 0;' % generator_cname)
1943 code.putln('%s.body = %s;' % (generator_cname, self.body_cname))
1944 for entry in lenv.scope_class.type.scope.entries.values():
1945 if entry.type.is_pyobject:
1946 code.put_xgiveref('%s->%s' % (Naming.cur_scope_cname, entry.cname))
1947 code.put_giveref(Naming.cur_scope_cname)
1948 code.put_finish_refcount_context()
1949 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
1951 code.exit_cfunc_scope()
1953 class DefNode(FuncDefNode):
1954 # A Python function definition.
1956 # name string the Python name of the function
1957 # lambda_name string the internal name of a lambda 'function'
1958 # decorators [DecoratorNode] list of decorators
1959 # args [CArgDeclNode] formal arguments
1960 # star_arg PyArgDeclNode or None * argument
1961 # starstar_arg PyArgDeclNode or None ** argument
1962 # doc EncodedString or None
1964 # return_type_annotation
1965 # ExprNode or None the Py3 return type annotation
1967 # The following subnode is constructed internally
1968 # when the def statement is inside a Python class definition.
1970 # assmt AssignmentNode Function construction/assignment
1972 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1977 num_required_kw_args = 0
1978 reqd_kw_flags_cname = "0"
1981 return_type_annotation = None
1986 def __init__(self, pos, **kwds):
1987 FuncDefNode.__init__(self, pos, **kwds)
1989 for arg in self.args:
1996 self.num_kwonly_args = k
1997 self.num_required_kw_args = rk
1998 self.num_required_args = r
2000 def as_cfunction(self, cfunc=None, scope=None):
2002 error(self.star_arg.pos, "cdef function cannot have star argument")
2003 if self.starstar_arg:
2004 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
2007 for formal_arg in self.args:
2008 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
2009 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
2011 type = py_object_type,
2012 pos = formal_arg.pos))
2013 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
2015 has_varargs = False,
2016 exception_value = None,
2017 exception_check = False,
2020 is_overridable = True)
2021 cfunc = CVarDefNode(self.pos, type=cfunc_type)
2025 cfunc_type = cfunc.type
2026 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2027 error(self.pos, "wrong number of arguments")
2028 error(cfunc.pos, "previous declaration here")
2029 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2030 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2031 is_self_arg = (i == 0 and scope.is_c_class_scope))
2032 if type is None or type is PyrexTypes.py_object_type:
2033 formal_arg.type = type_arg.type
2034 formal_arg.name_declarator = name_declarator
2036 if cfunc_type.exception_value is None:
2037 exception_value = None
2039 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2040 declarator = CFuncDeclaratorNode(self.pos,
2041 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2043 has_varargs = False,
2044 exception_check = cfunc_type.exception_check,
2045 exception_value = exception_value,
2046 with_gil = cfunc_type.with_gil,
2047 nogil = cfunc_type.nogil)
2048 return CFuncDefNode(self.pos,
2050 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2051 declarator = declarator,
2054 overridable = cfunc_type.is_overridable,
2056 with_gil = cfunc_type.with_gil,
2057 nogil = cfunc_type.nogil,
2058 visibility = 'private',
2060 directive_locals = getattr(cfunc, 'directive_locals', {}))
2062 def analyse_declarations(self, env):
2063 self.is_classmethod = self.is_staticmethod = False
2065 for decorator in self.decorators:
2066 func = decorator.decorator
2068 self.is_classmethod |= func.name == 'classmethod'
2069 self.is_staticmethod |= func.name == 'staticmethod'
2071 if self.is_classmethod and env.lookup_here('classmethod'):
2072 # classmethod() was overridden - not much we can do here ...
2073 self.is_classmethod = False
2074 if self.is_staticmethod and env.lookup_here('staticmethod'):
2075 # staticmethod() was overridden - not much we can do here ...
2076 self.is_staticmethod = False
2078 if self.name == '__new__':
2079 self.is_staticmethod = 1
2081 self.analyse_argument_types(env)
2082 if self.name == '<lambda>':
2083 self.declare_lambda_function(env)
2085 self.declare_pyfunction(env)
2086 self.analyse_signature(env)
2087 self.return_type = self.entry.signature.return_type()
2088 self.create_local_scope(env)
2090 def analyse_argument_types(self, env):
2091 directive_locals = self.directive_locals = env.directives['locals']
2092 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2093 for arg in self.args:
2094 if hasattr(arg, 'name'):
2096 name_declarator = None
2098 base_type = arg.base_type.analyse(env)
2099 name_declarator, type = \
2100 arg.declarator.analyse(base_type, env)
2101 arg.name = name_declarator.name
2102 if arg.name in directive_locals:
2103 type_node = directive_locals[arg.name]
2104 other_type = type_node.analyse_as_type(env)
2105 if other_type is None:
2106 error(type_node.pos, "Not a type")
2107 elif (type is not PyrexTypes.py_object_type
2108 and not type.same_as(other_type)):
2109 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2110 error(type_node.pos, "Previous declaration here")
2113 if name_declarator and name_declarator.cname:
2115 "Python function argument cannot have C name specification")
2116 arg.type = type.as_argument_type()
2118 arg.needs_conversion = 0
2119 arg.needs_type_test = 0
2121 if arg.type.is_pyobject:
2123 arg.accept_none = True
2125 arg.accept_none = False
2126 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2127 if arg.default and arg.default.constant_result is None:
2128 # special case: def func(MyType obj = None)
2129 arg.accept_none = True
2131 # default depends on compiler directive
2132 arg.accept_none = allow_none_for_extension_args
2134 # probably just a plain 'object'
2135 arg.accept_none = True
2137 arg.accept_none = True # won't be used, but must be there
2139 error(arg.pos, "Only Python type arguments can have 'not None'")
2141 error(arg.pos, "Only Python type arguments can have 'or None'")
2143 def analyse_signature(self, env):
2144 if self.entry.is_special:
2145 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2146 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2147 # Use the simpler calling signature for zero- and one-argument functions.
2148 if self.entry.signature is TypeSlots.pyfunction_signature:
2149 if len(self.args) == 0:
2150 self.entry.signature = TypeSlots.pyfunction_noargs
2151 elif len(self.args) == 1:
2152 if self.args[0].default is None and not self.args[0].kw_only:
2153 self.entry.signature = TypeSlots.pyfunction_onearg
2154 elif self.entry.signature is TypeSlots.pymethod_signature:
2155 if len(self.args) == 1:
2156 self.entry.signature = TypeSlots.unaryfunc
2157 elif len(self.args) == 2:
2158 if self.args[1].default is None and not self.args[1].kw_only:
2159 self.entry.signature = TypeSlots.ibinaryfunc
2161 sig = self.entry.signature
2162 nfixed = sig.num_fixed_args()
2163 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2164 and len(self.args) == 0 and self.star_arg:
2165 # this is the only case where a diverging number of
2166 # arguments is not an error - when we have no explicit
2167 # 'self' parameter as in method(*args)
2168 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2169 self.self_in_stararg = 1
2172 for i in range(min(nfixed, len(self.args))):
2175 if sig.is_self_arg(i) and not self.is_staticmethod:
2176 if self.is_classmethod:
2178 arg.hdr_type = arg.type = Builtin.type_type
2181 arg.hdr_type = arg.type = env.parent_type
2182 arg.needs_conversion = 0
2184 arg.hdr_type = sig.fixed_arg_type(i)
2185 if not arg.type.same_as(arg.hdr_type):
2186 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2187 arg.needs_type_test = 1
2189 arg.needs_conversion = 1
2190 if arg.needs_conversion:
2191 arg.hdr_cname = Naming.arg_prefix + arg.name
2193 arg.hdr_cname = Naming.var_prefix + arg.name
2195 if nfixed > len(self.args):
2196 self.bad_signature()
2198 elif nfixed < len(self.args):
2199 if not sig.has_generic_args:
2200 self.bad_signature()
2201 for arg in self.args:
2202 if arg.is_generic and \
2203 (arg.type.is_extension_type or arg.type.is_builtin_type):
2204 arg.needs_type_test = 1
2206 def bad_signature(self):
2207 sig = self.entry.signature
2208 expected_str = "%d" % sig.num_fixed_args()
2209 if sig.has_generic_args:
2210 expected_str = expected_str + " or more"
2212 if name.startswith("__") and name.endswith("__"):
2213 desc = "Special method"
2217 "%s %s has wrong number of arguments "
2218 "(%d declared, %s expected)" % (
2219 desc, self.name, len(self.args), expected_str))
2221 def signature_has_nongeneric_args(self):
2222 argcount = len(self.args)
2223 if argcount == 0 or (
2224 argcount == 1 and (self.args[0].is_self_arg or
2225 self.args[0].is_type_arg)):
2229 def signature_has_generic_args(self):
2230 return self.entry.signature.has_generic_args
2232 def declare_pyfunction(self, env):
2233 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2235 entry = env.lookup_here(name)
2236 if entry and entry.type.is_cfunction and not self.is_wrapper:
2237 warning(self.pos, "Overriding cdef method with def method.", 5)
2238 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2240 prefix = env.next_id(env.scope_prefix)
2242 entry.func_cname = \
2243 Naming.pyfunc_prefix + prefix + name
2244 entry.pymethdef_cname = \
2245 Naming.pymethdef_prefix + prefix + name
2247 if self.is_generator:
2248 self.generator_body_cname = Naming.genbody_prefix + env.next_id(env.scope_prefix) + name
2250 if Options.docstrings:
2251 entry.doc = embed_position(self.pos, self.doc)
2253 Naming.funcdoc_prefix + prefix + name
2254 if entry.is_special:
2255 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2256 entry.wrapperbase_cname = None
2258 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2262 def declare_lambda_function(self, env):
2264 prefix = env.scope_prefix
2266 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2267 entry = env.declare_lambda_function(func_cname, self.pos)
2268 entry.pymethdef_cname = \
2269 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2270 entry.qualified_name = env.qualify_name(self.lambda_name)
2274 def declare_arguments(self, env):
2275 for arg in self.args:
2277 error(arg.pos, "Missing argument name")
2279 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2280 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2281 if arg.needs_conversion:
2282 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2283 if arg.type.is_pyobject:
2284 arg.entry.init = "0"
2285 arg.entry.init_to_none = 0
2287 arg.entry = self.declare_argument(env, arg)
2289 arg.entry.is_self_arg = arg.is_self_arg
2291 if arg.is_self_arg or arg.is_type_arg or \
2292 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2293 arg.entry.is_declared_generic = 1
2294 self.declare_python_arg(env, self.star_arg)
2295 self.declare_python_arg(env, self.starstar_arg)
2297 def declare_python_arg(self, env, arg):
2299 if env.directives['infer_types'] != False:
2300 type = PyrexTypes.unspecified_type
2302 type = py_object_type
2303 entry = env.declare_var(arg.name, type, arg.pos)
2306 entry.init_to_none = 0
2307 entry.xdecref_cleanup = 1
2309 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2311 def analyse_expressions(self, env):
2312 self.local_scope.directives = env.directives
2313 self.analyse_default_values(env)
2314 if self.needs_assignment_synthesis(env):
2315 # Shouldn't we be doing this at the module level too?
2316 self.synthesize_assignment_node(env)
2318 def needs_assignment_synthesis(self, env, code=None):
2319 # Should enable for module level as well, that will require more testing...
2320 if self.entry.is_anonymous:
2322 if env.is_module_scope:
2324 return env.directives['binding']
2326 return code.globalstate.directives['binding']
2327 return env.is_py_class_scope or env.is_closure_scope
2329 def synthesize_assignment_node(self, env):
2332 while genv.is_py_class_scope or genv.is_c_class_scope:
2333 genv = genv.outer_scope
2335 if genv.is_closure_scope:
2336 rhs = ExprNodes.InnerFunctionNode(
2337 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2339 rhs = ExprNodes.PyCFunctionNode(
2340 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2342 if env.is_py_class_scope:
2343 if not self.is_staticmethod and not self.is_classmethod:
2346 self.assmt = SingleAssignmentNode(self.pos,
2347 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2349 self.assmt.analyse_declarations(env)
2350 self.assmt.analyse_expressions(env)
2352 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2354 sig = self.entry.signature
2355 if sig.has_dummy_arg or self.self_in_stararg:
2356 arg_code_list.append(
2357 "PyObject *%s" % Naming.self_cname)
2358 for arg in self.args:
2359 if not arg.is_generic:
2360 if arg.is_self_arg or arg.is_type_arg:
2361 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2363 arg_code_list.append(
2364 arg.hdr_type.declaration_code(arg.hdr_cname))
2365 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2366 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2367 if sig.has_generic_args:
2368 arg_code_list.append(
2369 "PyObject *%s, PyObject *%s"
2370 % (Naming.args_cname, Naming.kwds_cname))
2371 arg_code = ", ".join(arg_code_list)
2372 dc = self.return_type.declaration_code(self.entry.func_cname)
2373 mf = " ".join(self.modifiers).upper()
2375 header = "static %s%s(%s)" % (mf, dc, arg_code)
2376 code.putln("%s; /*proto*/" % header)
2379 if (Options.docstrings and self.entry.doc and
2380 not self.entry.scope.is_property_scope and
2381 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2382 docstr = self.entry.doc
2383 if docstr.is_unicode:
2384 docstr = docstr.utf8encode()
2386 'static char %s[] = "%s";' % (
2387 self.entry.doc_cname,
2388 split_string_literal(escape_byte_string(docstr))))
2389 if self.entry.is_special:
2391 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2394 "static PyMethodDef %s = " %
2395 self.entry.pymethdef_cname)
2396 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2397 if self.is_generator:
2398 code.putln("static PyObject *%s(PyObject *%s, PyObject *%s) /* generator body */\n{" %
2399 (self.generator_body_cname, Naming.self_cname, Naming.sent_value_cname))
2400 self.generator = GeneratorWrapperNode(self,
2401 func_cname=self.entry.func_cname,
2402 body_cname=self.generator_body_cname,
2405 code.putln("%s {" % header)
2407 def generate_argument_declarations(self, env, code):
2408 for arg in self.args:
2409 if arg.is_generic: # or arg.needs_conversion:
2410 if arg.needs_conversion:
2411 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2412 elif not arg.entry.in_closure:
2413 code.put_var_declaration(arg.entry)
2415 def generate_keyword_list(self, code):
2416 if self.signature_has_generic_args() and \
2417 self.signature_has_nongeneric_args():
2419 "static PyObject **%s[] = {" %
2420 Naming.pykwdlist_cname)
2421 for arg in self.args:
2423 pystring_cname = code.intern_identifier(arg.name)
2424 code.put('&%s,' % pystring_cname)
2427 def generate_argument_parsing_code(self, env, code):
2428 # Generate PyArg_ParseTuple call for generic
2429 # arguments, if any.
2430 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2431 # get rid of unused argument warning
2432 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2434 old_error_label = code.new_error_label()
2435 our_error_label = code.error_label
2436 end_label = code.new_label("argument_unpacking_done")
2438 has_kwonly_args = self.num_kwonly_args > 0
2439 has_star_or_kw_args = self.star_arg is not None \
2440 or self.starstar_arg is not None or has_kwonly_args
2442 for arg in self.args:
2443 if not arg.type.is_pyobject:
2444 done = arg.type.create_from_py_utility_code(env)
2445 if not done: pass # will fail later
2447 if not self.signature_has_generic_args():
2448 if has_star_or_kw_args:
2449 error(self.pos, "This method cannot have * or keyword arguments")
2450 self.generate_argument_conversion_code(code)
2452 elif not self.signature_has_nongeneric_args():
2453 # func(*args) or func(**kw) or func(*args, **kw)
2454 self.generate_stararg_copy_code(code)
2457 positional_args = []
2459 for arg in self.args:
2460 arg_entry = arg.entry
2463 if not arg.is_self_arg and not arg.is_type_arg:
2465 kw_only_args.append(arg)
2467 positional_args.append(arg)
2469 kw_only_args.append(arg)
2470 elif not arg.is_self_arg and not arg.is_type_arg:
2471 positional_args.append(arg)
2473 self.generate_tuple_and_keyword_parsing_code(
2474 positional_args, kw_only_args, end_label, code)
2476 code.error_label = old_error_label
2477 if code.label_used(our_error_label):
2478 if not code.label_used(end_label):
2479 code.put_goto(end_label)
2480 code.put_label(our_error_label)
2481 if has_star_or_kw_args:
2482 self.generate_arg_decref(self.star_arg, code)
2483 if self.starstar_arg:
2484 if self.starstar_arg.entry.xdecref_cleanup:
2485 code.put_var_xdecref(self.starstar_arg.entry)
2487 code.put_var_decref(self.starstar_arg.entry)
2488 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2489 # The arguments are put into the closure one after the
2490 # other, so when type errors are found, all references in
2491 # the closure instance must be properly ref-counted to
2492 # facilitate generic closure instance deallocation. In
2493 # the case of an argument type error, it's best to just
2494 # DECREF+clear the already handled references, as this
2495 # frees their references as early as possible.
2496 for arg in self.args:
2497 if arg.type.is_pyobject and arg.entry.in_closure:
2498 code.put_var_xdecref_clear(arg.entry)
2499 if self.needs_closure:
2500 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2501 code.put_finish_refcount_context()
2502 code.putln("return %s;" % self.error_value())
2503 if code.label_used(end_label):
2504 code.put_label(end_label)
2506 def generate_arg_assignment(self, arg, item, code):
2507 if arg.type.is_pyobject:
2509 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2511 code.putln("%s = %s;" % (entry.cname, item))
2512 if entry.in_closure:
2513 code.put_var_incref(entry)
2515 func = arg.type.from_py_function
2517 code.putln("%s = %s(%s); %s" % (
2521 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2523 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2525 def generate_arg_xdecref(self, arg, code):
2527 code.put_var_xdecref(arg.entry)
2529 def generate_arg_decref(self, arg, code):
2531 code.put_var_decref(arg.entry)
2533 def generate_stararg_copy_code(self, code):
2534 if not self.star_arg:
2535 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2536 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2538 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2539 self.name, Naming.args_cname, self.error_value()))
2542 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2544 if self.starstar_arg:
2546 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2548 kwarg_check = "%s" % Naming.kwds_cname
2550 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2551 Naming.kwds_cname, Naming.kwds_cname)
2553 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2554 kwarg_check, Naming.kwds_cname, self.name,
2555 bool(self.starstar_arg), self.error_value()))
2557 if self.starstar_arg:
2558 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2559 self.starstar_arg.entry.cname,
2562 code.putln("if (unlikely(!%s)) return %s;" % (
2563 self.starstar_arg.entry.cname, self.error_value()))
2564 self.starstar_arg.entry.xdecref_cleanup = 0
2565 code.put_gotref(self.starstar_arg.entry.cname)
2567 if self.self_in_stararg:
2568 # need to create a new tuple with 'self' inserted as first item
2569 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2570 self.star_arg.entry.cname,
2572 self.star_arg.entry.cname))
2573 if self.starstar_arg:
2575 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2576 code.putln("return %s;" % self.error_value())
2579 code.putln("return %s;" % self.error_value())
2580 code.put_gotref(self.star_arg.entry.cname)
2581 code.put_incref(Naming.self_cname, py_object_type)
2582 code.put_giveref(Naming.self_cname)
2583 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2584 self.star_arg.entry.cname, Naming.self_cname))
2585 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2586 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2587 temp, temp, Naming.args_cname, temp))
2588 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2589 Naming.args_cname, temp))
2590 code.put_incref("item", py_object_type)
2591 code.put_giveref("item")
2592 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2593 self.star_arg.entry.cname, temp))
2595 code.funcstate.release_temp(temp)
2596 self.star_arg.entry.xdecref_cleanup = 0
2598 code.put_incref(Naming.args_cname, py_object_type)
2599 code.putln("%s = %s;" % (
2600 self.star_arg.entry.cname,
2602 self.star_arg.entry.xdecref_cleanup = 0
2604 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2605 kw_only_args, success_label, code):
2606 argtuple_error_label = code.new_label("argtuple_error")
2608 min_positional_args = self.num_required_args - self.num_required_kw_args
2609 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2610 min_positional_args -= 1
2611 max_positional_args = len(positional_args)
2612 has_fixed_positional_count = not self.star_arg and \
2613 min_positional_args == max_positional_args
2615 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2616 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2617 if self.num_required_kw_args:
2618 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2620 if self.starstar_arg or self.star_arg:
2621 self.generate_stararg_init_code(max_positional_args, code)
2623 # --- optimised code when we receive keyword arguments
2624 if self.num_required_kw_args:
2625 likely_hint = "likely"
2627 likely_hint = "unlikely"
2628 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2629 self.generate_keyword_unpacking_code(
2630 min_positional_args, max_positional_args,
2631 has_fixed_positional_count,
2632 positional_args, kw_only_args, argtuple_error_label, code)
2634 # --- optimised code when we do not receive any keyword arguments
2635 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2636 # Python raises arg tuple related errors first, so we must
2637 # check the length here
2638 if min_positional_args == max_positional_args and not self.star_arg:
2642 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2643 Naming.args_cname, compare, min_positional_args))
2644 code.put_goto(argtuple_error_label)
2646 if self.num_required_kw_args:
2647 # pure error case: keywords required but not passed
2648 if max_positional_args > min_positional_args and not self.star_arg:
2649 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2650 Naming.args_cname, max_positional_args))
2651 code.put_goto(argtuple_error_label)
2652 code.putln('} else {')
2653 for i, arg in enumerate(kw_only_args):
2655 pystring_cname = code.intern_identifier(arg.name)
2656 # required keyword-only argument missing
2657 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2660 code.putln(code.error_goto(self.pos))
2663 elif min_positional_args == max_positional_args:
2664 # parse the exact number of positional arguments from the
2666 code.putln('} else {')
2667 for i, arg in enumerate(positional_args):
2668 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2669 self.generate_arg_assignment(arg, item, code)
2670 self.generate_arg_default_assignments(code)
2673 # parse the positional arguments from the variable length
2675 code.putln('} else {')
2676 self.generate_arg_default_assignments(code)
2677 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2679 code.putln('default:')
2680 reversed_args = list(enumerate(positional_args))[::-1]
2681 for i, arg in reversed_args:
2682 if i >= min_positional_args-1:
2683 if min_positional_args > 1:
2684 code.putln('case %2d:' % (i+1)) # pure code beautification
2686 code.put('case %2d: ' % (i+1))
2687 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2688 self.generate_arg_assignment(arg, item, code)
2689 if min_positional_args == 0:
2690 code.put('case 0: ')
2691 code.putln('break;')
2693 if min_positional_args:
2694 for i in range(min_positional_args-1, -1, -1):
2695 code.putln('case %2d:' % i)
2696 code.put_goto(argtuple_error_label)
2698 code.put('default: ')
2699 code.put_goto(argtuple_error_label)
2704 if code.label_used(argtuple_error_label):
2705 code.put_goto(success_label)
2706 code.put_label(argtuple_error_label)
2707 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2708 self.name, has_fixed_positional_count,
2709 min_positional_args, max_positional_args,
2711 code.putln(code.error_goto(self.pos))
2713 def generate_arg_default_assignments(self, code):
2714 for arg in self.args:
2715 if arg.is_generic and arg.default:
2719 arg.calculate_default_value_code(code)))
2721 def generate_stararg_init_code(self, max_positional_args, code):
2722 if self.starstar_arg:
2723 self.starstar_arg.entry.xdecref_cleanup = 0
2724 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2725 self.starstar_arg.entry.cname,
2726 self.starstar_arg.entry.cname,
2727 self.error_value()))
2728 code.put_gotref(self.starstar_arg.entry.cname)
2730 self.star_arg.entry.xdecref_cleanup = 0
2731 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2733 max_positional_args))
2734 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2735 self.star_arg.entry.cname, Naming.args_cname,
2736 max_positional_args, Naming.args_cname))
2737 code.put_gotref(self.star_arg.entry.cname)
2738 if self.starstar_arg:
2740 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2741 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2742 code.putln('return %s;' % self.error_value())
2745 code.putln("if (unlikely(!%s)) return %s;" % (
2746 self.star_arg.entry.cname, self.error_value()))
2747 code.putln('} else {')
2748 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2749 code.put_incref(Naming.empty_tuple, py_object_type)
2752 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2753 has_fixed_positional_count, positional_args,
2754 kw_only_args, argtuple_error_label, code):
2755 all_args = tuple(positional_args) + tuple(kw_only_args)
2756 max_args = len(all_args)
2758 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2760 # the 'values' array collects borrowed references to arguments
2761 # before doing any type coercion etc.
2762 code.putln("PyObject* values[%d] = {%s};" % (
2763 max_args, ','.join('0'*max_args)))
2765 # assign borrowed Python default values to the values array,
2766 # so that they can be overwritten by received arguments below
2767 for i, arg in enumerate(all_args):
2768 if arg.default and arg.type.is_pyobject:
2769 default_value = arg.calculate_default_value_code(code)
2770 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2772 # parse the args tuple and check that it's not too long
2773 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2775 code.putln('default:')
2776 for i in range(max_positional_args-1, -1, -1):
2777 code.put('case %2d: ' % (i+1))
2778 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2779 i, Naming.args_cname, i))
2780 code.putln('case 0: break;')
2781 if not self.star_arg:
2782 code.put('default: ') # more arguments than allowed
2783 code.put_goto(argtuple_error_label)
2786 # now fill up the positional/required arguments with values
2788 if self.num_required_args or max_positional_args > 0:
2789 last_required_arg = -1
2790 for i, arg in enumerate(all_args):
2792 last_required_arg = i
2793 if last_required_arg < max_positional_args:
2794 last_required_arg = max_positional_args-1
2795 num_required_args = self.num_required_args
2796 if max_positional_args > 0:
2797 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2798 for i, arg in enumerate(all_args[:last_required_arg+1]):
2799 if max_positional_args > 0 and i <= max_positional_args:
2800 if self.star_arg and i == max_positional_args:
2801 code.putln('default:')
2803 code.putln('case %2d:' % i)
2804 pystring_cname = code.intern_identifier(arg.name)
2807 # handled separately below
2809 code.putln('if (kw_args > 0) {')
2810 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2811 Naming.kwds_cname, pystring_cname))
2812 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2815 num_required_args -= 1
2816 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2817 i, Naming.kwds_cname, pystring_cname))
2818 code.putln('if (likely(values[%d])) kw_args--;' % i);
2819 if i < min_positional_args:
2821 # special case: we know arg 0 is missing
2823 code.put_goto(argtuple_error_label)
2825 # print the correct number of values (args or
2826 # kwargs) that were passed into positional
2827 # arguments up to this point
2828 code.putln('else {')
2829 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2830 self.name, has_fixed_positional_count,
2831 min_positional_args, max_positional_args, i))
2832 code.putln(code.error_goto(self.pos))
2835 code.putln('else {')
2836 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2837 self.name, pystring_cname))
2838 code.putln(code.error_goto(self.pos))
2840 if max_positional_args > 0:
2843 if kw_only_args and not self.starstar_arg:
2844 # unpack optional keyword-only arguments
2845 # checking for interned strings in a dict is faster than iterating
2846 # but it's too likely that we must iterate if we expect **kwargs
2848 for i, arg in enumerate(all_args[max_positional_args:]):
2849 if not arg.kw_only or not arg.default:
2851 optional_args.append((i+max_positional_args, arg))
2853 # this mimics an unrolled loop so that we can "break" out of it
2854 code.putln('while (kw_args > 0) {')
2855 code.putln('PyObject* value;')
2856 for i, arg in optional_args:
2857 pystring_cname = code.intern_identifier(arg.name)
2859 'value = PyDict_GetItem(%s, %s);' % (
2860 Naming.kwds_cname, pystring_cname))
2862 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2863 code.putln('break;')
2866 code.putln('if (unlikely(kw_args > 0)) {')
2867 # non-positional/-required kw args left in dict: default args,
2868 # kw-only args, **kwargs or error
2870 # This is sort of a catch-all: except for checking required
2871 # arguments, this will always do the right thing for unpacking
2872 # keyword arguments, so that we can concentrate on optimising
2873 # common cases above.
2874 if max_positional_args == 0:
2877 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2878 Naming.args_cname, max_positional_args,
2879 Naming.args_cname, max_positional_args))
2880 pos_arg_count = "used_pos_args"
2882 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2883 code.globalstate.use_utility_code(parse_keywords_utility_code)
2885 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2887 Naming.pykwdlist_cname,
2888 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2891 code.putln(code.error_goto(self.pos))
2894 # convert arg values to their final type and assign them
2895 for i, arg in enumerate(all_args):
2896 if arg.default and not arg.type.is_pyobject:
2897 code.putln("if (values[%d]) {" % i)
2898 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2899 if arg.default and not arg.type.is_pyobject:
2900 code.putln('} else {')
2904 arg.calculate_default_value_code(code)))
2907 def generate_argument_conversion_code(self, code):
2908 # Generate code to convert arguments from signature type to
2909 # declared type, if needed. Also copies signature arguments
2910 # into closure fields.
2911 for arg in self.args:
2912 if arg.needs_conversion:
2913 self.generate_arg_conversion(arg, code)
2914 elif arg.entry.in_closure:
2915 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2916 if arg.type.is_pyobject:
2917 code.put_var_incref(arg.entry)
2919 def generate_arg_conversion(self, arg, code):
2920 # Generate conversion code for one argument.
2921 old_type = arg.hdr_type
2923 if old_type.is_pyobject:
2925 code.putln("if (%s) {" % arg.hdr_cname)
2927 code.putln("assert(%s); {" % arg.hdr_cname)
2928 self.generate_arg_conversion_from_pyobject(arg, code)
2930 elif new_type.is_pyobject:
2931 self.generate_arg_conversion_to_pyobject(arg, code)
2933 if new_type.assignable_from(old_type):
2935 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2938 "Cannot convert 1 argument from '%s' to '%s'" %
2939 (old_type, new_type))
2941 def generate_arg_conversion_from_pyobject(self, arg, code):
2943 func = new_type.from_py_function
2944 # copied from CoerceFromPyTypeNode
2946 lhs = arg.entry.cname
2947 rhs = "%s(%s)" % (func, arg.hdr_cname)
2948 if new_type.is_enum:
2949 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2950 code.putln("%s = %s; %s" % (
2953 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2956 "Cannot convert Python object argument to type '%s'"
2959 def generate_arg_conversion_to_pyobject(self, arg, code):
2960 old_type = arg.hdr_type
2961 func = old_type.to_py_function
2963 code.putln("%s = %s(%s); %s" % (
2967 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2968 code.put_var_gotref(arg.entry)
2971 "Cannot convert argument of type '%s' to Python object"
2974 def generate_argument_type_tests(self, code):
2975 # Generate type tests for args whose signature
2976 # type is PyObject * and whose declared type is
2977 # a subtype thereof.
2978 for arg in self.args:
2979 if arg.needs_type_test:
2980 self.generate_arg_type_test(arg, code)
2981 elif not arg.accept_none and arg.type.is_pyobject:
2982 self.generate_arg_none_check(arg, code)
2984 def error_value(self):
2985 return self.entry.signature.error_value
2987 def caller_will_check_exceptions(self):
2990 class OverrideCheckNode(StatNode):
2991 # A Node for dispatching to the def method if it
3000 child_attrs = ['body']
3004 def analyse_expressions(self, env):
3005 self.args = env.arg_entries
3006 if self.py_func.is_module_scope:
3011 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3012 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3013 call_node = ExprNodes.SimpleCallNode(self.pos,
3014 function=self.func_node,
3015 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3016 self.body = ReturnStatNode(self.pos, value=call_node)
3017 self.body.analyse_expressions(env)
3019 def generate_execution_code(self, code):
3020 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3021 # Check to see if we are an extension type
3022 if self.py_func.is_module_scope:
3023 self_arg = "((PyObject *)%s)" % Naming.module_cname
3025 self_arg = "((PyObject *)%s)" % self.args[0].cname
3026 code.putln("/* Check if called by wrapper */")
3027 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3028 code.putln("/* Check if overriden in Python */")
3029 if self.py_func.is_module_scope:
3030 code.putln("else {")
3032 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3033 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3034 self.func_node.set_cname(func_node_temp)
3035 # need to get attribute manually--scope would return cdef method
3036 err = code.error_goto_if_null(func_node_temp, self.pos)
3037 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3038 func_node_temp, self_arg, interned_attr_cname, err))
3039 code.put_gotref(func_node_temp)
3040 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3041 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3042 func_node_temp, self.py_func.entry.func_cname)
3043 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3044 self.body.generate_execution_code(code)
3046 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3047 code.funcstate.release_temp(func_node_temp)
3050 class ClassDefNode(StatNode, BlockNode):
3053 class PyClassDefNode(ClassDefNode):
3054 # A Python class definition.
3056 # name EncodedString Name of the class
3057 # doc string or None
3058 # body StatNode Attribute definition code
3059 # entry Symtab.Entry
3060 # scope PyClassScope
3061 # decorators [DecoratorNode] list of decorators or None
3063 # The following subnodes are constructed internally:
3065 # dict DictNode Class dictionary or Py3 namespace
3066 # classobj ClassNode Class object
3067 # target NameNode Variable to assign class object to
3069 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3071 py3_style_class = False # Python3 style class (bases+kwargs)
3073 def __init__(self, pos, name, bases, doc, body, decorators = None,
3074 keyword_args = None, starstar_arg = None):
3075 StatNode.__init__(self, pos)
3079 self.decorators = decorators
3081 if self.doc and Options.docstrings:
3082 doc = embed_position(self.pos, self.doc)
3083 doc_node = ExprNodes.StringNode(pos, value = doc)
3086 if keyword_args or starstar_arg:
3087 self.py3_style_class = True
3089 self.metaclass = None
3090 if keyword_args and not starstar_arg:
3091 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3092 if item.key.value == 'metaclass':
3093 if self.metaclass is not None:
3094 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3095 # special case: we already know the metaclass,
3096 # so we don't need to do the "build kwargs,
3097 # find metaclass" dance at runtime
3098 self.metaclass = item.value
3099 del keyword_args.key_value_pairs[i]
3100 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3101 self.mkw = ExprNodes.KeywordArgsNode(
3102 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3104 self.mkw = ExprNodes.NullNode(pos)
3105 if self.metaclass is None:
3106 self.metaclass = ExprNodes.PyClassMetaclassNode(
3107 pos, mkw = self.mkw, bases = self.bases)
3108 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3109 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3111 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3112 bases = self.bases, dict = self.dict, doc = doc_node,
3113 metaclass = self.metaclass, mkw = self.mkw)
3115 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3116 self.metaclass = None
3119 self.classobj = ExprNodes.ClassNode(pos, name = name,
3120 bases = bases, dict = self.dict, doc = doc_node)
3121 self.target = ExprNodes.NameNode(pos, name = name)
3123 def as_cclass(self):
3125 Return this node as if it were declared as an extension class
3127 if self.py3_style_class:
3128 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3130 bases = self.classobj.bases.args
3132 base_class_name = None
3133 base_class_module = None
3134 elif len(bases) == 1:
3137 from ExprNodes import AttributeNode, NameNode
3138 while isinstance(base, AttributeNode):
3139 path.insert(0, base.attribute)
3141 if isinstance(base, NameNode):
3142 path.insert(0, base.name)
3143 base_class_name = path[-1]
3145 base_class_module = u'.'.join(path[:-1])
3147 base_class_module = None
3149 error(self.classobj.bases.args.pos, "Invalid base class")
3151 error(self.classobj.bases.args.pos, "C class may only have one base class")
3154 return CClassDefNode(self.pos,
3155 visibility = 'private',
3157 class_name = self.name,
3158 base_class_module = base_class_module,
3159 base_class_name = base_class_name,
3160 decorators = self.decorators,
3165 def create_scope(self, env):
3167 while genv.is_py_class_scope or genv.is_c_class_scope:
3168 genv = genv.outer_scope
3169 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3172 def analyse_declarations(self, env):
3173 self.target.analyse_target_declaration(env)
3174 cenv = self.create_scope(env)
3175 cenv.directives = env.directives
3176 cenv.class_obj_cname = self.target.entry.cname
3177 self.body.analyse_declarations(cenv)
3179 def analyse_expressions(self, env):
3180 if self.py3_style_class:
3181 self.bases.analyse_expressions(env)
3182 self.metaclass.analyse_expressions(env)
3183 self.mkw.analyse_expressions(env)
3184 self.dict.analyse_expressions(env)
3185 self.classobj.analyse_expressions(env)
3186 genv = env.global_scope()
3188 self.body.analyse_expressions(cenv)
3189 self.target.analyse_target_expression(env, self.classobj)
3191 def generate_function_definitions(self, env, code):
3192 self.generate_lambda_definitions(self.scope, code)
3193 self.body.generate_function_definitions(self.scope, code)
3195 def generate_execution_code(self, code):
3196 code.pyclass_stack.append(self)
3198 if self.py3_style_class:
3199 self.bases.generate_evaluation_code(code)
3200 self.mkw.generate_evaluation_code(code)
3201 self.metaclass.generate_evaluation_code(code)
3202 self.dict.generate_evaluation_code(code)
3203 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3204 self.body.generate_execution_code(code)
3205 self.classobj.generate_evaluation_code(code)
3206 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3207 self.target.generate_assignment_code(self.classobj, code)
3208 self.dict.generate_disposal_code(code)
3209 self.dict.free_temps(code)
3210 if self.py3_style_class:
3211 self.mkw.generate_disposal_code(code)
3212 self.mkw.free_temps(code)
3213 self.metaclass.generate_disposal_code(code)
3214 self.metaclass.free_temps(code)
3215 self.bases.generate_disposal_code(code)
3216 self.bases.free_temps(code)
3217 code.pyclass_stack.pop()
3219 class CClassDefNode(ClassDefNode):
3220 # An extension type definition.
3222 # visibility 'private' or 'public' or 'extern'
3223 # typedef_flag boolean
3225 # module_name string or None For import of extern type objects
3226 # class_name string Unqualified name of class
3227 # as_name string or None Name to declare as in this scope
3228 # base_class_module string or None Module containing the base class
3229 # base_class_name string or None Name of the base class
3230 # objstruct_name string or None Specified C name of object struct
3231 # typeobj_name string or None Specified C name of type object
3232 # in_pxd boolean Is in a .pxd file
3233 # decorators [DecoratorNode] list of decorators or None
3234 # doc string or None
3235 # body StatNode or None
3236 # entry Symtab.Entry
3237 # base_type PyExtensionType or None
3238 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3239 # buffer_defaults_pos
3241 child_attrs = ["body"]
3242 buffer_defaults_node = None
3243 buffer_defaults_pos = None
3244 typedef_flag = False
3246 objstruct_name = None
3250 def analyse_declarations(self, env):
3251 #print "CClassDefNode.analyse_declarations:", self.class_name
3252 #print "...visibility =", self.visibility
3253 #print "...module_name =", self.module_name
3256 if self.buffer_defaults_node:
3257 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3258 env, [], self.buffer_defaults_node,
3259 need_complete=False)
3261 buffer_defaults = None
3263 if env.in_cinclude and not self.objstruct_name:
3264 error(self.pos, "Object struct name specification required for "
3265 "C class defined in 'extern from' block")
3266 self.base_type = None
3267 # Now that module imports are cached, we need to
3268 # import the modules for extern classes.
3269 if self.module_name:
3271 for module in env.cimported_modules:
3272 if module.name == self.module_name:
3273 self.module = module
3274 if self.module is None:
3275 self.module = ModuleScope(self.module_name, None, env.context)
3276 self.module.has_extern_class = 1
3277 env.add_imported_module(self.module)
3279 if self.base_class_name:
3280 if self.base_class_module:
3281 base_class_scope = env.find_module(self.base_class_module, self.pos)
3283 base_class_scope = env
3284 if self.base_class_name == 'object':
3285 # extension classes are special and don't need to inherit from object
3286 if base_class_scope is None or base_class_scope.lookup('object') is None:
3287 self.base_class_name = None
3288 self.base_class_module = None
3289 base_class_scope = None
3290 if base_class_scope:
3291 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3292 if base_class_entry:
3293 if not base_class_entry.is_type:
3294 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3295 elif not base_class_entry.type.is_extension_type and \
3296 not (base_class_entry.type.is_builtin_type and \
3297 base_class_entry.type.objstruct_cname):
3298 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3299 elif not base_class_entry.type.is_complete():
3300 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3301 self.base_class_name, self.class_name))
3302 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3303 base_class_entry.type.scope.directives['final']:
3304 error(self.pos, "Base class '%s' of type '%s' is final" % (
3305 self.base_class_name, self.class_name))
3306 elif base_class_entry.type.is_builtin_type and \
3307 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3308 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3309 % base_class_entry.type.name)
3311 self.base_type = base_class_entry.type
3312 has_body = self.body is not None
3313 if self.module_name and self.visibility != 'extern':
3314 module_path = self.module_name.split(".")
3315 home_scope = env.find_imported_module(module_path, self.pos)
3321 if self.visibility == 'extern':
3322 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3323 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3325 self.entry = home_scope.declare_c_class(
3326 name = self.class_name,
3328 defining = has_body and self.in_pxd,
3329 implementing = has_body and not self.in_pxd,
3330 module_name = self.module_name,
3331 base_type = self.base_type,
3332 objstruct_cname = self.objstruct_name,
3333 typeobj_cname = self.typeobj_name,
3334 visibility = self.visibility,
3335 typedef_flag = self.typedef_flag,
3337 buffer_defaults = buffer_defaults)
3338 if home_scope is not env and self.visibility == 'extern':
3339 env.add_imported_entry(self.class_name, self.entry, self.pos)
3340 self.scope = scope = self.entry.type.scope
3341 if scope is not None:
3342 scope.directives = env.directives
3344 if self.doc and Options.docstrings:
3345 scope.doc = embed_position(self.pos, self.doc)
3348 self.body.analyse_declarations(scope)
3352 scope.implemented = 1
3353 env.allocate_vtable_names(self.entry)
3355 def analyse_expressions(self, env):
3357 scope = self.entry.type.scope
3358 self.body.analyse_expressions(scope)
3360 def generate_function_definitions(self, env, code):
3362 self.generate_lambda_definitions(self.scope, code)
3363 self.body.generate_function_definitions(self.scope, code)
3365 def generate_execution_code(self, code):
3366 # This is needed to generate evaluation code for
3367 # default values of method arguments.
3369 self.body.generate_execution_code(code)
3371 def annotate(self, code):
3373 self.body.annotate(code)
3376 class PropertyNode(StatNode):
3377 # Definition of a property in an extension type.
3380 # doc EncodedString or None Doc string
3383 child_attrs = ["body"]
3385 def analyse_declarations(self, env):
3386 entry = env.declare_property(self.name, self.doc, self.pos)
3388 entry.scope.directives = env.directives
3389 self.body.analyse_declarations(entry.scope)
3391 def analyse_expressions(self, env):
3392 self.body.analyse_expressions(env)
3394 def generate_function_definitions(self, env, code):
3395 self.body.generate_function_definitions(env, code)
3397 def generate_execution_code(self, code):
3400 def annotate(self, code):
3401 self.body.annotate(code)
3404 class GlobalNode(StatNode):
3405 # Global variable declaration.
3411 def analyse_declarations(self, env):
3412 for name in self.names:
3413 env.declare_global(name, self.pos)
3415 def analyse_expressions(self, env):
3418 def generate_execution_code(self, code):
3422 class ExprStatNode(StatNode):
3423 # Expression used as a statement.
3427 child_attrs = ["expr"]
3429 def analyse_declarations(self, env):
3431 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3432 func = self.expr.function.as_cython_attribute()
3433 if func == u'declare':
3434 args, kwds = self.expr.explicit_args_kwds()
3436 error(self.expr.pos, "Variable names must be specified.")
3437 for var, type_node in kwds.key_value_pairs:
3438 type = type_node.analyse_as_type(env)
3440 error(type_node.pos, "Unknown type")
3442 env.declare_var(var.value, type, var.pos, is_cdef = True)
3443 self.__class__ = PassStatNode
3445 def analyse_expressions(self, env):
3446 self.expr.analyse_expressions(env)
3448 def generate_execution_code(self, code):
3449 self.expr.generate_evaluation_code(code)
3450 if not self.expr.is_temp and self.expr.result():
3451 code.putln("%s;" % self.expr.result())
3452 self.expr.generate_disposal_code(code)
3453 self.expr.free_temps(code)
3455 def generate_function_definitions(self, env, code):
3456 self.expr.generate_function_definitions(env, code)
3458 def annotate(self, code):
3459 self.expr.annotate(code)
3462 class AssignmentNode(StatNode):
3463 # Abstract base class for assignment nodes.
3465 # The analyse_expressions and generate_execution_code
3466 # phases of assignments are split into two sub-phases
3467 # each, to enable all the right hand sides of a
3468 # parallel assignment to be evaluated before assigning
3469 # to any of the left hand sides.
3471 def analyse_expressions(self, env):
3472 self.analyse_types(env)
3474 # def analyse_expressions(self, env):
3475 # self.analyse_expressions_1(env)
3476 # self.analyse_expressions_2(env)
3478 def generate_execution_code(self, code):
3479 self.generate_rhs_evaluation_code(code)
3480 self.generate_assignment_code(code)
3483 class SingleAssignmentNode(AssignmentNode):
3484 # The simplest case:
3488 # lhs ExprNode Left hand side
3489 # rhs ExprNode Right hand side
3490 # first bool Is this guaranteed the first assignment to lhs?
3492 child_attrs = ["lhs", "rhs"]
3494 declaration_only = False
3496 def analyse_declarations(self, env):
3499 # handle declarations of the form x = cython.foo()
3500 if isinstance(self.rhs, ExprNodes.CallNode):
3501 func_name = self.rhs.function.as_cython_attribute()
3503 args, kwds = self.rhs.explicit_args_kwds()
3505 if func_name in ['declare', 'typedef']:
3506 if len(args) > 2 or kwds is not None:
3507 error(self.rhs.pos, "Can only declare one type at a time.")
3509 type = args[0].analyse_as_type(env)
3511 error(args[0].pos, "Unknown type")
3514 if func_name == 'declare':
3515 if isinstance(lhs, ExprNodes.NameNode):
3516 vars = [(lhs.name, lhs.pos)]
3517 elif isinstance(lhs, ExprNodes.TupleNode):
3518 vars = [(var.name, var.pos) for var in lhs.args]
3520 error(lhs.pos, "Invalid declaration")
3522 for var, pos in vars:
3523 env.declare_var(var, type, pos, is_cdef = True)
3528 self.declaration_only = True
3530 self.declaration_only = True
3531 if not isinstance(lhs, ExprNodes.NameNode):
3532 error(lhs.pos, "Invalid declaration.")
3533 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3535 elif func_name in ['struct', 'union']:
3536 self.declaration_only = True
3537 if len(args) > 0 or kwds is None:
3538 error(self.rhs.pos, "Struct or union members must be given by name.")
3541 for member, type_node in kwds.key_value_pairs:
3542 type = type_node.analyse_as_type(env)
3544 error(type_node.pos, "Unknown type")
3546 members.append((member.value, type, member.pos))
3547 if len(members) < len(kwds.key_value_pairs):
3549 if not isinstance(self.lhs, ExprNodes.NameNode):
3550 error(self.lhs.pos, "Invalid declaration.")
3551 name = self.lhs.name
3552 scope = StructOrUnionScope(name)
3553 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3554 for member, type, pos in members:
3555 scope.declare_var(member, type, pos)
3557 if self.declaration_only:
3560 self.lhs.analyse_target_declaration(env)
3562 def analyse_types(self, env, use_temp = 0):
3563 self.rhs.analyse_types(env)
3564 self.lhs.analyse_target_types(env)
3565 self.lhs.gil_assignment_check(env)
3566 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3568 self.rhs = self.rhs.coerce_to_temp(env)
3570 def generate_rhs_evaluation_code(self, code):
3571 self.rhs.generate_evaluation_code(code)
3573 def generate_assignment_code(self, code):
3574 self.lhs.generate_assignment_code(self.rhs, code)
3576 def generate_function_definitions(self, env, code):
3577 self.rhs.generate_function_definitions(env, code)
3579 def annotate(self, code):
3580 self.lhs.annotate(code)
3581 self.rhs.annotate(code)
3584 class CascadedAssignmentNode(AssignmentNode):
3585 # An assignment with multiple left hand sides:
3589 # lhs_list [ExprNode] Left hand sides
3590 # rhs ExprNode Right hand sides
3594 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3596 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3597 coerced_rhs_list = None
3599 def analyse_declarations(self, env):
3600 for lhs in self.lhs_list:
3601 lhs.analyse_target_declaration(env)
3603 def analyse_types(self, env, use_temp = 0):
3604 self.rhs.analyse_types(env)
3605 if not self.rhs.is_simple():
3607 self.rhs = self.rhs.coerce_to_temp(env)
3609 self.rhs = self.rhs.coerce_to_simple(env)
3610 from ExprNodes import CloneNode
3611 self.coerced_rhs_list = []
3612 for lhs in self.lhs_list:
3613 lhs.analyse_target_types(env)
3614 lhs.gil_assignment_check(env)
3615 rhs = CloneNode(self.rhs)
3616 rhs = rhs.coerce_to(lhs.type, env)
3617 self.coerced_rhs_list.append(rhs)
3619 def generate_rhs_evaluation_code(self, code):
3620 self.rhs.generate_evaluation_code(code)
3622 def generate_assignment_code(self, code):
3623 for i in range(len(self.lhs_list)):
3624 lhs = self.lhs_list[i]
3625 rhs = self.coerced_rhs_list[i]
3626 rhs.generate_evaluation_code(code)
3627 lhs.generate_assignment_code(rhs, code)
3628 # Assignment has disposed of the cloned RHS
3629 self.rhs.generate_disposal_code(code)
3630 self.rhs.free_temps(code)
3632 def generate_function_definitions(self, env, code):
3633 self.rhs.generate_function_definitions(env, code)
3635 def annotate(self, code):
3636 for i in range(len(self.lhs_list)):
3637 lhs = self.lhs_list[i].annotate(code)
3638 rhs = self.coerced_rhs_list[i].annotate(code)
3639 self.rhs.annotate(code)
3642 class ParallelAssignmentNode(AssignmentNode):
3643 # A combined packing/unpacking assignment:
3647 # This has been rearranged by the parser into
3649 # a = d ; b = e ; c = f
3651 # but we must evaluate all the right hand sides
3652 # before assigning to any of the left hand sides.
3654 # stats [AssignmentNode] The constituent assignments
3656 child_attrs = ["stats"]
3658 def analyse_declarations(self, env):
3659 for stat in self.stats:
3660 stat.analyse_declarations(env)
3662 def analyse_expressions(self, env):
3663 for stat in self.stats:
3664 stat.analyse_types(env, use_temp = 1)
3666 # def analyse_expressions(self, env):
3667 # for stat in self.stats:
3668 # stat.analyse_expressions_1(env, use_temp = 1)
3669 # for stat in self.stats:
3670 # stat.analyse_expressions_2(env)
3672 def generate_execution_code(self, code):
3673 for stat in self.stats:
3674 stat.generate_rhs_evaluation_code(code)
3675 for stat in self.stats:
3676 stat.generate_assignment_code(code)
3678 def generate_function_definitions(self, env, code):
3679 for stat in self.stats:
3680 stat.generate_function_definitions(env, code)
3682 def annotate(self, code):
3683 for stat in self.stats:
3687 class InPlaceAssignmentNode(AssignmentNode):
3688 # An in place arithmetic operand:
3694 # lhs ExprNode Left hand side
3695 # rhs ExprNode Right hand side
3696 # op char one of "+-*/%^&|"
3697 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3699 # This code is a bit tricky because in order to obey Python
3700 # semantics the sub-expressions (e.g. indices) of the lhs must
3701 # not be evaluated twice. So we must re-use the values calculated
3702 # in evaluation phase for the assignment phase as well.
3703 # Fortunately, the type of the lhs node is fairly constrained
3704 # (it must be a NameNode, AttributeNode, or IndexNode).
3706 child_attrs = ["lhs", "rhs"]
3708 def analyse_declarations(self, env):
3709 self.lhs.analyse_target_declaration(env)
3711 def analyse_types(self, env):
3712 self.rhs.analyse_types(env)
3713 self.lhs.analyse_target_types(env)
3715 def generate_execution_code(self, code):
3717 self.rhs.generate_evaluation_code(code)
3718 self.lhs.generate_subexpr_evaluation_code(code)
3719 c_op = self.operator
3723 error(self.pos, "No C inplace power operator")
3724 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3725 if self.lhs.type.is_pyobject:
3726 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3727 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3728 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3729 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3732 # TODO: make sure overload is declared
3733 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3734 self.lhs.generate_subexpr_disposal_code(code)
3735 self.lhs.free_subexpr_temps(code)
3736 self.rhs.generate_disposal_code(code)
3737 self.rhs.free_temps(code)
3739 def annotate(self, code):
3740 self.lhs.annotate(code)
3741 self.rhs.annotate(code)
3743 def create_binop_node(self):
3745 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3748 class PrintStatNode(StatNode):
3751 # arg_tuple TupleNode
3752 # stream ExprNode or None (stdout)
3753 # append_newline boolean
3755 child_attrs = ["arg_tuple", "stream"]
3757 def analyse_expressions(self, env):
3759 self.stream.analyse_expressions(env)
3760 self.stream = self.stream.coerce_to_pyobject(env)
3761 self.arg_tuple.analyse_expressions(env)
3762 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3763 env.use_utility_code(printing_utility_code)
3764 if len(self.arg_tuple.args) == 1 and self.append_newline:
3765 env.use_utility_code(printing_one_utility_code)
3767 nogil_check = Node.gil_error
3768 gil_message = "Python print statement"
3770 def generate_execution_code(self, code):
3772 self.stream.generate_evaluation_code(code)
3773 stream_result = self.stream.py_result()
3776 if len(self.arg_tuple.args) == 1 and self.append_newline:
3777 arg = self.arg_tuple.args[0]
3778 arg.generate_evaluation_code(code)
3781 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3784 code.error_goto(self.pos)))
3785 arg.generate_disposal_code(code)
3786 arg.free_temps(code)
3788 self.arg_tuple.generate_evaluation_code(code)
3790 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3792 self.arg_tuple.py_result(),
3793 self.append_newline,
3794 code.error_goto(self.pos)))
3795 self.arg_tuple.generate_disposal_code(code)
3796 self.arg_tuple.free_temps(code)
3799 self.stream.generate_disposal_code(code)
3800 self.stream.free_temps(code)
3802 def generate_function_definitions(self, env, code):
3804 self.stream.generate_function_definitions(env, code)
3805 self.arg_tuple.generate_function_definitions(env, code)
3807 def annotate(self, code):
3809 self.stream.annotate(code)
3810 self.arg_tuple.annotate(code)
3813 class ExecStatNode(StatNode):
3818 child_attrs = ["args"]
3820 def analyse_expressions(self, env):
3821 for i, arg in enumerate(self.args):
3822 arg.analyse_expressions(env)
3823 arg = arg.coerce_to_pyobject(env)
3825 env.use_utility_code(Builtin.pyexec_utility_code)
3827 nogil_check = Node.gil_error
3828 gil_message = "Python exec statement"
3830 def generate_execution_code(self, code):
3832 for arg in self.args:
3833 arg.generate_evaluation_code(code)
3834 args.append( arg.py_result() )
3835 args = tuple(args + ['0', '0'][:3-len(args)])
3836 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3837 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3838 (temp_result,) + args))
3839 for arg in self.args:
3840 arg.generate_disposal_code(code)
3841 arg.free_temps(code)
3843 code.error_goto_if_null(temp_result, self.pos))
3844 code.put_gotref(temp_result)
3845 code.put_decref_clear(temp_result, py_object_type)
3846 code.funcstate.release_temp(temp_result)
3848 def annotate(self, code):
3849 for arg in self.args:
3853 class DelStatNode(StatNode):
3858 child_attrs = ["args"]
3860 def analyse_declarations(self, env):
3861 for arg in self.args:
3862 arg.analyse_target_declaration(env)
3864 def analyse_expressions(self, env):
3865 for arg in self.args:
3866 arg.analyse_target_expression(env, None)
3867 if arg.type.is_pyobject:
3869 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3871 elif arg.type.is_cpp_class:
3872 error(arg.pos, "Deletion of non-heap C++ object")
3874 error(arg.pos, "Deletion of non-Python, non-C++ object")
3875 #arg.release_target_temp(env)
3877 def nogil_check(self, env):
3878 for arg in self.args:
3879 if arg.type.is_pyobject:
3882 gil_message = "Deleting Python object"
3884 def generate_execution_code(self, code):
3885 for arg in self.args:
3886 if arg.type.is_pyobject:
3887 arg.generate_deletion_code(code)
3888 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3889 arg.generate_result_code(code)
3890 code.putln("delete %s;" % arg.result())
3891 # else error reported earlier
3893 def annotate(self, code):
3894 for arg in self.args:
3898 class PassStatNode(StatNode):
3903 def analyse_expressions(self, env):
3906 def generate_execution_code(self, code):
3910 class BreakStatNode(StatNode):
3914 def analyse_expressions(self, env):
3917 def generate_execution_code(self, code):
3918 if not code.break_label:
3919 error(self.pos, "break statement not inside loop")
3921 code.put_goto(code.break_label)
3924 class ContinueStatNode(StatNode):
3928 def analyse_expressions(self, env):
3931 def generate_execution_code(self, code):
3932 if code.funcstate.in_try_finally:
3933 error(self.pos, "continue statement inside try of try...finally")
3934 elif not code.continue_label:
3935 error(self.pos, "continue statement not inside loop")
3937 code.put_goto(code.continue_label)
3940 class ReturnStatNode(StatNode):
3943 # value ExprNode or None
3944 # return_type PyrexType
3946 child_attrs = ["value"]
3948 def analyse_expressions(self, env):
3949 return_type = env.return_type
3950 self.return_type = return_type
3952 error(self.pos, "Return not inside a function body")
3955 self.value.analyse_types(env)
3956 if return_type.is_void or return_type.is_returncode:
3957 error(self.value.pos,
3958 "Return with value in void function")
3960 self.value = self.value.coerce_to(env.return_type, env)
3962 if (not return_type.is_void
3963 and not return_type.is_pyobject
3964 and not return_type.is_returncode):
3965 error(self.pos, "Return value required")
3967 def nogil_check(self, env):
3968 if self.return_type.is_pyobject:
3971 gil_message = "Returning Python object"
3973 def generate_execution_code(self, code):
3974 code.mark_pos(self.pos)
3975 if not self.return_type:
3976 # error reported earlier
3978 if self.return_type.is_pyobject:
3979 code.put_xdecref(Naming.retval_cname,
3982 self.value.generate_evaluation_code(code)
3983 self.value.make_owned_reference(code)
3986 Naming.retval_cname,
3987 self.value.result_as(self.return_type)))
3988 self.value.generate_post_assignment_code(code)
3989 self.value.free_temps(code)
3991 if self.return_type.is_pyobject:
3992 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3993 elif self.return_type.is_returncode:
3996 Naming.retval_cname,
3997 self.return_type.default_value))
3998 for cname, type in code.funcstate.temps_holding_reference():
3999 code.put_decref_clear(cname, type)
4000 code.put_goto(code.return_label)
4002 def generate_function_definitions(self, env, code):
4003 if self.value is not None:
4004 self.value.generate_function_definitions(env, code)
4006 def annotate(self, code):
4008 self.value.annotate(code)
4011 class RaiseStatNode(StatNode):
4014 # exc_type ExprNode or None
4015 # exc_value ExprNode or None
4016 # exc_tb ExprNode or None
4018 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4020 def analyse_expressions(self, env):
4022 self.exc_type.analyse_types(env)
4023 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4025 self.exc_value.analyse_types(env)
4026 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4028 self.exc_tb.analyse_types(env)
4029 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4030 env.use_utility_code(raise_utility_code)
4032 nogil_check = Node.gil_error
4033 gil_message = "Raising exception"
4035 def generate_execution_code(self, code):
4037 self.exc_type.generate_evaluation_code(code)
4038 type_code = self.exc_type.py_result()
4042 self.exc_value.generate_evaluation_code(code)
4043 value_code = self.exc_value.py_result()
4047 self.exc_tb.generate_evaluation_code(code)
4048 tb_code = self.exc_tb.py_result()
4052 "__Pyx_Raise(%s, %s, %s);" % (
4056 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4058 obj.generate_disposal_code(code)
4059 obj.free_temps(code)
4061 code.error_goto(self.pos))
4063 def generate_function_definitions(self, env, code):
4064 if self.exc_type is not None:
4065 self.exc_type.generate_function_definitions(env, code)
4066 if self.exc_value is not None:
4067 self.exc_value.generate_function_definitions(env, code)
4068 if self.exc_tb is not None:
4069 self.exc_tb.generate_function_definitions(env, code)
4071 def annotate(self, code):
4073 self.exc_type.annotate(code)
4075 self.exc_value.annotate(code)
4077 self.exc_tb.annotate(code)
4080 class ReraiseStatNode(StatNode):
4084 def analyse_expressions(self, env):
4085 env.use_utility_code(restore_exception_utility_code)
4087 nogil_check = Node.gil_error
4088 gil_message = "Raising exception"
4090 def generate_execution_code(self, code):
4091 vars = code.funcstate.exc_vars
4093 for varname in vars:
4094 code.put_giveref(varname)
4095 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4096 for varname in vars:
4097 code.put("%s = 0; " % varname)
4099 code.putln(code.error_goto(self.pos))
4101 error(self.pos, "Reraise not inside except clause")
4104 class AssertStatNode(StatNode):
4108 # value ExprNode or None
4110 child_attrs = ["cond", "value"]
4112 def analyse_expressions(self, env):
4113 self.cond = self.cond.analyse_boolean_expression(env)
4115 self.value.analyse_types(env)
4116 self.value = self.value.coerce_to_pyobject(env)
4118 nogil_check = Node.gil_error
4119 gil_message = "Raising exception"
4121 def generate_execution_code(self, code):
4122 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4123 self.cond.generate_evaluation_code(code)
4125 "if (unlikely(!%s)) {" %
4128 self.value.generate_evaluation_code(code)
4130 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4131 self.value.py_result())
4132 self.value.generate_disposal_code(code)
4133 self.value.free_temps(code)
4136 "PyErr_SetNone(PyExc_AssertionError);")
4138 code.error_goto(self.pos))
4141 self.cond.generate_disposal_code(code)
4142 self.cond.free_temps(code)
4143 code.putln("#endif")
4145 def generate_function_definitions(self, env, code):
4146 self.cond.generate_function_definitions(env, code)
4147 if self.value is not None:
4148 self.value.generate_function_definitions(env, code)
4150 def annotate(self, code):
4151 self.cond.annotate(code)
4153 self.value.annotate(code)
4156 class IfStatNode(StatNode):
4159 # if_clauses [IfClauseNode]
4160 # else_clause StatNode or None
4162 child_attrs = ["if_clauses", "else_clause"]
4164 def analyse_control_flow(self, env):
4165 env.start_branching(self.pos)
4166 for if_clause in self.if_clauses:
4167 if_clause.analyse_control_flow(env)
4168 env.next_branch(if_clause.end_pos())
4169 if self.else_clause:
4170 self.else_clause.analyse_control_flow(env)
4171 env.finish_branching(self.end_pos())
4173 def analyse_declarations(self, env):
4174 for if_clause in self.if_clauses:
4175 if_clause.analyse_declarations(env)
4176 if self.else_clause:
4177 self.else_clause.analyse_declarations(env)
4179 def analyse_expressions(self, env):
4180 for if_clause in self.if_clauses:
4181 if_clause.analyse_expressions(env)
4182 if self.else_clause:
4183 self.else_clause.analyse_expressions(env)
4185 def generate_execution_code(self, code):
4186 code.mark_pos(self.pos)
4187 end_label = code.new_label()
4188 for if_clause in self.if_clauses:
4189 if_clause.generate_execution_code(code, end_label)
4190 if self.else_clause:
4191 code.putln("/*else*/ {")
4192 self.else_clause.generate_execution_code(code)
4194 code.put_label(end_label)
4196 def generate_function_definitions(self, env, code):
4197 for clause in self.if_clauses:
4198 clause.generate_function_definitions(env, code)
4199 if self.else_clause is not None:
4200 self.else_clause.generate_function_definitions(env, code)
4202 def annotate(self, code):
4203 for if_clause in self.if_clauses:
4204 if_clause.annotate(code)
4205 if self.else_clause:
4206 self.else_clause.annotate(code)
4209 class IfClauseNode(Node):
4210 # if or elif clause in an if statement
4212 # condition ExprNode
4215 child_attrs = ["condition", "body"]
4217 def analyse_control_flow(self, env):
4218 self.body.analyse_control_flow(env)
4220 def analyse_declarations(self, env):
4221 self.body.analyse_declarations(env)
4223 def analyse_expressions(self, env):
4225 self.condition.analyse_temp_boolean_expression(env)
4226 self.body.analyse_expressions(env)
4228 def get_constant_condition_result(self):
4229 if self.condition.has_constant_result():
4230 return bool(self.condition.constant_result)
4234 def generate_execution_code(self, code, end_label):
4235 self.condition.generate_evaluation_code(code)
4238 self.condition.result())
4239 self.condition.generate_disposal_code(code)
4240 self.condition.free_temps(code)
4241 self.body.generate_execution_code(code)
4242 code.put_goto(end_label)
4245 def generate_function_definitions(self, env, code):
4246 self.condition.generate_function_definitions(env, code)
4247 self.body.generate_function_definitions(env, code)
4249 def annotate(self, code):
4250 self.condition.annotate(code)
4251 self.body.annotate(code)
4254 class SwitchCaseNode(StatNode):
4255 # Generated in the optimization of an if-elif-else node
4257 # conditions [ExprNode]
4260 child_attrs = ['conditions', 'body']
4262 def generate_execution_code(self, code):
4263 for cond in self.conditions:
4264 code.mark_pos(cond.pos)
4265 cond.generate_evaluation_code(code)
4266 code.putln("case %s:" % cond.result())
4267 self.body.generate_execution_code(code)
4268 code.putln("break;")
4270 def generate_function_definitions(self, env, code):
4271 for cond in self.conditions:
4272 cond.generate_function_definitions(env, code)
4273 self.body.generate_function_definitions(env, code)
4275 def annotate(self, code):
4276 for cond in self.conditions:
4278 self.body.annotate(code)
4280 class SwitchStatNode(StatNode):
4281 # Generated in the optimization of an if-elif-else node
4284 # cases [SwitchCaseNode]
4285 # else_clause StatNode or None
4287 child_attrs = ['test', 'cases', 'else_clause']
4289 def generate_execution_code(self, code):
4290 self.test.generate_evaluation_code(code)
4291 code.putln("switch (%s) {" % self.test.result())
4292 for case in self.cases:
4293 case.generate_execution_code(code)
4294 if self.else_clause is not None:
4295 code.putln("default:")
4296 self.else_clause.generate_execution_code(code)
4297 code.putln("break;")
4300 def generate_function_definitions(self, env, code):
4301 self.test.generate_function_definitions(env, code)
4302 for case in self.cases:
4303 case.generate_function_definitions(env, code)
4304 if self.else_clause is not None:
4305 self.else_clause.generate_function_definitions(env, code)
4307 def annotate(self, code):
4308 self.test.annotate(code)
4309 for case in self.cases:
4311 if self.else_clause is not None:
4312 self.else_clause.annotate(code)
4314 class LoopNode(object):
4316 def analyse_control_flow(self, env):
4317 env.start_branching(self.pos)
4318 self.body.analyse_control_flow(env)
4319 env.next_branch(self.body.end_pos())
4320 if self.else_clause:
4321 self.else_clause.analyse_control_flow(env)
4322 env.finish_branching(self.end_pos())
4325 class WhileStatNode(LoopNode, StatNode):
4328 # condition ExprNode
4330 # else_clause StatNode
4332 child_attrs = ["condition", "body", "else_clause"]
4334 def analyse_declarations(self, env):
4335 self.body.analyse_declarations(env)
4336 if self.else_clause:
4337 self.else_clause.analyse_declarations(env)
4339 def analyse_expressions(self, env):
4341 self.condition.analyse_temp_boolean_expression(env)
4342 self.body.analyse_expressions(env)
4343 if self.else_clause:
4344 self.else_clause.analyse_expressions(env)
4346 def generate_execution_code(self, code):
4347 old_loop_labels = code.new_loop_labels()
4350 self.condition.generate_evaluation_code(code)
4351 self.condition.generate_disposal_code(code)
4354 self.condition.result())
4355 self.condition.free_temps(code)
4356 self.body.generate_execution_code(code)
4357 code.put_label(code.continue_label)
4359 break_label = code.break_label
4360 code.set_loop_labels(old_loop_labels)
4361 if self.else_clause:
4362 code.putln("/*else*/ {")
4363 self.else_clause.generate_execution_code(code)
4365 code.put_label(break_label)
4367 def generate_function_definitions(self, env, code):
4368 self.condition.generate_function_definitions(env, code)
4369 self.body.generate_function_definitions(env, code)
4370 if self.else_clause is not None:
4371 self.else_clause.generate_function_definitions(env, code)
4373 def annotate(self, code):
4374 self.condition.annotate(code)
4375 self.body.annotate(code)
4376 if self.else_clause:
4377 self.else_clause.annotate(code)
4380 def ForStatNode(pos, **kw):
4381 if 'iterator' in kw:
4382 return ForInStatNode(pos, **kw)
4384 return ForFromStatNode(pos, **kw)
4386 class ForInStatNode(LoopNode, StatNode):
4390 # iterator IteratorNode
4392 # else_clause StatNode
4393 # item NextNode used internally
4395 child_attrs = ["target", "iterator", "body", "else_clause"]
4398 def analyse_declarations(self, env):
4399 self.target.analyse_target_declaration(env)
4400 self.body.analyse_declarations(env)
4401 if self.else_clause:
4402 self.else_clause.analyse_declarations(env)
4404 def analyse_expressions(self, env):
4406 self.target.analyse_target_types(env)
4407 self.iterator.analyse_expressions(env)
4408 self.item = ExprNodes.NextNode(self.iterator, env)
4409 self.item = self.item.coerce_to(self.target.type, env)
4410 self.body.analyse_expressions(env)
4411 if self.else_clause:
4412 self.else_clause.analyse_expressions(env)
4414 def generate_execution_code(self, code):
4415 old_loop_labels = code.new_loop_labels()
4416 self.iterator.allocate_counter_temp(code)
4417 self.iterator.generate_evaluation_code(code)
4420 self.item.generate_evaluation_code(code)
4421 self.target.generate_assignment_code(self.item, code)
4422 self.body.generate_execution_code(code)
4423 code.put_label(code.continue_label)
4426 break_label = code.break_label
4427 code.set_loop_labels(old_loop_labels)
4429 if self.else_clause:
4430 # in nested loops, the 'else' block can contain a
4431 # 'continue' statement for the outer loop, but we may need
4432 # to generate cleanup code before taking that path, so we
4434 orig_continue_label = code.continue_label
4435 code.continue_label = code.new_label('outer_continue')
4437 code.putln("/*else*/ {")
4438 self.else_clause.generate_execution_code(code)
4441 if code.label_used(code.continue_label):
4442 code.put_goto(break_label)
4443 code.put_label(code.continue_label)
4444 self.iterator.generate_disposal_code(code)
4445 code.put_goto(orig_continue_label)
4446 code.set_loop_labels(old_loop_labels)
4448 if code.label_used(break_label):
4449 code.put_label(break_label)
4450 self.iterator.release_counter_temp(code)
4451 self.iterator.generate_disposal_code(code)
4452 self.iterator.free_temps(code)
4454 def generate_function_definitions(self, env, code):
4455 self.target.generate_function_definitions(env, code)
4456 self.iterator.generate_function_definitions(env, code)
4457 self.body.generate_function_definitions(env, code)
4458 if self.else_clause is not None:
4459 self.else_clause.generate_function_definitions(env, code)
4461 def annotate(self, code):
4462 self.target.annotate(code)
4463 self.iterator.annotate(code)
4464 self.body.annotate(code)
4465 if self.else_clause:
4466 self.else_clause.annotate(code)
4467 self.item.annotate(code)
4470 class ForFromStatNode(LoopNode, StatNode):
4471 # for name from expr rel name rel expr
4478 # step ExprNode or None
4480 # else_clause StatNode or None
4486 # loopvar_node ExprNode (usually a NameNode or temp node)
4487 # py_loopvar_node PyTempNode or None
4488 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4490 is_py_target = False
4492 py_loopvar_node = None
4495 gil_message = "For-loop using object bounds or target"
4497 def nogil_check(self, env):
4498 for x in (self.target, self.bound1, self.bound2):
4499 if x.type.is_pyobject:
4502 def analyse_declarations(self, env):
4503 self.target.analyse_target_declaration(env)
4504 self.body.analyse_declarations(env)
4505 if self.else_clause:
4506 self.else_clause.analyse_declarations(env)
4508 def analyse_expressions(self, env):
4510 self.target.analyse_target_types(env)
4511 self.bound1.analyse_types(env)
4512 self.bound2.analyse_types(env)
4513 if self.step is not None:
4514 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4515 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4516 self.step.analyse_types(env)
4518 target_type = self.target.type
4519 if self.target.type.is_numeric:
4520 loop_type = self.target.type
4522 loop_type = PyrexTypes.c_int_type
4523 if not self.bound1.type.is_pyobject:
4524 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4525 if not self.bound2.type.is_pyobject:
4526 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4527 if self.step is not None and not self.step.type.is_pyobject:
4528 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4529 self.bound1 = self.bound1.coerce_to(loop_type, env)
4530 self.bound2 = self.bound2.coerce_to(loop_type, env)
4531 if not self.bound2.is_literal:
4532 self.bound2 = self.bound2.coerce_to_temp(env)
4533 if self.step is not None:
4534 self.step = self.step.coerce_to(loop_type, env)
4535 if not self.step.is_literal:
4536 self.step = self.step.coerce_to_temp(env)
4538 target_type = self.target.type
4539 if not (target_type.is_pyobject or target_type.is_numeric):
4540 error(self.target.pos,
4541 "for-from loop variable must be c numeric type or Python object")
4542 if target_type.is_numeric:
4543 self.is_py_target = False
4544 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4545 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4546 self.loopvar_node = self.target
4547 self.py_loopvar_node = None
4549 self.is_py_target = True
4550 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4551 self.loopvar_node = c_loopvar_node
4552 self.py_loopvar_node = \
4553 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4554 self.body.analyse_expressions(env)
4555 if self.else_clause:
4556 self.else_clause.analyse_expressions(env)
4558 def generate_execution_code(self, code):
4559 old_loop_labels = code.new_loop_labels()
4560 from_range = self.from_range
4561 self.bound1.generate_evaluation_code(code)
4562 self.bound2.generate_evaluation_code(code)
4563 offset, incop = self.relation_table[self.relation1]
4564 if self.step is not None:
4565 self.step.generate_evaluation_code(code)
4566 step = self.step.result()
4567 incop = "%s=%s" % (incop[0], step)
4569 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4570 self.loopvar_node.allocate(code)
4571 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4572 self.py_loopvar_node.allocate(code)
4574 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4576 loopvar_name = self.loopvar_node.result()
4578 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4580 self.bound1.result(), offset,
4581 loopvar_name, self.relation2, self.bound2.result(),
4582 loopvar_name, incop))
4583 if self.py_loopvar_node:
4584 self.py_loopvar_node.generate_evaluation_code(code)
4585 self.target.generate_assignment_code(self.py_loopvar_node, code)
4587 code.putln("%s = %s;" % (
4588 self.target.result(), loopvar_name))
4589 self.body.generate_execution_code(code)
4590 code.put_label(code.continue_label)
4591 if self.py_loopvar_node:
4592 # This mess is to make for..from loops with python targets behave
4593 # exactly like those with C targets with regards to re-assignment
4594 # of the loop variable.
4596 if self.target.entry.is_pyglobal:
4597 # We know target is a NameNode, this is the only ugly case.
4598 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4599 target_node.allocate(code)
4600 interned_cname = code.intern_identifier(self.target.entry.name)
4601 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4602 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4603 target_node.result(),
4604 Naming.module_cname,
4606 code.error_goto_if_null(target_node.result(), self.target.pos)))
4607 code.put_gotref(target_node.result())
4609 target_node = self.target
4610 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4611 from_py_node.temp_code = loopvar_name
4612 from_py_node.generate_result_code(code)
4613 if self.target.entry.is_pyglobal:
4614 code.put_decref(target_node.result(), target_node.type)
4615 target_node.release(code)
4617 if self.py_loopvar_node:
4618 # This is potentially wasteful, but we don't want the semantics to
4619 # depend on whether or not the loop is a python type.
4620 self.py_loopvar_node.generate_evaluation_code(code)
4621 self.target.generate_assignment_code(self.py_loopvar_node, code)
4623 code.funcstate.release_temp(loopvar_name)
4624 break_label = code.break_label
4625 code.set_loop_labels(old_loop_labels)
4626 if self.else_clause:
4627 code.putln("/*else*/ {")
4628 self.else_clause.generate_execution_code(code)
4630 code.put_label(break_label)
4631 self.bound1.generate_disposal_code(code)
4632 self.bound1.free_temps(code)
4633 self.bound2.generate_disposal_code(code)
4634 self.bound2.free_temps(code)
4635 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4636 self.loopvar_node.release(code)
4637 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4638 self.py_loopvar_node.release(code)
4639 if self.step is not None:
4640 self.step.generate_disposal_code(code)
4641 self.step.free_temps(code)
4644 # {relop : (initial offset, increment op)}
4651 def generate_function_definitions(self, env, code):
4652 self.target.generate_function_definitions(env, code)
4653 self.bound1.generate_function_definitions(env, code)
4654 self.bound2.generate_function_definitions(env, code)
4655 if self.step is not None:
4656 self.step.generate_function_definitions(env, code)
4657 self.body.generate_function_definitions(env, code)
4658 if self.else_clause is not None:
4659 self.else_clause.generate_function_definitions(env, code)
4661 def annotate(self, code):
4662 self.target.annotate(code)
4663 self.bound1.annotate(code)
4664 self.bound2.annotate(code)
4666 self.step.annotate(code)
4667 self.body.annotate(code)
4668 if self.else_clause:
4669 self.else_clause.annotate(code)
4672 class WithStatNode(StatNode):
4674 Represents a Python with statement.
4676 This is only used at parse tree level; and is not present in
4677 analysis or generation phases.
4679 # manager The with statement manager object
4680 # target Node (lhs expression)
4682 child_attrs = ["manager", "target", "body"]
4684 class TryExceptStatNode(StatNode):
4685 # try .. except statement
4688 # except_clauses [ExceptClauseNode]
4689 # else_clause StatNode or None
4691 child_attrs = ["body", "except_clauses", "else_clause"]
4693 def analyse_control_flow(self, env):
4694 env.start_branching(self.pos)
4695 self.body.analyse_control_flow(env)
4696 successful_try = env.control_flow # grab this for later
4697 env.next_branch(self.body.end_pos())
4698 env.finish_branching(self.body.end_pos())
4700 env.start_branching(self.except_clauses[0].pos)
4701 for except_clause in self.except_clauses:
4702 except_clause.analyse_control_flow(env)
4703 env.next_branch(except_clause.end_pos())
4705 # the else cause it executed only when the try clause finishes
4706 env.control_flow.incoming = successful_try
4707 if self.else_clause:
4708 self.else_clause.analyse_control_flow(env)
4709 env.finish_branching(self.end_pos())
4711 def analyse_declarations(self, env):
4712 self.body.analyse_declarations(env)
4713 for except_clause in self.except_clauses:
4714 except_clause.analyse_declarations(env)
4715 if self.else_clause:
4716 self.else_clause.analyse_declarations(env)
4717 env.use_utility_code(reset_exception_utility_code)
4719 def analyse_expressions(self, env):
4720 self.body.analyse_expressions(env)
4721 default_clause_seen = 0
4722 for except_clause in self.except_clauses:
4723 except_clause.analyse_expressions(env)
4724 if default_clause_seen:
4725 error(except_clause.pos, "default 'except:' must be last")
4726 if not except_clause.pattern:
4727 default_clause_seen = 1
4728 self.has_default_clause = default_clause_seen
4729 if self.else_clause:
4730 self.else_clause.analyse_expressions(env)
4732 nogil_check = Node.gil_error
4733 gil_message = "Try-except statement"
4735 def generate_execution_code(self, code):
4736 old_return_label = code.return_label
4737 old_break_label = code.break_label
4738 old_continue_label = code.continue_label
4739 old_error_label = code.new_error_label()
4740 our_error_label = code.error_label
4741 except_end_label = code.new_label('exception_handled')
4742 except_error_label = code.new_label('except_error')
4743 except_return_label = code.new_label('except_return')
4744 try_return_label = code.new_label('try_return')
4745 try_break_label = code.new_label('try_break')
4746 try_continue_label = code.new_label('try_continue')
4747 try_end_label = code.new_label('try_end')
4749 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4752 code.putln("__Pyx_ExceptionSave(%s);" %
4753 ', '.join(['&%s' % var for var in exc_save_vars]))
4754 for var in exc_save_vars:
4755 code.put_xgotref(var)
4758 code.return_label = try_return_label
4759 code.break_label = try_break_label
4760 code.continue_label = try_continue_label
4761 self.body.generate_execution_code(code)
4764 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4765 code.error_label = except_error_label
4766 code.return_label = except_return_label
4767 if self.else_clause:
4770 self.else_clause.generate_execution_code(code)
4773 for var in exc_save_vars:
4774 code.put_xdecref_clear(var, py_object_type)
4775 code.put_goto(try_end_label)
4776 if code.label_used(try_return_label):
4777 code.put_label(try_return_label)
4778 for var in exc_save_vars: code.put_xgiveref(var)
4779 code.putln("__Pyx_ExceptionReset(%s);" %
4780 ', '.join(exc_save_vars))
4781 code.put_goto(old_return_label)
4782 code.put_label(our_error_label)
4783 for temp_name, type in temps_to_clean_up:
4784 code.put_xdecref_clear(temp_name, type)
4785 for except_clause in self.except_clauses:
4786 except_clause.generate_handling_code(code, except_end_label)
4788 error_label_used = code.label_used(except_error_label)
4789 if error_label_used or not self.has_default_clause:
4790 if error_label_used:
4791 code.put_label(except_error_label)
4792 for var in exc_save_vars: code.put_xgiveref(var)
4793 code.putln("__Pyx_ExceptionReset(%s);" %
4794 ', '.join(exc_save_vars))
4795 code.put_goto(old_error_label)
4797 for exit_label, old_label in zip(
4798 [try_break_label, try_continue_label, except_return_label],
4799 [old_break_label, old_continue_label, old_return_label]):
4801 if code.label_used(exit_label):
4802 code.put_label(exit_label)
4803 for var in exc_save_vars: code.put_xgiveref(var)
4804 code.putln("__Pyx_ExceptionReset(%s);" %
4805 ', '.join(exc_save_vars))
4806 code.put_goto(old_label)
4808 if code.label_used(except_end_label):
4809 code.put_label(except_end_label)
4810 for var in exc_save_vars: code.put_xgiveref(var)
4811 code.putln("__Pyx_ExceptionReset(%s);" %
4812 ', '.join(exc_save_vars))
4813 code.put_label(try_end_label)
4816 for cname in exc_save_vars:
4817 code.funcstate.release_temp(cname)
4819 code.return_label = old_return_label
4820 code.break_label = old_break_label
4821 code.continue_label = old_continue_label
4822 code.error_label = old_error_label
4824 def generate_function_definitions(self, env, code):
4825 self.body.generate_function_definitions(env, code)
4826 for except_clause in self.except_clauses:
4827 except_clause.generate_function_definitions(env, code)
4828 if self.else_clause is not None:
4829 self.else_clause.generate_function_definitions(env, code)
4831 def annotate(self, code):
4832 self.body.annotate(code)
4833 for except_node in self.except_clauses:
4834 except_node.annotate(code)
4835 if self.else_clause:
4836 self.else_clause.annotate(code)
4839 class ExceptClauseNode(Node):
4840 # Part of try ... except statement.
4842 # pattern [ExprNode]
4843 # target ExprNode or None
4845 # excinfo_target NameNode or None optional target for exception info
4846 # match_flag string result of exception match
4847 # exc_value ExcValueNode used internally
4848 # function_name string qualified name of enclosing function
4849 # exc_vars (string * 3) local exception variables
4851 # excinfo_target is never set by the parser, but can be set by a transform
4852 # in order to extract more extensive information about the exception as a
4853 # sys.exc_info()-style tuple into a target variable
4855 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4858 excinfo_target = None
4860 def analyse_declarations(self, env):
4862 self.target.analyse_target_declaration(env)
4863 if self.excinfo_target is not None:
4864 self.excinfo_target.analyse_target_declaration(env)
4865 self.body.analyse_declarations(env)
4867 def analyse_expressions(self, env):
4869 genv = env.global_scope()
4870 self.function_name = env.qualified_name
4872 # normalise/unpack self.pattern into a list
4873 for i, pattern in enumerate(self.pattern):
4874 pattern.analyse_expressions(env)
4875 self.pattern[i] = pattern.coerce_to_pyobject(env)
4878 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4879 self.target.analyse_target_expression(env, self.exc_value)
4880 if self.excinfo_target is not None:
4882 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4883 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4884 self.excinfo_tuple.analyse_expressions(env)
4885 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4887 self.body.analyse_expressions(env)
4889 def generate_handling_code(self, code, end_label):
4890 code.mark_pos(self.pos)
4893 for pattern in self.pattern:
4894 pattern.generate_evaluation_code(code)
4895 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4897 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4899 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4900 for pattern in self.pattern:
4901 pattern.generate_disposal_code(code)
4902 pattern.free_temps(code)
4906 code.funcstate.release_temp(match_flag)
4908 code.putln("/*except:*/ {")
4910 if not getattr(self.body, 'stats', True) and \
4911 self.excinfo_target is None and self.target is None:
4912 # most simple case: no exception variable, empty body (pass)
4913 # => reset the exception state, done
4914 code.putln("PyErr_Restore(0,0,0);")
4915 code.put_goto(end_label)
4919 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4922 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4923 # We always have to fetch the exception value even if
4924 # there is no target, because this also normalises the
4925 # exception and stores it in the thread state.
4926 code.globalstate.use_utility_code(get_exception_utility_code)
4927 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4928 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4929 code.error_goto(self.pos)))
4933 self.exc_value.set_var(exc_vars[1])
4934 self.exc_value.generate_evaluation_code(code)
4935 self.target.generate_assignment_code(self.exc_value, code)
4936 if self.excinfo_target is not None:
4937 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4938 node.set_var(tempvar)
4939 self.excinfo_tuple.generate_evaluation_code(code)
4940 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4942 old_break_label, old_continue_label = code.break_label, code.continue_label
4943 code.break_label = code.new_label('except_break')
4944 code.continue_label = code.new_label('except_continue')
4946 old_exc_vars = code.funcstate.exc_vars
4947 code.funcstate.exc_vars = exc_vars
4948 self.body.generate_execution_code(code)
4949 code.funcstate.exc_vars = old_exc_vars
4950 for var in exc_vars:
4951 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4952 code.put_goto(end_label)
4954 if code.label_used(code.break_label):
4955 code.put_label(code.break_label)
4956 for var in exc_vars:
4957 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4958 code.put_goto(old_break_label)
4959 code.break_label = old_break_label
4961 if code.label_used(code.continue_label):
4962 code.put_label(code.continue_label)
4963 for var in exc_vars:
4964 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4965 code.put_goto(old_continue_label)
4966 code.continue_label = old_continue_label
4968 for temp in exc_vars:
4969 code.funcstate.release_temp(temp)
4974 def generate_function_definitions(self, env, code):
4975 if self.target is not None:
4976 self.target.generate_function_definitions(env, code)
4977 self.body.generate_function_definitions(env, code)
4979 def annotate(self, code):
4981 for pattern in self.pattern:
4982 pattern.annotate(code)
4984 self.target.annotate(code)
4985 self.body.annotate(code)
4988 class TryFinallyStatNode(StatNode):
4989 # try ... finally statement
4992 # finally_clause StatNode
4994 # The plan is that we funnel all continue, break
4995 # return and error gotos into the beginning of the
4996 # finally block, setting a variable to remember which
4997 # one we're doing. At the end of the finally block, we
4998 # switch on the variable to figure out where to go.
4999 # In addition, if we're doing an error, we save the
5000 # exception on entry to the finally block and restore
5003 child_attrs = ["body", "finally_clause"]
5005 preserve_exception = 1
5007 disallow_continue_in_try_finally = 0
5008 # There doesn't seem to be any point in disallowing
5009 # continue in the try block, since we have no problem
5012 def create_analysed(pos, env, body, finally_clause):
5013 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5015 create_analysed = staticmethod(create_analysed)
5017 def analyse_control_flow(self, env):
5018 env.start_branching(self.pos)
5019 self.body.analyse_control_flow(env)
5020 env.next_branch(self.body.end_pos())
5021 env.finish_branching(self.body.end_pos())
5022 self.finally_clause.analyse_control_flow(env)
5024 def analyse_declarations(self, env):
5025 self.body.analyse_declarations(env)
5026 self.finally_clause.analyse_declarations(env)
5028 def analyse_expressions(self, env):
5029 self.body.analyse_expressions(env)
5030 self.finally_clause.analyse_expressions(env)
5032 nogil_check = Node.gil_error
5033 gil_message = "Try-finally statement"
5035 def generate_execution_code(self, code):
5036 old_error_label = code.error_label
5037 old_labels = code.all_new_labels()
5038 new_labels = code.get_all_labels()
5039 new_error_label = code.error_label
5040 catch_label = code.new_label()
5043 if self.disallow_continue_in_try_finally:
5044 was_in_try_finally = code.funcstate.in_try_finally
5045 code.funcstate.in_try_finally = 1
5046 self.body.generate_execution_code(code)
5047 if self.disallow_continue_in_try_finally:
5048 code.funcstate.in_try_finally = was_in_try_finally
5051 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5052 code.mark_pos(self.finally_clause.pos)
5056 error_label_used = 0
5057 for i, new_label in enumerate(new_labels):
5058 if new_label in code.labels_used:
5059 cases_used.append(i)
5060 if new_label == new_error_label:
5061 error_label_used = 1
5062 error_label_case = i
5066 if error_label_used and self.preserve_exception:
5068 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5070 "int %s;" % Naming.exc_lineno_name)
5071 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5072 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5073 code.putln(exc_var_init_zero)
5075 exc_var_init_zero = None
5076 code.use_label(catch_label)
5078 "__pyx_why = 0; goto %s;" % catch_label)
5079 for i in cases_used:
5080 new_label = new_labels[i]
5081 #if new_label and new_label != "<try>":
5082 if new_label == new_error_label and self.preserve_exception:
5083 self.put_error_catcher(code,
5084 new_error_label, i+1, catch_label, temps_to_clean_up)
5086 code.put('%s: ' % new_label)
5087 if exc_var_init_zero:
5088 code.putln(exc_var_init_zero)
5089 code.putln("__pyx_why = %s; goto %s;" % (
5092 code.put_label(catch_label)
5093 code.set_all_labels(old_labels)
5094 if error_label_used:
5095 code.new_error_label()
5096 finally_error_label = code.error_label
5097 self.finally_clause.generate_execution_code(code)
5098 if error_label_used:
5099 if finally_error_label in code.labels_used and self.preserve_exception:
5100 over_label = code.new_label()
5101 code.put_goto(over_label);
5102 code.put_label(finally_error_label)
5103 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5104 for var in Naming.exc_vars:
5105 code.putln("Py_XDECREF(%s);" % var)
5107 code.put_goto(old_error_label)
5108 code.put_label(over_label)
5109 code.error_label = old_error_label
5112 "switch (__pyx_why) {")
5113 for i in cases_used:
5114 old_label = old_labels[i]
5115 if old_label == old_error_label and self.preserve_exception:
5116 self.put_error_uncatcher(code, i+1, old_error_label)
5118 code.use_label(old_label)
5120 "case %s: goto %s;" % (
5128 def generate_function_definitions(self, env, code):
5129 self.body.generate_function_definitions(env, code)
5130 self.finally_clause.generate_function_definitions(env, code)
5132 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5133 code.globalstate.use_utility_code(restore_exception_utility_code)
5140 for temp_name, type in temps_to_clean_up:
5141 code.put_xdecref_clear(temp_name, type)
5143 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5147 Naming.exc_lineno_name, Naming.lineno_cname))
5148 code.put_goto(catch_label)
5151 def put_error_uncatcher(self, code, i, error_label):
5152 code.globalstate.use_utility_code(restore_exception_utility_code)
5157 "__Pyx_ErrRestore(%s, %s, %s);" %
5161 Naming.lineno_cname, Naming.exc_lineno_name))
5162 for var in Naming.exc_vars:
5166 code.put_goto(error_label)
5170 def annotate(self, code):
5171 self.body.annotate(code)
5172 self.finally_clause.annotate(code)
5175 class GILStatNode(TryFinallyStatNode):
5176 # 'with gil' or 'with nogil' statement
5178 # state string 'gil' or 'nogil'
5182 preserve_exception = 0
5184 def __init__(self, pos, state, body):
5186 TryFinallyStatNode.__init__(self, pos,
5188 finally_clause = GILExitNode(pos, state = state))
5190 def analyse_expressions(self, env):
5191 env.use_utility_code(force_init_threads_utility_code)
5192 was_nogil = env.nogil
5194 TryFinallyStatNode.analyse_expressions(self, env)
5195 env.nogil = was_nogil
5199 def generate_execution_code(self, code):
5200 code.mark_pos(self.pos)
5202 if self.state == 'gil':
5203 code.putln("#ifdef WITH_THREAD")
5204 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5205 code.putln("#endif")
5207 code.putln("#ifdef WITH_THREAD")
5208 code.putln("PyThreadState *_save;")
5209 code.putln("#endif")
5210 code.putln("Py_UNBLOCK_THREADS")
5211 TryFinallyStatNode.generate_execution_code(self, code)
5215 class GILExitNode(StatNode):
5216 # Used as the 'finally' block in a GILStatNode
5218 # state string 'gil' or 'nogil'
5222 def analyse_expressions(self, env):
5225 def generate_execution_code(self, code):
5226 if self.state == 'gil':
5227 code.putln("#ifdef WITH_THREAD")
5228 code.putln("PyGILState_Release(_save);")
5229 code.putln("#endif")
5231 code.putln("Py_BLOCK_THREADS")
5234 class CImportStatNode(StatNode):
5237 # module_name string Qualified name of module being imported
5238 # as_name string or None Name specified in "as" clause, if any
5242 def analyse_declarations(self, env):
5243 if not env.is_module_scope:
5244 error(self.pos, "cimport only allowed at module level")
5246 module_scope = env.find_module(self.module_name, self.pos)
5247 if "." in self.module_name:
5248 names = [EncodedString(name) for name in self.module_name.split(".")]
5250 top_module_scope = env.context.find_submodule(top_name)
5251 module_scope = top_module_scope
5252 for name in names[1:]:
5253 submodule_scope = module_scope.find_submodule(name)
5254 module_scope.declare_module(name, submodule_scope, self.pos)
5255 module_scope = submodule_scope
5257 env.declare_module(self.as_name, module_scope, self.pos)
5259 env.declare_module(top_name, top_module_scope, self.pos)
5261 name = self.as_name or self.module_name
5262 env.declare_module(name, module_scope, self.pos)
5264 def analyse_expressions(self, env):
5267 def generate_execution_code(self, code):
5271 class FromCImportStatNode(StatNode):
5272 # from ... cimport statement
5274 # module_name string Qualified name of module
5275 # imported_names [(pos, name, as_name, kind)] Names to be imported
5279 def analyse_declarations(self, env):
5280 if not env.is_module_scope:
5281 error(self.pos, "cimport only allowed at module level")
5283 module_scope = env.find_module(self.module_name, self.pos)
5284 env.add_imported_module(module_scope)
5285 for pos, name, as_name, kind in self.imported_names:
5287 for local_name, entry in module_scope.entries.items():
5288 env.add_imported_entry(local_name, entry, pos)
5290 entry = module_scope.lookup(name)
5292 if kind and not self.declaration_matches(entry, kind):
5293 entry.redeclared(pos)
5295 if kind == 'struct' or kind == 'union':
5296 entry = module_scope.declare_struct_or_union(name,
5297 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5298 elif kind == 'class':
5299 entry = module_scope.declare_c_class(name, pos = pos,
5300 module_name = self.module_name)
5302 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5303 if submodule_scope.parent_module is module_scope:
5304 env.declare_module(as_name or name, submodule_scope, self.pos)
5306 error(pos, "Name '%s' not declared in module '%s'"
5307 % (name, self.module_name))
5310 local_name = as_name or name
5311 env.add_imported_entry(local_name, entry, pos)
5313 def declaration_matches(self, entry, kind):
5314 if not entry.is_type:
5318 if not type.is_extension_type:
5321 if not type.is_struct_or_union:
5323 if kind != type.kind:
5327 def analyse_expressions(self, env):
5330 def generate_execution_code(self, code):
5334 class FromImportStatNode(StatNode):
5335 # from ... import statement
5338 # items [(string, NameNode)]
5339 # interned_items [(string, NameNode, ExprNode)]
5340 # item PyTempNode used internally
5341 # import_star boolean used internally
5343 child_attrs = ["module"]
5346 def analyse_declarations(self, env):
5347 for name, target in self.items:
5349 if not env.is_module_scope:
5350 error(self.pos, "import * only allowed at module level")
5352 env.has_import_star = 1
5353 self.import_star = 1
5355 target.analyse_target_declaration(env)
5357 def analyse_expressions(self, env):
5359 self.module.analyse_expressions(env)
5360 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5361 self.interned_items = []
5362 for name, target in self.items:
5364 for _, entry in env.entries.items():
5365 if not entry.is_type and entry.type.is_extension_type:
5366 env.use_utility_code(ExprNodes.type_test_utility_code)
5369 entry = env.lookup(target.name)
5370 # check whether or not entry is already cimported
5371 if (entry.is_type and entry.type.name == name
5372 and hasattr(entry.type, 'module_name')):
5373 if entry.type.module_name == self.module.module_name.value:
5374 # cimported with absolute name
5377 # cimported with relative name
5378 module = env.find_module(self.module.module_name.value,
5380 if entry.type.module_name == module.qualified_name:
5382 except AttributeError:
5384 target.analyse_target_expression(env, None)
5385 if target.type is py_object_type:
5388 coerced_item = self.item.coerce_to(target.type, env)
5389 self.interned_items.append((name, target, coerced_item))
5391 def generate_execution_code(self, code):
5392 self.module.generate_evaluation_code(code)
5393 if self.import_star:
5395 'if (%s(%s) < 0) %s;' % (
5397 self.module.py_result(),
5398 code.error_goto(self.pos)))
5399 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5400 self.item.set_cname(item_temp)
5401 for name, target, coerced_item in self.interned_items:
5402 cname = code.intern_identifier(name)
5404 '%s = PyObject_GetAttr(%s, %s); %s' % (
5406 self.module.py_result(),
5408 code.error_goto_if_null(item_temp, self.pos)))
5409 code.put_gotref(item_temp)
5410 if coerced_item is None:
5411 target.generate_assignment_code(self.item, code)
5413 coerced_item.allocate_temp_result(code)
5414 coerced_item.generate_result_code(code)
5415 target.generate_assignment_code(coerced_item, code)
5416 code.put_decref_clear(item_temp, py_object_type)
5417 code.funcstate.release_temp(item_temp)
5418 self.module.generate_disposal_code(code)
5419 self.module.free_temps(code)
5423 #------------------------------------------------------------------------------------
5425 # Runtime support code
5427 #------------------------------------------------------------------------------------
5429 utility_function_predeclarations = \
5431 /* inline attribute */
5432 #ifndef CYTHON_INLINE
5433 #if defined(__GNUC__)
5434 #define CYTHON_INLINE __inline__
5435 #elif defined(_MSC_VER)
5436 #define CYTHON_INLINE __inline
5437 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5438 #define CYTHON_INLINE inline
5440 #define CYTHON_INLINE
5444 /* unused attribute */
5445 #ifndef CYTHON_UNUSED
5446 # if defined(__GNUC__)
5447 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5448 # define CYTHON_UNUSED __attribute__ ((__unused__))
5450 # define CYTHON_UNUSED
5452 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5453 # define CYTHON_UNUSED __attribute__ ((__unused__))
5455 # define CYTHON_UNUSED
5459 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*/
5463 if Options.gcc_branch_hints:
5464 branch_prediction_macros = \
5467 /* Test for GCC > 2.95 */
5468 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5469 #define likely(x) __builtin_expect(!!(x), 1)
5470 #define unlikely(x) __builtin_expect(!!(x), 0)
5471 #else /* __GNUC__ > 2 ... */
5472 #define likely(x) (x)
5473 #define unlikely(x) (x)
5474 #endif /* __GNUC__ > 2 ... */
5475 #else /* __GNUC__ */
5476 #define likely(x) (x)
5477 #define unlikely(x) (x)
5478 #endif /* __GNUC__ */
5481 branch_prediction_macros = \
5483 #define likely(x) (x)
5484 #define unlikely(x) (x)
5487 #get_name_predeclaration = \
5488 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5490 #get_name_interned_predeclaration = \
5491 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5493 #------------------------------------------------------------------------------------
5495 printing_utility_code = UtilityCode(
5497 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5498 #if PY_MAJOR_VERSION >= 3
5499 static PyObject* %s = 0;
5500 static PyObject* %s = 0;
5502 """ % (Naming.print_function, Naming.print_function_kwargs),
5504 #if PY_MAJOR_VERSION >= 3
5508 """ % (Naming.print_function, Naming.print_function_kwargs),
5510 #if PY_MAJOR_VERSION < 3
5511 static PyObject *__Pyx_GetStdout(void) {
5512 PyObject *f = PySys_GetObject((char *)"stdout");
5514 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5519 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5524 if (!(f = __Pyx_GetStdout()))
5527 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5528 if (PyFile_SoftSpace(f, 1)) {
5529 if (PyFile_WriteString(" ", f) < 0)
5532 v = PyTuple_GET_ITEM(arg_tuple, i);
5533 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5535 if (PyString_Check(v)) {
5536 char *s = PyString_AsString(v);
5537 Py_ssize_t len = PyString_Size(v);
5539 isspace(Py_CHARMASK(s[len-1])) &&
5541 PyFile_SoftSpace(f, 0);
5545 if (PyFile_WriteString("\n", f) < 0)
5547 PyFile_SoftSpace(f, 0);
5552 #else /* Python 3 has a print function */
5554 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5555 PyObject* kwargs = 0;
5556 PyObject* result = 0;
5557 PyObject* end_string;
5558 if (unlikely(!%(PRINT_FUNCTION)s)) {
5559 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5560 if (!%(PRINT_FUNCTION)s)
5564 kwargs = PyDict_New();
5565 if (unlikely(!kwargs))
5567 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5570 end_string = PyUnicode_FromStringAndSize(" ", 1);
5571 if (unlikely(!end_string))
5573 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5574 Py_DECREF(end_string);
5577 Py_DECREF(end_string);
5579 } else if (!newline) {
5580 if (unlikely(!%(PRINT_KWARGS)s)) {
5581 %(PRINT_KWARGS)s = PyDict_New();
5582 if (unlikely(!%(PRINT_KWARGS)s))
5584 end_string = PyUnicode_FromStringAndSize(" ", 1);
5585 if (unlikely(!end_string))
5587 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5588 Py_DECREF(end_string);
5591 Py_DECREF(end_string);
5593 kwargs = %(PRINT_KWARGS)s;
5595 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5596 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5603 if (kwargs != %(PRINT_KWARGS)s)
5609 """ % {'BUILTINS' : Naming.builtins_cname,
5610 'PRINT_FUNCTION' : Naming.print_function,
5611 'PRINT_KWARGS' : Naming.print_function_kwargs}
5615 printing_one_utility_code = UtilityCode(
5617 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5620 #if PY_MAJOR_VERSION < 3
5622 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5624 if (!(f = __Pyx_GetStdout()))
5627 if (PyFile_SoftSpace(f, 0)) {
5628 if (PyFile_WriteString(" ", f) < 0)
5631 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5633 if (PyFile_WriteString("\n", f) < 0)
5636 /* the line below is just to avoid compiler
5637 * compiler warnings about unused functions */
5638 return __Pyx_Print(f, NULL, 0);
5641 #else /* Python 3 has a print function */
5643 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5645 PyObject* arg_tuple = PyTuple_New(1);
5646 if (unlikely(!arg_tuple))
5649 PyTuple_SET_ITEM(arg_tuple, 0, o);
5650 res = __Pyx_Print(stream, arg_tuple, 1);
5651 Py_DECREF(arg_tuple);
5657 requires=[printing_utility_code])
5661 #------------------------------------------------------------------------------------
5663 # Exception raising code
5665 # Exceptions are raised by __Pyx_Raise() and stored as plain
5666 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5667 # 'except' statement, curexc_* is moved over to exc_* by
5668 # __Pyx_GetException()
5670 restore_exception_utility_code = UtilityCode(
5672 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5673 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5676 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5677 PyObject *tmp_type, *tmp_value, *tmp_tb;
5678 PyThreadState *tstate = PyThreadState_GET();
5680 tmp_type = tstate->curexc_type;
5681 tmp_value = tstate->curexc_value;
5682 tmp_tb = tstate->curexc_traceback;
5683 tstate->curexc_type = type;
5684 tstate->curexc_value = value;
5685 tstate->curexc_traceback = tb;
5686 Py_XDECREF(tmp_type);
5687 Py_XDECREF(tmp_value);
5691 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5692 PyThreadState *tstate = PyThreadState_GET();
5693 *type = tstate->curexc_type;
5694 *value = tstate->curexc_value;
5695 *tb = tstate->curexc_traceback;
5697 tstate->curexc_type = 0;
5698 tstate->curexc_value = 0;
5699 tstate->curexc_traceback = 0;
5704 # The following function is based on do_raise() from ceval.c. There
5705 # are separate versions for Python2 and Python3 as exception handling
5706 # has changed quite a lot between the two versions.
5708 raise_utility_code = UtilityCode(
5710 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5713 #if PY_MAJOR_VERSION < 3
5714 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5718 /* First, check the traceback argument, replacing None with NULL. */
5719 if (tb == Py_None) {
5723 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5724 PyErr_SetString(PyExc_TypeError,
5725 "raise: arg 3 must be a traceback or None");
5728 /* Next, replace a missing value with None */
5729 if (value == NULL) {
5733 #if PY_VERSION_HEX < 0x02050000
5734 if (!PyClass_Check(type))
5736 if (!PyType_Check(type))
5739 /* Raising an instance. The value should be a dummy. */
5740 if (value != Py_None) {
5741 PyErr_SetString(PyExc_TypeError,
5742 "instance exception may not have a separate value");
5745 /* Normalize to raise <class>, <instance> */
5748 #if PY_VERSION_HEX < 0x02050000
5749 if (PyInstance_Check(type)) {
5750 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5755 PyErr_SetString(PyExc_TypeError,
5756 "raise: exception must be an old-style class or instance");
5760 type = (PyObject*) Py_TYPE(type);
5762 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5763 PyErr_SetString(PyExc_TypeError,
5764 "raise: exception class must be a subclass of BaseException");
5770 __Pyx_ErrRestore(type, value, tb);
5779 #else /* Python 3+ */
5781 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5782 if (tb == Py_None) {
5784 } else if (tb && !PyTraceBack_Check(tb)) {
5785 PyErr_SetString(PyExc_TypeError,
5786 "raise: arg 3 must be a traceback or None");
5789 if (value == Py_None)
5792 if (PyExceptionInstance_Check(type)) {
5794 PyErr_SetString(PyExc_TypeError,
5795 "instance exception may not have a separate value");
5799 type = (PyObject*) Py_TYPE(value);
5800 } else if (!PyExceptionClass_Check(type)) {
5801 PyErr_SetString(PyExc_TypeError,
5802 "raise: exception class must be a subclass of BaseException");
5806 PyErr_SetObject(type, value);
5809 PyThreadState *tstate = PyThreadState_GET();
5810 PyObject* tmp_tb = tstate->curexc_traceback;
5813 tstate->curexc_traceback = tb;
5823 requires=[restore_exception_utility_code])
5825 #------------------------------------------------------------------------------------
5827 get_exception_utility_code = UtilityCode(
5829 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5832 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5833 PyObject *local_type, *local_value, *local_tb;
5834 PyObject *tmp_type, *tmp_value, *tmp_tb;
5835 PyThreadState *tstate = PyThreadState_GET();
5836 local_type = tstate->curexc_type;
5837 local_value = tstate->curexc_value;
5838 local_tb = tstate->curexc_traceback;
5839 tstate->curexc_type = 0;
5840 tstate->curexc_value = 0;
5841 tstate->curexc_traceback = 0;
5842 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5843 if (unlikely(tstate->curexc_type))
5845 #if PY_MAJOR_VERSION >= 3
5846 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5850 *value = local_value;
5852 Py_INCREF(local_type);
5853 Py_INCREF(local_value);
5854 Py_INCREF(local_tb);
5855 tmp_type = tstate->exc_type;
5856 tmp_value = tstate->exc_value;
5857 tmp_tb = tstate->exc_traceback;
5858 tstate->exc_type = local_type;
5859 tstate->exc_value = local_value;
5860 tstate->exc_traceback = local_tb;
5861 /* Make sure tstate is in a consistent state when we XDECREF
5862 these objects (XDECREF may run arbitrary code). */
5863 Py_XDECREF(tmp_type);
5864 Py_XDECREF(tmp_value);
5871 Py_XDECREF(local_type);
5872 Py_XDECREF(local_value);
5873 Py_XDECREF(local_tb);
5879 #------------------------------------------------------------------------------------
5881 get_exception_tuple_utility_code = UtilityCode(proto="""
5882 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5884 # I doubt that calling __Pyx_GetException() here is correct as it moves
5885 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5886 # exception handlers later on from receiving it.
5888 static PyObject *__Pyx_GetExceptionTuple(void) {
5889 PyObject *type = NULL, *value = NULL, *tb = NULL;
5890 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5891 PyObject* exc_info = PyTuple_New(3);
5896 PyTuple_SET_ITEM(exc_info, 0, type);
5897 PyTuple_SET_ITEM(exc_info, 1, value);
5898 PyTuple_SET_ITEM(exc_info, 2, tb);
5905 requires=[get_exception_utility_code])
5907 #------------------------------------------------------------------------------------
5909 reset_exception_utility_code = UtilityCode(
5911 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5912 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5915 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5916 PyThreadState *tstate = PyThreadState_GET();
5917 *type = tstate->exc_type;
5918 *value = tstate->exc_value;
5919 *tb = tstate->exc_traceback;
5925 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5926 PyObject *tmp_type, *tmp_value, *tmp_tb;
5927 PyThreadState *tstate = PyThreadState_GET();
5928 tmp_type = tstate->exc_type;
5929 tmp_value = tstate->exc_value;
5930 tmp_tb = tstate->exc_traceback;
5931 tstate->exc_type = type;
5932 tstate->exc_value = value;
5933 tstate->exc_traceback = tb;
5934 Py_XDECREF(tmp_type);
5935 Py_XDECREF(tmp_value);
5940 #------------------------------------------------------------------------------------
5942 arg_type_test_utility_code = UtilityCode(
5944 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5945 const char *name, int exact); /*proto*/
5948 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5949 const char *name, int exact)
5952 PyErr_Format(PyExc_SystemError, "Missing type object");
5955 if (none_allowed && obj == Py_None) return 1;
5957 if (Py_TYPE(obj) == type) return 1;
5960 if (PyObject_TypeCheck(obj, type)) return 1;
5962 PyErr_Format(PyExc_TypeError,
5963 "Argument '%s' has incorrect type (expected %s, got %s)",
5964 name, type->tp_name, Py_TYPE(obj)->tp_name);
5969 #------------------------------------------------------------------------------------
5971 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5972 # many or too few positional arguments were found. This handles
5973 # Py_ssize_t formatting correctly.
5975 raise_argtuple_invalid_utility_code = UtilityCode(
5977 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5978 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5981 static void __Pyx_RaiseArgtupleInvalid(
5982 const char* func_name,
5986 Py_ssize_t num_found)
5988 Py_ssize_t num_expected;
5989 const char *number, *more_or_less;
5991 if (num_found < num_min) {
5992 num_expected = num_min;
5993 more_or_less = "at least";
5995 num_expected = num_max;
5996 more_or_less = "at most";
5999 more_or_less = "exactly";
6001 number = (num_expected == 1) ? "" : "s";
6002 PyErr_Format(PyExc_TypeError,
6003 #if PY_VERSION_HEX < 0x02050000
6004 "%s() takes %s %d positional argument%s (%d given)",
6006 "%s() takes %s %zd positional argument%s (%zd given)",
6008 func_name, more_or_less, num_expected, number, num_found);
6012 raise_keyword_required_utility_code = UtilityCode(
6014 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6017 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6018 const char* func_name,
6021 PyErr_Format(PyExc_TypeError,
6022 #if PY_MAJOR_VERSION >= 3
6023 "%s() needs keyword-only argument %U", func_name, kw_name);
6025 "%s() needs keyword-only argument %s", func_name,
6026 PyString_AS_STRING(kw_name));
6031 raise_double_keywords_utility_code = UtilityCode(
6033 static void __Pyx_RaiseDoubleKeywordsError(
6034 const char* func_name, PyObject* kw_name); /*proto*/
6037 static void __Pyx_RaiseDoubleKeywordsError(
6038 const char* func_name,
6041 PyErr_Format(PyExc_TypeError,
6042 #if PY_MAJOR_VERSION >= 3
6043 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6045 "%s() got multiple values for keyword argument '%s'", func_name,
6046 PyString_AS_STRING(kw_name));
6051 #------------------------------------------------------------------------------------
6053 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6054 # were passed to a function, or if any keywords were passed to a
6055 # function that does not accept them.
6057 keyword_string_check_utility_code = UtilityCode(
6059 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6060 const char* function_name, int kw_allowed); /*proto*/
6063 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6065 const char* function_name,
6070 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6071 #if PY_MAJOR_VERSION < 3
6072 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6074 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6076 goto invalid_keyword_type;
6078 if ((!kw_allowed) && unlikely(key))
6079 goto invalid_keyword;
6081 invalid_keyword_type:
6082 PyErr_Format(PyExc_TypeError,
6083 "%s() keywords must be strings", function_name);
6086 PyErr_Format(PyExc_TypeError,
6087 #if PY_MAJOR_VERSION < 3
6088 "%s() got an unexpected keyword argument '%s'",
6089 function_name, PyString_AsString(key));
6091 "%s() got an unexpected keyword argument '%U'",
6092 function_name, key);
6098 #------------------------------------------------------------------------------------
6100 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6101 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6102 # keywords will raise an invalid keyword error.
6104 # Three kinds of errors are checked: 1) non-string keywords, 2)
6105 # unexpected keywords and 3) overlap with positional arguments.
6107 # If num_posargs is greater 0, it denotes the number of positional
6108 # arguments that were passed and that must therefore not appear
6109 # amongst the keywords as well.
6111 # This method does not check for required keyword arguments.
6114 parse_keywords_utility_code = UtilityCode(
6116 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6117 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6118 const char* function_name); /*proto*/
6121 static int __Pyx_ParseOptionalKeywords(
6123 PyObject **argnames[],
6126 Py_ssize_t num_pos_args,
6127 const char* function_name)
6129 PyObject *key = 0, *value = 0;
6132 PyObject*** first_kw_arg = argnames + num_pos_args;
6134 while (PyDict_Next(kwds, &pos, &key, &value)) {
6135 name = first_kw_arg;
6136 while (*name && (**name != key)) name++;
6138 values[name-argnames] = value;
6140 #if PY_MAJOR_VERSION < 3
6141 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6143 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6145 goto invalid_keyword_type;
6147 for (name = first_kw_arg; *name; name++) {
6148 #if PY_MAJOR_VERSION >= 3
6149 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6150 PyUnicode_Compare(**name, key) == 0) break;
6152 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6153 _PyString_Eq(**name, key)) break;
6157 values[name-argnames] = value;
6159 /* unexpected keyword found */
6160 for (name=argnames; name != first_kw_arg; name++) {
6161 if (**name == key) goto arg_passed_twice;
6162 #if PY_MAJOR_VERSION >= 3
6163 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6164 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6166 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6167 _PyString_Eq(**name, key)) goto arg_passed_twice;
6171 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6173 goto invalid_keyword;
6181 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6183 invalid_keyword_type:
6184 PyErr_Format(PyExc_TypeError,
6185 "%s() keywords must be strings", function_name);
6188 PyErr_Format(PyExc_TypeError,
6189 #if PY_MAJOR_VERSION < 3
6190 "%s() got an unexpected keyword argument '%s'",
6191 function_name, PyString_AsString(key));
6193 "%s() got an unexpected keyword argument '%U'",
6194 function_name, key);
6201 #------------------------------------------------------------------------------------
6203 traceback_utility_code = UtilityCode(
6205 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6208 #include "compile.h"
6209 #include "frameobject.h"
6210 #include "traceback.h"
6212 static void __Pyx_AddTraceback(const char *funcname) {
6213 PyObject *py_srcfile = 0;
6214 PyObject *py_funcname = 0;
6215 PyObject *py_globals = 0;
6216 PyCodeObject *py_code = 0;
6217 PyFrameObject *py_frame = 0;
6219 #if PY_MAJOR_VERSION < 3
6220 py_srcfile = PyString_FromString(%(FILENAME)s);
6222 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6224 if (!py_srcfile) goto bad;
6226 #if PY_MAJOR_VERSION < 3
6227 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6229 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6233 #if PY_MAJOR_VERSION < 3
6234 py_funcname = PyString_FromString(funcname);
6236 py_funcname = PyUnicode_FromString(funcname);
6239 if (!py_funcname) goto bad;
6240 py_globals = PyModule_GetDict(%(GLOBALS)s);
6241 if (!py_globals) goto bad;
6242 py_code = PyCode_New(
6243 0, /*int argcount,*/
6244 #if PY_MAJOR_VERSION >= 3
6245 0, /*int kwonlyargcount,*/
6248 0, /*int stacksize,*/
6250 %(EMPTY_BYTES)s, /*PyObject *code,*/
6251 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6252 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6253 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6254 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6255 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6256 py_srcfile, /*PyObject *filename,*/
6257 py_funcname, /*PyObject *name,*/
6258 %(LINENO)s, /*int firstlineno,*/
6259 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6261 if (!py_code) goto bad;
6262 py_frame = PyFrame_New(
6263 PyThreadState_GET(), /*PyThreadState *tstate,*/
6264 py_code, /*PyCodeObject *code,*/
6265 py_globals, /*PyObject *globals,*/
6266 0 /*PyObject *locals*/
6268 if (!py_frame) goto bad;
6269 py_frame->f_lineno = %(LINENO)s;
6270 PyTraceBack_Here(py_frame);
6272 Py_XDECREF(py_srcfile);
6273 Py_XDECREF(py_funcname);
6274 Py_XDECREF(py_code);
6275 Py_XDECREF(py_frame);
6278 'FILENAME': Naming.filename_cname,
6279 'LINENO': Naming.lineno_cname,
6280 'CFILENAME': Naming.cfilenm_cname,
6281 'CLINENO': Naming.clineno_cname,
6282 'GLOBALS': Naming.module_cname,
6283 'EMPTY_TUPLE' : Naming.empty_tuple,
6284 'EMPTY_BYTES' : Naming.empty_bytes,
6287 #------------------------------------------------------------------------------------
6289 unraisable_exception_utility_code = UtilityCode(
6291 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6294 static void __Pyx_WriteUnraisable(const char *name) {
6295 PyObject *old_exc, *old_val, *old_tb;
6297 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6298 #if PY_MAJOR_VERSION < 3
6299 ctx = PyString_FromString(name);
6301 ctx = PyUnicode_FromString(name);
6303 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6305 PyErr_WriteUnraisable(Py_None);
6307 PyErr_WriteUnraisable(ctx);
6312 requires=[restore_exception_utility_code])
6314 #------------------------------------------------------------------------------------
6316 set_vtable_utility_code = UtilityCode(
6318 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6321 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6322 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6323 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6325 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6329 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6339 #------------------------------------------------------------------------------------
6341 get_vtable_utility_code = UtilityCode(
6343 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6346 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6347 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6350 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6351 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6353 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6355 if (!*(void **)vtabptr)
6365 #------------------------------------------------------------------------------------
6367 init_string_tab_utility_code = UtilityCode(
6369 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6372 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6374 #if PY_MAJOR_VERSION < 3
6375 if (t->is_unicode) {
6376 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6377 } else if (t->intern) {
6378 *t->p = PyString_InternFromString(t->s);
6380 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6382 #else /* Python 3+ has unicode identifiers */
6383 if (t->is_unicode | t->is_str) {
6385 *t->p = PyUnicode_InternFromString(t->s);
6386 } else if (t->encoding) {
6387 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6389 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6392 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6403 #------------------------------------------------------------------------------------
6405 force_init_threads_utility_code = UtilityCode(
6407 #ifndef __PYX_FORCE_INIT_THREADS
6408 #if PY_VERSION_HEX < 0x02040200
6409 #define __PYX_FORCE_INIT_THREADS 1
6411 #define __PYX_FORCE_INIT_THREADS 0
6416 #------------------------------------------------------------------------------------
6418 # Note that cPython ignores PyTrace_EXCEPTION,
6419 # but maybe some other profilers don't.
6421 profile_utility_code = UtilityCode(proto="""
6422 #ifndef CYTHON_PROFILE
6423 #define CYTHON_PROFILE 1
6426 #ifndef CYTHON_PROFILE_REUSE_FRAME
6427 #define CYTHON_PROFILE_REUSE_FRAME 0
6432 #include "compile.h"
6433 #include "frameobject.h"
6434 #include "traceback.h"
6436 #if CYTHON_PROFILE_REUSE_FRAME
6437 #define CYTHON_FRAME_MODIFIER static
6438 #define CYTHON_FRAME_DEL
6440 #define CYTHON_FRAME_MODIFIER
6441 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6444 #define __Pyx_TraceDeclarations \\
6445 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6446 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6447 int __Pyx_use_tracing = 0;
6449 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6450 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6451 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6454 #define __Pyx_TraceException() \\
6455 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6456 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6458 PyThreadState_GET()->c_profilefunc( \\
6459 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6460 Py_DECREF(exc_info); \\
6464 #define __Pyx_TraceReturn(result) \\
6465 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6466 PyThreadState_GET()->c_profilefunc( \\
6467 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6468 CYTHON_FRAME_DEL; \\
6471 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6472 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6476 #define __Pyx_TraceDeclarations
6477 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6478 #define __Pyx_TraceException()
6479 #define __Pyx_TraceReturn(result)
6481 #endif /* CYTHON_PROFILE */
6484 "FRAME": Naming.frame_cname,
6485 "FRAME_CODE": Naming.frame_code_cname,
6491 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6492 PyFrameObject** frame,
6493 const char *funcname,
6494 const char *srcfile,
6496 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6497 if (*code == NULL) {
6498 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6499 if (*code == NULL) return 0;
6501 *frame = PyFrame_New(
6502 PyThreadState_GET(), /*PyThreadState *tstate*/
6503 *code, /*PyCodeObject *code*/
6504 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6505 0 /*PyObject *locals*/
6507 if (*frame == NULL) return 0;
6510 (*frame)->f_tstate = PyThreadState_GET();
6512 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6515 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6516 PyObject *py_srcfile = 0;
6517 PyObject *py_funcname = 0;
6518 PyCodeObject *py_code = 0;
6520 #if PY_MAJOR_VERSION < 3
6521 py_funcname = PyString_FromString(funcname);
6522 py_srcfile = PyString_FromString(srcfile);
6524 py_funcname = PyUnicode_FromString(funcname);
6525 py_srcfile = PyUnicode_FromString(srcfile);
6527 if (!py_funcname | !py_srcfile) goto bad;
6529 py_code = PyCode_New(
6530 0, /*int argcount,*/
6531 #if PY_MAJOR_VERSION >= 3
6532 0, /*int kwonlyargcount,*/
6535 0, /*int stacksize,*/
6537 %(EMPTY_BYTES)s, /*PyObject *code,*/
6538 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6539 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6540 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6541 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6542 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6543 py_srcfile, /*PyObject *filename,*/
6544 py_funcname, /*PyObject *name,*/
6545 firstlineno, /*int firstlineno,*/
6546 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6550 Py_XDECREF(py_srcfile);
6551 Py_XDECREF(py_funcname);
6556 #endif /* CYTHON_PROFILE */
6558 'EMPTY_TUPLE' : Naming.empty_tuple,
6559 'EMPTY_BYTES' : Naming.empty_bytes,
6560 "MODULE": Naming.module_cname,