3 # Pyrex - Parse tree nodes
8 cython.declare(sys=object, os=object, time=object, copy=object,
9 Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10 py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11 StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12 CppClassScope=object, UtilityCode=object, EncodedString=object,
13 absolute_path_length=cython.Py_ssize_t)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode, ClosureTempAllocator
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
32 absolute_path_length = 0
34 def relative_position(pos):
36 We embed the relative filename in the generated C file, since we
37 don't want to have to regnerate and compile all the source code
38 whenever the Python install directory moves (which could happen,
39 e.g,. when distributing binaries.)
42 a position tuple -- (absolute filename, line number column position)
50 global absolute_path_length
51 if absolute_path_length==0:
52 absolute_path_length = len(os.path.abspath(os.getcwd()))
53 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
63 # make sure we can encode the filename in the docstring encoding
64 # otherwise make the docstring a unicode string
65 encoding = docstring.encoding
66 if encoding is not None:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
86 if len(args) > 1 and isinstance(args[1], CCodeWriter):
87 # here we annotate the code with this function call
88 # but only if new code is generated
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
111 class VerboseCodeWriter(type):
112 # Set this as a metaclass to trace function calls in code.
113 # This slows down code generation and makes much larger files.
114 def __new__(cls, name, bases, attrs):
116 for mname, m in attrs.items():
117 if isinstance(m, FunctionType):
118 attrs[mname] = write_func_call(m)
119 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
134 # All descandants should set child_attrs to a list of the attributes
135 # containing nodes considered "children" in the tree. Each such attribute
136 # can either contain a single node or a list of nodes. See Visitor.py.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
159 def clone_node(self):
160 """Clone the node. This is defined as a shallow copy, except for member lists
161 amongst the child attributes (from get_child_accessors) which are also
162 copied. Lists containing child nodes are thus seen as a way for the node
163 to hold multiple children directly; the list is not treated as a seperate
164 level in the tree."""
165 result = copy.copy(self)
166 for attrname in result.child_attrs:
167 value = getattr(result, attrname)
168 if isinstance(value, list):
169 setattr(result, attrname, [x for x in value])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
181 # (1) analyse_declarations
182 # Make symbol table entries for all declarations at the current
183 # level, both explicit (def, cdef, etc.) and implicit (assignment
184 # to an otherwise undeclared name).
186 # (2) analyse_expressions
187 # Determine the result types of expressions and fill in the
188 # 'type' attribute of each ExprNode. Insert coercion nodes into the
189 # tree where needed to convert to and from Python objects.
190 # Allocate temporary locals for intermediate results. Fill
191 # in the 'result_code' attribute of each ExprNode with a C code
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
249 def dump_child(x, level):
250 if isinstance(x, Node):
251 return x.dump(level, filter_out, cutoff-1, encountered)
252 elif isinstance(x, list):
253 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
263 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264 for key, value in attrs:
265 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
266 res += "%s>" % indent
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
296 def generate_function_definitions(self, env, code):
297 env_old = env.directives
298 code_old = code.globalstate.directives
299 code.globalstate.directives = self.directives
300 self.body.generate_function_definitions(env, code)
301 env.directives = env_old
302 code.globalstate.directives = code_old
304 def generate_execution_code(self, code):
305 old = code.globalstate.directives
306 code.globalstate.directives = self.directives
307 self.body.generate_execution_code(code)
308 code.globalstate.directives = old
310 def annotate(self, code):
311 old = code.globalstate.directives
312 code.globalstate.directives = self.directives
313 self.body.annotate(code)
314 code.globalstate.directives = old
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
319 def generate_cached_builtins_decls(self, env, code):
320 entries = env.global_scope().undeclared_cached_builtins
321 for entry in entries:
322 code.globalstate.add_cached_builtin_decl(entry)
325 def generate_lambda_definitions(self, env, code):
326 for node in env.lambda_defs:
327 node.generate_function_definitions(env, code)
329 class StatListNode(Node):
330 # stats a list of StatNode
332 child_attrs = ["stats"]
334 def create_analysed(pos, env, *args, **kw):
335 node = StatListNode(pos, *args, **kw)
336 return node # No node-specific analysis necesarry
337 create_analysed = staticmethod(create_analysed)
339 def analyse_control_flow(self, env):
340 for stat in self.stats:
341 stat.analyse_control_flow(env)
343 def analyse_declarations(self, env):
344 #print "StatListNode.analyse_declarations" ###
345 for stat in self.stats:
346 stat.analyse_declarations(env)
348 def analyse_expressions(self, env):
349 #print "StatListNode.analyse_expressions" ###
350 for stat in self.stats:
351 stat.analyse_expressions(env)
353 def generate_function_definitions(self, env, code):
354 #print "StatListNode.generate_function_definitions" ###
355 for stat in self.stats:
356 stat.generate_function_definitions(env, code)
358 def generate_execution_code(self, code):
359 #print "StatListNode.generate_execution_code" ###
360 for stat in self.stats:
361 code.mark_pos(stat.pos)
362 stat.generate_execution_code(code)
364 def annotate(self, code):
365 for stat in self.stats:
369 class StatNode(Node):
371 # Code generation for statements is split into the following subphases:
373 # (1) generate_function_definitions
374 # Emit C code for the definitions of any structs,
375 # unions, enums and functions defined in the current
378 # (2) generate_execution_code
379 # Emit C code for executable statements.
382 def generate_function_definitions(self, env, code):
385 def generate_execution_code(self, code):
386 raise InternalError("generate_execution_code not implemented for %s" % \
387 self.__class__.__name__)
390 class CDefExternNode(StatNode):
391 # include_file string or None
394 child_attrs = ["body"]
396 def analyse_declarations(self, env):
397 if self.include_file:
398 env.add_include_file(self.include_file)
399 old_cinclude_flag = env.in_cinclude
401 self.body.analyse_declarations(env)
402 env.in_cinclude = old_cinclude_flag
404 def analyse_expressions(self, env):
407 def generate_execution_code(self, code):
410 def annotate(self, code):
411 self.body.annotate(code)
414 class CDeclaratorNode(Node):
415 # Part of a C declaration.
417 # Processing during analyse_declarations phase:
420 # Returns (name, type) pair where name is the
421 # CNameDeclaratorNode of the name being declared
422 # and type is the type it is being declared as.
424 # calling_convention string Calling convention of CFuncDeclaratorNode
425 # for which this is a base
429 calling_convention = ""
432 class CNameDeclaratorNode(CDeclaratorNode):
433 # name string The Pyrex name being declared
434 # cname string or None C name, if specified
435 # default ExprNode or None the value assigned on declaration
437 child_attrs = ['default']
441 def analyse(self, base_type, env, nonempty = 0):
442 if nonempty and self.name == '':
443 # May have mistaken the name for the type.
444 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
445 error(self.pos, "Missing argument name")
446 elif base_type.is_void:
447 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
449 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
450 base_type = py_object_type
451 self.type = base_type
452 return self, base_type
454 class CPtrDeclaratorNode(CDeclaratorNode):
455 # base CDeclaratorNode
457 child_attrs = ["base"]
459 def analyse(self, base_type, env, nonempty = 0):
460 if base_type.is_pyobject:
462 "Pointer base type cannot be a Python object")
463 ptr_type = PyrexTypes.c_ptr_type(base_type)
464 return self.base.analyse(ptr_type, env, nonempty = nonempty)
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Reference base type cannot be a Python object")
475 ref_type = PyrexTypes.c_ref_type(base_type)
476 return self.base.analyse(ref_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
485 if base_type.is_cpp_class:
486 from ExprNodes import TupleNode
487 if isinstance(self.dimension, TupleNode):
488 args = self.dimension.args
490 args = self.dimension,
491 values = [v.analyse_as_type(env) for v in args]
493 ix = values.index(None)
494 error(args[ix].pos, "Template parameter not a type.")
496 base_type = base_type.specialize_here(self.pos, values)
497 return self.base.analyse(base_type, env, nonempty = nonempty)
499 self.dimension.analyse_const_expression(env)
500 if not self.dimension.type.is_int:
501 error(self.dimension.pos, "Array dimension not integer")
502 size = self.dimension.get_constant_c_result_code()
511 if not base_type.is_complete():
513 "Array element type '%s' is incomplete" % base_type)
514 if base_type.is_pyobject:
516 "Array element cannot be a Python object")
517 if base_type.is_cfunction:
519 "Array element cannot be a function")
520 array_type = PyrexTypes.c_array_type(base_type, size)
521 return self.base.analyse(array_type, env, nonempty = nonempty)
524 class CFuncDeclaratorNode(CDeclaratorNode):
525 # base CDeclaratorNode
526 # args [CArgDeclNode]
527 # has_varargs boolean
528 # exception_value ConstNode
529 # exception_check boolean True if PyErr_Occurred check needed
530 # nogil boolean Can be called without gil
531 # with_gil boolean Acquire gil around function body
533 child_attrs = ["base", "args", "exception_value"]
536 optional_arg_count = 0
538 def analyse(self, return_type, env, nonempty = 0):
542 for i, arg_node in enumerate(self.args):
543 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544 is_self_arg = (i == 0 and env.is_c_class_scope))
545 name = name_declarator.name
546 if name_declarator.cname:
548 "Function argument cannot have C name specification")
549 # Turn *[] argument into **
551 type = PyrexTypes.c_ptr_type(type.base_type)
552 # Catch attempted C-style func(void) decl
554 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
555 func_type_args.append(
556 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
558 self.optional_arg_count += 1
559 elif self.optional_arg_count:
560 error(self.pos, "Non-default argument follows default argument")
562 if self.optional_arg_count:
563 scope = StructOrUnionScope()
564 arg_count_member = '%sn' % Naming.pyrex_prefix
565 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
566 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
567 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
568 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
569 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
574 cname = struct_cname)
575 self.op_args_struct.defined_in_pxd = 1
576 self.op_args_struct.used = 1
580 if self.exception_check == '+':
581 env.add_include_file('stdexcept')
582 if return_type.is_pyobject \
583 and (self.exception_value or self.exception_check) \
584 and self.exception_check != '+':
586 "Exception clause not allowed for function returning Python object")
588 if self.exception_value:
589 self.exception_value.analyse_const_expression(env)
590 if self.exception_check == '+':
591 self.exception_value.analyse_types(env)
592 exc_val_type = self.exception_value.type
593 if not exc_val_type.is_error and \
594 not exc_val_type.is_pyobject and \
595 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
596 error(self.exception_value.pos,
597 "Exception value must be a Python exception or cdef function with no arguments.")
598 exc_val = self.exception_value
600 self.exception_value = self.exception_value.coerce_to(return_type, env)
601 if self.exception_value.analyse_const_expression(env):
602 exc_val = self.exception_value.get_constant_c_result_code()
604 raise InternalError("get_constant_c_result_code not implemented for %s" %
605 self.exception_value.__class__.__name__)
606 if not return_type.assignable_from(self.exception_value.type):
607 error(self.exception_value.pos,
608 "Exception value incompatible with function return type")
609 exc_check = self.exception_check
610 if return_type.is_array:
612 "Function cannot return an array")
613 if return_type.is_cfunction:
615 "Function cannot return a function")
616 func_type = PyrexTypes.CFuncType(
617 return_type, func_type_args, self.has_varargs,
618 optional_arg_count = self.optional_arg_count,
619 exception_value = exc_val, exception_check = exc_check,
620 calling_convention = self.base.calling_convention,
621 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
622 if self.optional_arg_count:
623 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
624 callspec = env.directives['callspec']
626 current = func_type.calling_convention
627 if current and current != callspec:
628 error(self.pos, "cannot have both '%s' and '%s' "
629 "calling conventions" % (current, callspec))
630 func_type.calling_convention = callspec
631 return self.base.analyse(func_type, env)
634 class CArgDeclNode(Node):
635 # Item in a function declaration argument list.
637 # base_type CBaseTypeNode
638 # declarator CDeclaratorNode
639 # not_none boolean Tagged with 'not None'
640 # or_none boolean Tagged with 'or None'
641 # accept_none boolean Resolved boolean for not_none/or_none
642 # default ExprNode or None
643 # default_value PyObjectConst constant for default value
644 # annotation ExprNode or None Py3 function arg annotation
645 # is_self_arg boolean Is the "self" arg of an extension type method
646 # is_type_arg boolean Is the "class" arg of an extension type classmethod
647 # is_kw_only boolean Is a keyword-only argument
649 child_attrs = ["base_type", "declarator", "default"]
655 name_declarator = None
659 def analyse(self, env, nonempty = 0, is_self_arg = False):
661 self.base_type.is_self_arg = self.is_self_arg = True
662 if self.type is None:
663 # The parser may missinterpret names as types...
665 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
667 self.declarator.name = self.base_type.name
668 self.base_type.name = None
669 self.base_type.is_basic_c_type = False
672 could_be_name = False
673 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
674 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
675 self.declarator.name = self.base_type.arg_name
676 # The parser is unable to resolve the ambiguity of [] as part of the
677 # type (e.g. in buffers) or empty declarator (as with arrays).
678 # This is only arises for empty multi-dimensional arrays.
679 if (base_type.is_array
680 and isinstance(self.base_type, TemplatedTypeNode)
681 and isinstance(self.declarator, CArrayDeclaratorNode)):
682 declarator = self.declarator
683 while isinstance(declarator.base, CArrayDeclaratorNode):
684 declarator = declarator.base
685 declarator.base = self.base_type.array_declarator
686 base_type = base_type.base_type
687 return self.declarator.analyse(base_type, env, nonempty = nonempty)
689 return self.name_declarator, self.type
691 def calculate_default_value_code(self, code):
692 if self.default_value is None:
694 if self.default.is_literal:
695 # will not output any code, just assign the result_code
696 self.default.generate_evaluation_code(code)
697 return self.type.cast_code(self.default.result())
698 self.default_value = code.get_argument_default_const(self.type)
699 return self.default_value
701 def annotate(self, code):
703 self.default.annotate(code)
706 class CBaseTypeNode(Node):
707 # Abstract base class for C base type nodes.
709 # Processing during analyse_declarations phase:
716 def analyse_as_type(self, env):
717 return self.analyse(env)
719 class CAnalysedBaseTypeNode(Node):
724 def analyse(self, env, could_be_name = False):
727 class CSimpleBaseTypeNode(CBaseTypeNode):
729 # module_path [string] Qualifying name components
730 # is_basic_c_type boolean
734 # is_self_arg boolean Is self argument of C method
735 # ##is_type_arg boolean Is type argument of class method
738 arg_name = None # in case the argument name was interpreted as a type
740 def analyse(self, env, could_be_name = False):
741 # Return type descriptor.
742 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
744 if self.is_basic_c_type:
745 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
747 error(self.pos, "Unrecognised type modifier combination")
748 elif self.name == "object" and not self.module_path:
749 type = py_object_type
750 elif self.name is None:
751 if self.is_self_arg and env.is_c_class_scope:
752 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
753 type = env.parent_type
754 ## elif self.is_type_arg and env.is_c_class_scope:
755 ## type = Builtin.type_type
757 type = py_object_type
760 scope = env.find_imported_module(self.module_path, self.pos)
764 if scope.is_c_class_scope:
765 scope = scope.global_scope()
766 entry = scope.lookup(self.name)
767 if entry and entry.is_type:
770 if self.is_self_arg and env.is_c_class_scope:
771 type = env.parent_type
772 ## elif self.is_type_arg and env.is_c_class_scope:
773 ## type = Builtin.type_type
775 type = py_object_type
776 self.arg_name = self.name
779 if not self.name in self.templates:
780 error(self.pos, "'%s' is not a type identifier" % self.name)
781 type = PyrexTypes.TemplatePlaceholderType(self.name)
783 error(self.pos, "'%s' is not a type identifier" % self.name)
785 if not type.is_numeric or type.is_complex:
786 error(self.pos, "can only complexify c numeric types")
787 type = PyrexTypes.CComplexType(type)
788 type.create_declaration_utility_code(env)
789 elif type is Builtin.complex_type:
790 # Special case: optimise builtin complex type into C's
791 # double complex. The parser cannot do this (as for the
792 # normal scalar types) as the user may have redeclared the
793 # 'complex' type. Testing for the exact type here works.
794 type = PyrexTypes.c_double_complex_type
795 type.create_declaration_utility_code(env)
800 return PyrexTypes.error_type
802 class CNestedBaseTypeNode(CBaseTypeNode):
803 # For C++ classes that live inside other C++ classes.
806 # base_type CBaseTypeNode
808 child_attrs = ['base_type']
810 def analyse(self, env, could_be_name = None):
811 base_type = self.base_type.analyse(env)
812 if base_type is PyrexTypes.error_type:
813 return PyrexTypes.error_type
814 if not base_type.is_cpp_class:
815 error(self.pos, "'%s' is not a valid type scope" % base_type)
816 return PyrexTypes.error_type
817 type_entry = base_type.scope.lookup_here(self.name)
818 if not type_entry or not type_entry.is_type:
819 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
820 return PyrexTypes.error_type
821 return type_entry.type
823 class TemplatedTypeNode(CBaseTypeNode):
825 # positional_args [ExprNode] List of positional arguments
826 # keyword_args DictNode Keyword arguments
827 # base_type_node CBaseTypeNode
830 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
833 child_attrs = ["base_type_node", "positional_args",
834 "keyword_args", "dtype_node"]
840 def analyse(self, env, could_be_name = False, base_type = None):
841 if base_type is None:
842 base_type = self.base_type_node.analyse(env)
843 if base_type.is_error: return base_type
845 if base_type.is_cpp_class:
847 if self.keyword_args and self.keyword_args.key_value_pairs:
848 error(self.pos, "c++ templates cannot take keyword arguments");
849 self.type = PyrexTypes.error_type
852 for template_node in self.positional_args:
853 type = template_node.analyse_as_type(env)
855 error(template_node.pos, "unknown type in template argument")
857 template_types.append(type)
858 self.type = base_type.specialize_here(self.pos, template_types)
860 elif base_type.is_pyobject:
864 options = Buffer.analyse_buffer_options(
867 self.positional_args,
869 base_type.buffer_defaults)
871 if sys.version_info[0] < 3:
872 # Py 2.x enforces byte strings as keyword arguments ...
873 options = dict([ (name.encode('ASCII'), value)
874 for name, value in options.items() ])
876 self.type = PyrexTypes.BufferType(base_type, **options)
880 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
881 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
882 error(self.pos, "invalid array declaration")
883 self.type = PyrexTypes.error_type
885 # It would be nice to merge this class with CArrayDeclaratorNode,
886 # but arrays are part of the declaration, not the type...
887 if not self.positional_args:
890 dimension = self.positional_args[0]
891 self.array_declarator = CArrayDeclaratorNode(self.pos,
892 base = empty_declarator,
893 dimension = dimension)
894 self.type = self.array_declarator.analyse(base_type, env)[1]
898 class CComplexBaseTypeNode(CBaseTypeNode):
899 # base_type CBaseTypeNode
900 # declarator CDeclaratorNode
902 child_attrs = ["base_type", "declarator"]
904 def analyse(self, env, could_be_name = False):
905 base = self.base_type.analyse(env, could_be_name)
906 _, type = self.declarator.analyse(base, env)
910 class CVarDefNode(StatNode):
911 # C variable definition or forward/extern function declaration.
913 # visibility 'private' or 'public' or 'extern'
914 # base_type CBaseTypeNode
915 # declarators [CDeclaratorNode]
919 # decorators [cython.locals(...)] or None
920 # directive_locals { string : NameNode } locals defined by cython.locals(...)
922 child_attrs = ["base_type", "declarators"]
925 directive_locals = {}
927 def analyse_declarations(self, env, dest_scope = None):
930 self.dest_scope = dest_scope
931 base_type = self.base_type.analyse(env)
933 # If the field is an external typedef, we cannot be sure about the type,
934 # so do conversion ourself rather than rely on the CPython mechanism (through
935 # a property; made in AnalyseDeclarationsTransform).
936 if (dest_scope.is_c_class_scope
937 and self.visibility in ('public', 'readonly')):
940 need_property = False
941 visibility = self.visibility
943 for declarator in self.declarators:
944 name_declarator, type = declarator.analyse(base_type, env)
945 if not type.is_complete():
946 if not (self.visibility == 'extern' and type.is_array):
947 error(declarator.pos,
948 "Variable type '%s' is incomplete" % type)
949 if self.visibility == 'extern' and type.is_pyobject:
950 error(declarator.pos,
951 "Python object cannot be declared extern")
952 name = name_declarator.name
953 cname = name_declarator.cname
955 error(declarator.pos, "Missing name in declaration.")
957 if type.is_cfunction:
958 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
959 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
961 if entry is not None:
962 entry.directive_locals = self.directive_locals
964 if self.directive_locals:
965 error(self.pos, "Decorators can only be followed by functions")
966 if self.in_pxd and self.visibility != 'extern':
968 "Only 'extern' C variable declaration allowed in .pxd file")
969 entry = dest_scope.declare_var(name, type, declarator.pos,
970 cname = cname, visibility = visibility, is_cdef = 1)
971 entry.needs_property = need_property
974 class CStructOrUnionDefNode(StatNode):
976 # cname string or None
977 # kind "struct" or "union"
978 # typedef_flag boolean
979 # visibility "public" or "private"
981 # attributes [CVarDefNode] or None
985 child_attrs = ["attributes"]
987 def analyse_declarations(self, env):
989 if self.visibility == 'extern' and self.packed:
990 error(self.pos, "Cannot declare extern struct as 'packed'")
991 if self.attributes is not None:
992 scope = StructOrUnionScope(self.name)
993 self.entry = env.declare_struct_or_union(
994 self.name, self.kind, scope, self.typedef_flag, self.pos,
995 self.cname, visibility = self.visibility, packed = self.packed)
996 if self.attributes is not None:
997 if self.in_pxd and not env.in_cinclude:
998 self.entry.defined_in_pxd = 1
999 for attr in self.attributes:
1000 attr.analyse_declarations(env, scope)
1001 if self.visibility != 'extern':
1002 need_typedef_indirection = False
1003 for attr in scope.var_entries:
1005 while type.is_array:
1006 type = type.base_type
1007 if type == self.entry.type:
1008 error(attr.pos, "Struct cannot contain itself as a member.")
1009 if self.typedef_flag:
1011 type = type.base_type
1012 if type == self.entry.type:
1013 need_typedef_indirection = True
1014 if need_typedef_indirection:
1015 # C can't handle typedef structs that refer to themselves.
1016 struct_entry = self.entry
1017 self.entry = env.declare_typedef(
1018 self.name, struct_entry.type, self.pos,
1019 cname = self.cname, visibility='ignore')
1020 struct_entry.type.typedef_flag = False
1021 # FIXME: this might be considered a hack ;-)
1022 struct_entry.cname = struct_entry.type.cname = \
1023 '_' + self.entry.type.typedef_cname
1025 def analyse_expressions(self, env):
1028 def generate_execution_code(self, code):
1032 class CppClassNode(CStructOrUnionDefNode):
1035 # cname string or None
1036 # visibility "extern"
1038 # attributes [CVarDefNode] or None
1040 # base_classes [string]
1041 # templates [string] or None
1043 def analyse_declarations(self, env):
1045 if self.attributes is not None:
1046 scope = CppClassScope(self.name, env)
1047 base_class_types = []
1048 for base_class_name in self.base_classes:
1049 base_class_entry = env.lookup(base_class_name)
1050 if base_class_entry is None:
1051 error(self.pos, "'%s' not found" % base_class_name)
1052 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1053 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1055 base_class_types.append(base_class_entry.type)
1056 if self.templates is None:
1057 template_types = None
1059 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1060 self.entry = env.declare_cpp_class(
1061 self.name, scope, self.pos,
1062 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1063 self.entry.is_cpp_class = 1
1064 if self.attributes is not None:
1065 if self.in_pxd and not env.in_cinclude:
1066 self.entry.defined_in_pxd = 1
1067 for attr in self.attributes:
1068 attr.analyse_declarations(scope)
1070 class CEnumDefNode(StatNode):
1071 # name string or None
1072 # cname string or None
1073 # items [CEnumDefItemNode]
1074 # typedef_flag boolean
1075 # visibility "public" or "private"
1079 child_attrs = ["items"]
1081 def analyse_declarations(self, env):
1082 self.entry = env.declare_enum(self.name, self.pos,
1083 cname = self.cname, typedef_flag = self.typedef_flag,
1084 visibility = self.visibility)
1085 if self.items is not None:
1086 if self.in_pxd and not env.in_cinclude:
1087 self.entry.defined_in_pxd = 1
1088 for item in self.items:
1089 item.analyse_declarations(env, self.entry)
1091 def analyse_expressions(self, env):
1094 def generate_execution_code(self, code):
1095 if self.visibility == 'public':
1096 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1097 for item in self.entry.enum_values:
1098 code.putln("%s = PyInt_FromLong(%s); %s" % (
1101 code.error_goto_if_null(temp, item.pos)))
1102 code.put_gotref(temp)
1103 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1104 Naming.module_cname,
1107 code.error_goto(item.pos)))
1108 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1109 code.funcstate.release_temp(temp)
1112 class CEnumDefItemNode(StatNode):
1114 # cname string or None
1115 # value ExprNode or None
1117 child_attrs = ["value"]
1119 def analyse_declarations(self, env, enum_entry):
1121 self.value.analyse_const_expression(env)
1122 if not self.value.type.is_int:
1123 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1124 self.value.analyse_const_expression(env)
1125 entry = env.declare_const(self.name, enum_entry.type,
1126 self.value, self.pos, cname = self.cname,
1127 visibility = enum_entry.visibility)
1128 enum_entry.enum_values.append(entry)
1131 class CTypeDefNode(StatNode):
1132 # base_type CBaseTypeNode
1133 # declarator CDeclaratorNode
1134 # visibility "public" or "private"
1137 child_attrs = ["base_type", "declarator"]
1139 def analyse_declarations(self, env):
1140 base = self.base_type.analyse(env)
1141 name_declarator, type = self.declarator.analyse(base, env)
1142 name = name_declarator.name
1143 cname = name_declarator.cname
1144 entry = env.declare_typedef(name, type, self.pos,
1145 cname = cname, visibility = self.visibility)
1146 if self.in_pxd and not env.in_cinclude:
1147 entry.defined_in_pxd = 1
1149 def analyse_expressions(self, env):
1151 def generate_execution_code(self, code):
1155 class FuncDefNode(StatNode, BlockNode):
1156 # Base class for function definition nodes.
1158 # return_type PyrexType
1159 # #filename string C name of filename string const
1160 # entry Symtab.Entry
1161 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1162 # needs_outer_scope boolean Whether or not this function requires outer scope
1163 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1167 needs_closure = False
1168 needs_outer_scope = False
1169 is_generator = False
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 code.put_declare_refcount_context()
1300 if not self.is_generator:
1301 self.generate_keyword_list(code)
1303 code.put_trace_declarations()
1304 # ----- Extern library function declarations
1305 lenv.generate_library_function_declarations(code)
1306 # ----- GIL acquisition
1307 acquire_gil = self.acquire_gil
1309 env.use_utility_code(force_init_threads_utility_code)
1310 code.putln("#ifdef WITH_THREAD")
1311 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1312 code.putln("#endif")
1313 # ----- set up refnanny
1315 code.put_setup_refcount_context(self.entry.name)
1316 # ----- Automatic lead-ins for certain special functions
1317 if is_getbuffer_slot:
1318 self.getbuffer_init(code)
1319 # ----- Create closure scope object
1320 if self.is_generator:
1321 code.putln("%s = (%s) %s;" % (
1322 Naming.cur_scope_cname,
1323 lenv.scope_class.type.declaration_code(''),
1325 gotref_code = code.insertion_point()
1327 elif self.needs_closure:
1328 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1329 Naming.cur_scope_cname,
1330 lenv.scope_class.type.declaration_code(''),
1331 lenv.scope_class.type.typeptr_cname,
1332 lenv.scope_class.type.typeptr_cname,
1333 Naming.empty_tuple))
1334 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1335 if is_getbuffer_slot:
1336 self.getbuffer_error_cleanup(code)
1338 code.put_finish_refcount_context()
1339 # FIXME: what if the error return value is a Python value?
1340 code.putln("return %s;" % self.error_value())
1342 code.put_gotref(Naming.cur_scope_cname)
1343 # Note that it is unsafe to decref the scope at this point.
1344 if self.needs_outer_scope and not self.is_generator:
1345 code.putln("%s = (%s)%s;" % (
1347 cenv.scope_class.type.declaration_code(''),
1349 if lenv.is_passthrough:
1350 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1351 elif self.needs_closure:
1352 # inner closures own a reference to their outer parent
1353 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1354 code.put_giveref(outer_scope_cname)
1355 # ----- Trace function call
1357 # this looks a bit late, but if we don't get here due to a
1358 # fatal error before hand, it's not really worth tracing
1359 code.put_trace_call(self.entry.name, self.pos)
1360 # ----- Fetch arguments
1361 if not self.is_generator:
1362 self.generate_preamble(env, code)
1363 if self.is_generator:
1364 code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
1365 resume_code = code.insertion_point()
1366 first_run_label = code.new_label('first_run')
1367 code.use_label(first_run_label)
1368 code.put_label(first_run_label)
1370 (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
1371 # -------------------------
1372 # ----- Function body -----
1373 # -------------------------
1374 self.body.generate_execution_code(code)
1376 if self.is_generator:
1377 code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
1379 # ----- Default return value
1381 if self.return_type.is_pyobject:
1382 #if self.return_type.is_extension_type:
1383 # lhs = "(PyObject *)%s" % Naming.retval_cname
1385 lhs = Naming.retval_cname
1386 code.put_init_to_py_none(lhs, self.return_type)
1388 val = self.return_type.default_value
1390 code.putln("%s = %s;" % (Naming.retval_cname, val))
1391 # ----- Error cleanup
1392 if code.error_label in code.labels_used:
1393 code.put_goto(code.return_label)
1394 code.put_label(code.error_label)
1395 for cname, type in code.funcstate.all_managed_temps():
1396 code.put_xdecref(cname, type)
1398 # Clean up buffers -- this calls a Python function
1399 # so need to save and restore error state
1400 buffers_present = len(lenv.buffer_entries) > 0
1402 code.globalstate.use_utility_code(restore_exception_utility_code)
1403 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1404 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1405 for entry in lenv.buffer_entries:
1406 Buffer.put_release_buffer_code(code, entry)
1407 #code.putln("%s = 0;" % entry.cname)
1408 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1410 err_val = self.error_value()
1411 exc_check = self.caller_will_check_exceptions()
1412 if err_val is not None or exc_check:
1413 # TODO: Fix exception tracing (though currently unused by cProfile).
1414 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1415 # code.put_trace_exception()
1416 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1418 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1419 % self.entry.qualified_name, 0)
1421 '__Pyx_WriteUnraisable("%s");' %
1422 self.entry.qualified_name)
1423 env.use_utility_code(unraisable_exception_utility_code)
1424 env.use_utility_code(restore_exception_utility_code)
1425 default_retval = self.return_type.default_value
1426 if err_val is None and default_retval:
1427 err_val = default_retval
1428 if err_val is not None:
1429 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1431 if is_getbuffer_slot:
1432 self.getbuffer_error_cleanup(code)
1434 # If we are using the non-error cleanup section we should
1435 # jump past it if we have an error. The if-test below determine
1436 # whether this section is used.
1437 if buffers_present or is_getbuffer_slot:
1438 code.put_goto(code.return_from_error_cleanup_label)
1441 # ----- Non-error return cleanup
1442 code.put_label(code.return_label)
1443 for entry in lenv.buffer_entries:
1445 Buffer.put_release_buffer_code(code, entry)
1446 if is_getbuffer_slot:
1447 self.getbuffer_normal_cleanup(code)
1448 # ----- Return cleanup for both error and no-error return
1449 code.put_label(code.return_from_error_cleanup_label)
1450 if not Options.init_local_none:
1451 for entry in lenv.var_entries:
1452 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1453 entry.xdecref_cleanup = 1
1455 for entry in lenv.var_entries:
1456 if entry.type.is_pyobject:
1457 if entry.used and not entry.in_closure:
1458 code.put_var_decref(entry)
1459 # Decref any increfed args
1460 for entry in lenv.arg_entries:
1461 if entry.type.is_pyobject:
1462 if entry.assignments and not entry.in_closure:
1463 code.put_var_decref(entry)
1464 if self.needs_closure and not self.is_generator:
1465 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1466 if self.is_generator:
1467 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
1470 # This code is duplicated in ModuleNode.generate_module_init_func
1472 default_retval = self.return_type.default_value
1473 err_val = self.error_value()
1474 if err_val is None and default_retval:
1475 err_val = default_retval
1476 if self.return_type.is_pyobject:
1477 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1479 if self.entry.is_special and self.entry.name == "__hash__":
1480 # Returning -1 for __hash__ is supposed to signal an error
1481 # We do as Python instances and coerce -1 into -2.
1482 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1483 Naming.retval_cname, Naming.retval_cname))
1486 if self.return_type.is_pyobject:
1487 code.put_trace_return(Naming.retval_cname)
1489 code.put_trace_return("Py_None")
1491 code.put_finish_refcount_context()
1494 code.putln("#ifdef WITH_THREAD")
1495 code.putln("PyGILState_Release(_save);")
1496 code.putln("#endif")
1498 if not self.return_type.is_void:
1499 code.putln("return %s;" % Naming.retval_cname)
1503 if preprocessor_guard:
1504 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1505 # ----- Go back and insert temp variable declarations
1506 tempvardecl_code.put_temp_declarations(code.funcstate)
1507 # ----- Generator resume code
1508 if self.is_generator:
1509 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
1510 resume_code.putln("case 0: goto %s;" % first_run_label)
1511 for yield_expr in self.yields:
1512 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
1513 resume_code.putln("default: /* CPython raises the right error here */");
1514 resume_code.putln("return NULL;");
1515 resume_code.putln("}");
1516 # ----- Python version
1517 code.exit_cfunc_scope()
1519 self.py_func.generate_function_definitions(env, code)
1520 self.generate_wrapper_functions(code)
1522 if self.is_generator:
1523 self.generator.generate_function_body(self.local_scope, code)
1525 def generate_preamble(self, env, code):
1526 """Parse arguments and prepare scope"""
1529 lenv = self.local_scope
1531 self.generate_argument_parsing_code(env, code)
1532 # If an argument is assigned to in the body, we must
1533 # incref it to properly keep track of refcounts.
1534 for entry in lenv.arg_entries:
1535 if entry.type.is_pyobject:
1536 if entry.assignments and not entry.in_closure:
1537 code.put_var_incref(entry)
1538 # ----- Initialise local variables
1539 for entry in lenv.var_entries:
1540 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1541 code.put_init_var_to_py_none(entry)
1542 # ----- Initialise local buffer auxiliary variables
1543 for entry in lenv.var_entries + lenv.arg_entries:
1544 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1545 code.putln("%s.buf = NULL;" %
1546 entry.buffer_aux.buffer_info_var.cname)
1547 # ----- Check and convert arguments
1548 self.generate_argument_type_tests(code)
1549 # ----- Acquire buffer arguments
1550 for entry in lenv.arg_entries:
1551 if entry.type.is_buffer:
1552 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1554 def declare_argument(self, env, arg):
1555 if arg.type.is_void:
1556 error(arg.pos, "Invalid use of 'void'")
1557 elif not arg.type.is_complete() and not arg.type.is_array:
1559 "Argument type '%s' is incomplete" % arg.type)
1560 return env.declare_arg(arg.name, arg.type, arg.pos)
1562 def generate_arg_type_test(self, arg, code):
1563 # Generate type test for one argument.
1564 if arg.type.typeobj_is_available():
1565 code.globalstate.use_utility_code(arg_type_test_utility_code)
1566 typeptr_cname = arg.type.typeptr_cname
1567 arg_code = "((PyObject *)%s)" % arg.entry.cname
1569 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1574 arg.type.is_builtin_type,
1575 code.error_goto(arg.pos)))
1577 error(arg.pos, "Cannot test type of extern C class "
1578 "without type object name specification")
1580 def generate_arg_none_check(self, arg, code):
1581 # Generate None check for one argument.
1582 code.globalstate.use_utility_code(arg_type_test_utility_code)
1583 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1584 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1586 code.error_goto(arg.pos)))
1589 def generate_wrapper_functions(self, code):
1592 def generate_execution_code(self, code):
1593 # Evaluate and store argument default values
1594 for arg in self.args:
1595 default = arg.default
1597 if not default.is_literal:
1598 default.generate_evaluation_code(code)
1599 default.make_owned_reference(code)
1600 result = default.result_as(arg.type)
1603 arg.calculate_default_value_code(code),
1605 if arg.type.is_pyobject:
1606 code.put_giveref(default.result())
1607 default.generate_post_assignment_code(code)
1608 default.free_temps(code)
1609 # For Python class methods, create and store function object
1611 self.assmt.generate_execution_code(code)
1614 # Special code for the __getbuffer__ function
1616 def getbuffer_init(self, code):
1617 info = self.local_scope.arg_entries[1].cname
1618 # Python 3.0 betas have a bug in memoryview which makes it call
1619 # getbuffer with a NULL parameter. For now we work around this;
1620 # the following line should be removed when this bug is fixed.
1621 code.putln("if (%s == NULL) return 0;" % info)
1622 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1623 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1625 def getbuffer_error_cleanup(self, code):
1626 info = self.local_scope.arg_entries[1].cname
1627 code.put_gotref("%s->obj" % info)
1628 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1631 def getbuffer_normal_cleanup(self, code):
1632 info = self.local_scope.arg_entries[1].cname
1633 code.putln("if (%s->obj == Py_None) {" % info)
1634 code.put_gotref("Py_None")
1635 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1638 class CFuncDefNode(FuncDefNode):
1639 # C function definition.
1641 # modifiers ['inline']
1642 # visibility 'private' or 'public' or 'extern'
1643 # base_type CBaseTypeNode
1644 # declarator CDeclaratorNode
1647 # decorators [DecoratorNode] list of decorators
1649 # with_gil boolean Acquire GIL around body
1651 # py_func wrapper for calling from Python
1652 # overridable whether or not this is a cpdef function
1653 # inline_in_pxd whether this is an inline function in a pxd file
1655 child_attrs = ["base_type", "declarator", "body", "py_func"]
1657 inline_in_pxd = False
1659 directive_locals = {}
1661 def unqualified_name(self):
1662 return self.entry.name
1664 def analyse_declarations(self, env):
1665 self.directive_locals.update(env.directives['locals'])
1666 base_type = self.base_type.analyse(env)
1667 # The 2 here is because we need both function and argument names.
1668 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1669 if not type.is_cfunction:
1671 "Suite attached to non-function declaration")
1672 # Remember the actual type according to the function header
1673 # written here, because the type in the symbol table entry
1674 # may be different if we're overriding a C method inherited
1675 # from the base type of an extension type.
1677 type.is_overridable = self.overridable
1678 declarator = self.declarator
1679 while not hasattr(declarator, 'args'):
1680 declarator = declarator.base
1681 self.args = declarator.args
1682 for formal_arg, type_arg in zip(self.args, type.args):
1683 formal_arg.type = type_arg.type
1684 formal_arg.name = type_arg.name
1685 formal_arg.cname = type_arg.cname
1686 name = name_declarator.name
1687 cname = name_declarator.cname
1688 self.entry = env.declare_cfunction(
1689 name, type, self.pos,
1690 cname = cname, visibility = self.visibility,
1691 defining = self.body is not None,
1692 api = self.api, modifiers = self.modifiers)
1693 self.entry.inline_func_in_pxd = self.inline_in_pxd
1694 self.return_type = type.return_type
1696 if self.overridable and not env.is_module_scope:
1697 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1698 # An error will be produced in the cdef function
1699 self.overridable = False
1701 if self.overridable:
1703 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1704 self.py_func = DefNode(pos = self.pos,
1705 name = self.entry.name,
1708 starstar_arg = None,
1710 body = py_func_body,
1712 self.py_func.is_module_scope = env.is_module_scope
1713 self.py_func.analyse_declarations(env)
1714 self.entry.as_variable = self.py_func.entry
1715 # Reset scope entry the above cfunction
1716 env.entries[name] = self.entry
1717 if not env.is_module_scope or Options.lookup_module_cpdef:
1718 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1719 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1720 self.create_local_scope(env)
1722 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1724 args = self.type.args
1725 if omit_optional_args:
1726 args = args[:len(args) - self.type.optional_arg_count]
1727 arg_names = [arg.name for arg in args]
1729 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1731 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1732 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1733 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1734 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)
1735 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1737 def declare_arguments(self, env):
1738 for arg in self.type.args:
1740 error(arg.pos, "Missing argument name")
1741 self.declare_argument(env, arg)
1743 def need_gil_acquisition(self, lenv):
1744 return self.type.with_gil
1746 def nogil_check(self, env):
1748 with_gil = type.with_gil
1749 if type.nogil and not with_gil:
1750 if type.return_type.is_pyobject:
1752 "Function with Python return type cannot be declared nogil")
1753 for entry in self.local_scope.var_entries:
1754 if entry.type.is_pyobject:
1755 error(self.pos, "Function declared nogil has Python locals or temporaries")
1757 def analyse_expressions(self, env):
1758 self.local_scope.directives = env.directives
1759 if self.py_func is not None:
1760 # this will also analyse the default values
1761 self.py_func.analyse_expressions(env)
1763 self.analyse_default_values(env)
1764 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1766 def needs_assignment_synthesis(self, env, code=None):
1769 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1772 visibility = self.entry.visibility
1773 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1774 arg_decls.append(arg.declaration_code())
1775 if with_dispatch and self.overridable:
1776 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1777 if type.optional_arg_count and with_opt_args:
1778 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1779 if type.has_varargs:
1780 arg_decls.append("...")
1782 arg_decls = ["void"]
1784 cname = self.entry.func_cname
1785 entity = type.function_header_code(cname, ', '.join(arg_decls))
1786 if visibility == 'public':
1787 dll_linkage = "DL_EXPORT"
1790 header = self.return_type.declaration_code(entity,
1791 dll_linkage = dll_linkage)
1792 if visibility == 'extern':
1793 storage_class = "%s " % Naming.extern_c_macro
1794 elif visibility == 'public':
1797 storage_class = "static "
1798 if 'inline' in self.modifiers:
1799 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1800 code.putln("%s%s %s {" % (
1802 ' '.join(self.modifiers).upper(), # macro forms
1805 def generate_argument_declarations(self, env, code):
1806 for arg in self.args:
1808 result = arg.calculate_default_value_code(code)
1809 code.putln('%s = %s;' % (
1810 arg.type.declaration_code(arg.cname), result))
1812 def generate_keyword_list(self, code):
1815 def generate_argument_parsing_code(self, env, code):
1817 if self.type.optional_arg_count:
1818 code.putln('if (%s) {' % Naming.optional_args_cname)
1819 for arg in self.args:
1821 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1822 declarator = arg.declarator
1823 while not hasattr(declarator, 'name'):
1824 declarator = declarator.base
1825 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1827 for _ in range(self.type.optional_arg_count):
1831 def generate_argument_conversion_code(self, code):
1834 def generate_argument_type_tests(self, code):
1835 # Generate type tests for args whose type in a parent
1836 # class is a supertype of the declared type.
1837 for arg in self.type.args:
1838 if arg.needs_type_test:
1839 self.generate_arg_type_test(arg, code)
1840 elif arg.type.is_pyobject and not arg.accept_none:
1841 self.generate_arg_none_check(arg, code)
1843 def error_value(self):
1844 if self.return_type.is_pyobject:
1848 return self.entry.type.exception_value
1850 def caller_will_check_exceptions(self):
1851 return self.entry.type.exception_check
1853 def generate_wrapper_functions(self, code):
1854 # If the C signature of a function has changed, we need to generate
1855 # wrappers to put in the slots here.
1858 func_type = entry.type
1859 while entry.prev_entry is not None:
1861 entry = entry.prev_entry
1862 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1864 self.generate_function_header(code,
1866 with_dispatch = entry.type.is_overridable,
1867 with_opt_args = entry.type.optional_arg_count,
1868 cname = entry.func_cname)
1869 if not self.return_type.is_void:
1871 args = self.type.args
1872 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1873 if entry.type.is_overridable:
1874 arglist.append(Naming.skip_dispatch_cname)
1875 elif func_type.is_overridable:
1877 if entry.type.optional_arg_count:
1878 arglist.append(Naming.optional_args_cname)
1879 elif func_type.optional_arg_count:
1880 arglist.append('NULL')
1881 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1885 class PyArgDeclNode(Node):
1886 # Argument which must be a Python object (used
1887 # for * and ** arguments).
1890 # entry Symtab.Entry
1891 # annotation ExprNode or None Py3 argument annotation
1894 def generate_function_definitions(self, env, code):
1895 self.entry.generate_function_definitions(env, code)
1897 class DecoratorNode(Node):
1900 # decorator NameNode or CallNode or AttributeNode
1901 child_attrs = ['decorator']
1904 class GeneratorWrapperNode(object):
1906 def __init__(self, def_node, func_cname=None, body_cname=None, header=None):
1907 self.def_node = def_node
1908 self.func_cname = func_cname
1909 self.body_cname = body_cname
1910 self.header = header
1912 def generate_function_body(self, env, code):
1913 code.mark_pos(self.def_node.pos)
1914 cenv = env.outer_scope # XXX: correct?
1915 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1916 cenv = cenv.outer_scope
1917 lenv = self.def_node.local_scope
1918 code.enter_cfunc_scope()
1920 code.putln('%s {' % self.header)
1921 code.put_declare_refcount_context()
1922 self.def_node.generate_keyword_list(code)
1923 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1925 code.put_setup_refcount_context(self.def_node.entry.name)
1926 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1927 Naming.cur_scope_cname,
1928 lenv.scope_class.type.declaration_code(''),
1929 lenv.scope_class.type.typeptr_cname,
1930 lenv.scope_class.type.typeptr_cname,
1931 Naming.empty_tuple))
1932 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1933 code.put_finish_refcount_context()
1934 code.putln("return NULL;");
1936 code.put_gotref(Naming.cur_scope_cname)
1938 if self.def_node.needs_outer_scope:
1939 outer_scope_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.outer_scope_cname)
1940 code.putln("%s = (%s)%s;" % (
1942 cenv.scope_class.type.declaration_code(''),
1944 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1945 code.put_giveref(outer_scope_cname)
1947 self.def_node.generate_preamble(env, code)
1949 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
1951 code.putln('%s.resume_label = 0;' % generator_cname)
1952 code.putln('%s.body = %s;' % (generator_cname, self.body_cname))
1953 code.put_giveref(Naming.cur_scope_cname)
1954 code.put_finish_refcount_context()
1955 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
1957 code.exit_cfunc_scope()
1959 class DefNode(FuncDefNode):
1960 # A Python function definition.
1962 # name string the Python name of the function
1963 # lambda_name string the internal name of a lambda 'function'
1964 # decorators [DecoratorNode] list of decorators
1965 # args [CArgDeclNode] formal arguments
1966 # star_arg PyArgDeclNode or None * argument
1967 # starstar_arg PyArgDeclNode or None ** argument
1968 # doc EncodedString or None
1970 # return_type_annotation
1971 # ExprNode or None the Py3 return type annotation
1973 # The following subnode is constructed internally
1974 # when the def statement is inside a Python class definition.
1976 # assmt AssignmentNode Function construction/assignment
1978 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1983 num_required_kw_args = 0
1984 reqd_kw_flags_cname = "0"
1987 return_type_annotation = None
1992 def __init__(self, pos, **kwds):
1993 FuncDefNode.__init__(self, pos, **kwds)
1995 for arg in self.args:
2002 self.num_kwonly_args = k
2003 self.num_required_kw_args = rk
2004 self.num_required_args = r
2006 def as_cfunction(self, cfunc=None, scope=None):
2008 error(self.star_arg.pos, "cdef function cannot have star argument")
2009 if self.starstar_arg:
2010 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
2013 for formal_arg in self.args:
2014 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
2015 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
2017 type = py_object_type,
2018 pos = formal_arg.pos))
2019 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
2021 has_varargs = False,
2022 exception_value = None,
2023 exception_check = False,
2026 is_overridable = True)
2027 cfunc = CVarDefNode(self.pos, type=cfunc_type)
2031 cfunc_type = cfunc.type
2032 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2033 error(self.pos, "wrong number of arguments")
2034 error(cfunc.pos, "previous declaration here")
2035 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2036 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2037 is_self_arg = (i == 0 and scope.is_c_class_scope))
2038 if type is None or type is PyrexTypes.py_object_type:
2039 formal_arg.type = type_arg.type
2040 formal_arg.name_declarator = name_declarator
2042 if cfunc_type.exception_value is None:
2043 exception_value = None
2045 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2046 declarator = CFuncDeclaratorNode(self.pos,
2047 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2049 has_varargs = False,
2050 exception_check = cfunc_type.exception_check,
2051 exception_value = exception_value,
2052 with_gil = cfunc_type.with_gil,
2053 nogil = cfunc_type.nogil)
2054 return CFuncDefNode(self.pos,
2056 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2057 declarator = declarator,
2060 overridable = cfunc_type.is_overridable,
2062 with_gil = cfunc_type.with_gil,
2063 nogil = cfunc_type.nogil,
2064 visibility = 'private',
2066 directive_locals = getattr(cfunc, 'directive_locals', {}))
2068 def analyse_declarations(self, env):
2069 self.is_classmethod = self.is_staticmethod = False
2071 for decorator in self.decorators:
2072 func = decorator.decorator
2074 self.is_classmethod |= func.name == 'classmethod'
2075 self.is_staticmethod |= func.name == 'staticmethod'
2077 if self.is_classmethod and env.lookup_here('classmethod'):
2078 # classmethod() was overridden - not much we can do here ...
2079 self.is_classmethod = False
2080 if self.is_staticmethod and env.lookup_here('staticmethod'):
2081 # staticmethod() was overridden - not much we can do here ...
2082 self.is_staticmethod = False
2084 if self.name == '__new__':
2085 self.is_staticmethod = 1
2087 self.analyse_argument_types(env)
2088 if self.name == '<lambda>':
2089 self.declare_lambda_function(env)
2091 self.declare_pyfunction(env)
2092 self.analyse_signature(env)
2093 self.return_type = self.entry.signature.return_type()
2094 self.create_local_scope(env)
2096 def analyse_argument_types(self, env):
2097 directive_locals = self.directive_locals = env.directives['locals']
2098 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2099 for arg in self.args:
2100 if hasattr(arg, 'name'):
2102 name_declarator = None
2104 base_type = arg.base_type.analyse(env)
2105 name_declarator, type = \
2106 arg.declarator.analyse(base_type, env)
2107 arg.name = name_declarator.name
2108 if arg.name in directive_locals:
2109 type_node = directive_locals[arg.name]
2110 other_type = type_node.analyse_as_type(env)
2111 if other_type is None:
2112 error(type_node.pos, "Not a type")
2113 elif (type is not PyrexTypes.py_object_type
2114 and not type.same_as(other_type)):
2115 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2116 error(type_node.pos, "Previous declaration here")
2119 if name_declarator and name_declarator.cname:
2121 "Python function argument cannot have C name specification")
2122 arg.type = type.as_argument_type()
2124 arg.needs_conversion = 0
2125 arg.needs_type_test = 0
2127 if arg.type.is_pyobject:
2129 arg.accept_none = True
2131 arg.accept_none = False
2132 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2133 if arg.default and arg.default.constant_result is None:
2134 # special case: def func(MyType obj = None)
2135 arg.accept_none = True
2137 # default depends on compiler directive
2138 arg.accept_none = allow_none_for_extension_args
2140 # probably just a plain 'object'
2141 arg.accept_none = True
2143 arg.accept_none = True # won't be used, but must be there
2145 error(arg.pos, "Only Python type arguments can have 'not None'")
2147 error(arg.pos, "Only Python type arguments can have 'or None'")
2149 def analyse_signature(self, env):
2150 if self.entry.is_special:
2151 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2152 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2153 # Use the simpler calling signature for zero- and one-argument functions.
2154 if self.entry.signature is TypeSlots.pyfunction_signature:
2155 if len(self.args) == 0:
2156 self.entry.signature = TypeSlots.pyfunction_noargs
2157 elif len(self.args) == 1:
2158 if self.args[0].default is None and not self.args[0].kw_only:
2159 self.entry.signature = TypeSlots.pyfunction_onearg
2160 elif self.entry.signature is TypeSlots.pymethod_signature:
2161 if len(self.args) == 1:
2162 self.entry.signature = TypeSlots.unaryfunc
2163 elif len(self.args) == 2:
2164 if self.args[1].default is None and not self.args[1].kw_only:
2165 self.entry.signature = TypeSlots.ibinaryfunc
2167 sig = self.entry.signature
2168 nfixed = sig.num_fixed_args()
2169 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2170 and len(self.args) == 0 and self.star_arg:
2171 # this is the only case where a diverging number of
2172 # arguments is not an error - when we have no explicit
2173 # 'self' parameter as in method(*args)
2174 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2175 self.self_in_stararg = 1
2178 for i in range(min(nfixed, len(self.args))):
2181 if sig.is_self_arg(i) and not self.is_staticmethod:
2182 if self.is_classmethod:
2184 arg.hdr_type = arg.type = Builtin.type_type
2187 arg.hdr_type = arg.type = env.parent_type
2188 arg.needs_conversion = 0
2190 arg.hdr_type = sig.fixed_arg_type(i)
2191 if not arg.type.same_as(arg.hdr_type):
2192 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2193 arg.needs_type_test = 1
2195 arg.needs_conversion = 1
2196 if arg.needs_conversion:
2197 arg.hdr_cname = Naming.arg_prefix + arg.name
2199 arg.hdr_cname = Naming.var_prefix + arg.name
2201 if nfixed > len(self.args):
2202 self.bad_signature()
2204 elif nfixed < len(self.args):
2205 if not sig.has_generic_args:
2206 self.bad_signature()
2207 for arg in self.args:
2208 if arg.is_generic and \
2209 (arg.type.is_extension_type or arg.type.is_builtin_type):
2210 arg.needs_type_test = 1
2212 def bad_signature(self):
2213 sig = self.entry.signature
2214 expected_str = "%d" % sig.num_fixed_args()
2215 if sig.has_generic_args:
2216 expected_str = expected_str + " or more"
2218 if name.startswith("__") and name.endswith("__"):
2219 desc = "Special method"
2223 "%s %s has wrong number of arguments "
2224 "(%d declared, %s expected)" % (
2225 desc, self.name, len(self.args), expected_str))
2227 def signature_has_nongeneric_args(self):
2228 argcount = len(self.args)
2229 if argcount == 0 or (
2230 argcount == 1 and (self.args[0].is_self_arg or
2231 self.args[0].is_type_arg)):
2235 def signature_has_generic_args(self):
2236 return self.entry.signature.has_generic_args
2238 def declare_pyfunction(self, env):
2239 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2241 entry = env.lookup_here(name)
2242 if entry and entry.type.is_cfunction and not self.is_wrapper:
2243 warning(self.pos, "Overriding cdef method with def method.", 5)
2244 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2246 prefix = env.next_id(env.scope_prefix)
2248 entry.func_cname = \
2249 Naming.pyfunc_prefix + prefix + name
2250 entry.pymethdef_cname = \
2251 Naming.pymethdef_prefix + prefix + name
2253 if self.is_generator:
2254 self.generator_body_cname = Naming.genbody_prefix + env.next_id(env.scope_prefix) + name
2256 if Options.docstrings:
2257 entry.doc = embed_position(self.pos, self.doc)
2259 Naming.funcdoc_prefix + prefix + name
2260 if entry.is_special:
2261 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2262 entry.wrapperbase_cname = None
2264 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2268 def declare_lambda_function(self, env):
2270 prefix = env.scope_prefix
2272 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2273 entry = env.declare_lambda_function(func_cname, self.pos)
2274 entry.pymethdef_cname = \
2275 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2276 entry.qualified_name = env.qualify_name(self.lambda_name)
2280 def declare_arguments(self, env):
2281 for arg in self.args:
2283 error(arg.pos, "Missing argument name")
2285 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2286 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2287 if arg.needs_conversion:
2288 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2289 if arg.type.is_pyobject:
2290 arg.entry.init = "0"
2291 arg.entry.init_to_none = 0
2293 arg.entry = self.declare_argument(env, arg)
2295 arg.entry.is_self_arg = arg.is_self_arg
2297 if arg.is_self_arg or arg.is_type_arg or \
2298 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2299 arg.entry.is_declared_generic = 1
2300 self.declare_python_arg(env, self.star_arg)
2301 self.declare_python_arg(env, self.starstar_arg)
2303 def declare_python_arg(self, env, arg):
2305 if env.directives['infer_types'] != False:
2306 type = PyrexTypes.unspecified_type
2308 type = py_object_type
2309 entry = env.declare_var(arg.name, type, arg.pos)
2312 entry.init_to_none = 0
2313 entry.xdecref_cleanup = 1
2315 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2317 def analyse_expressions(self, env):
2318 self.local_scope.directives = env.directives
2319 self.analyse_default_values(env)
2320 if self.needs_assignment_synthesis(env):
2321 # Shouldn't we be doing this at the module level too?
2322 self.synthesize_assignment_node(env)
2324 def needs_assignment_synthesis(self, env, code=None):
2325 # Should enable for module level as well, that will require more testing...
2326 if self.entry.is_anonymous:
2328 if env.is_module_scope:
2330 return env.directives['binding']
2332 return code.globalstate.directives['binding']
2333 return env.is_py_class_scope or env.is_closure_scope
2335 def synthesize_assignment_node(self, env):
2338 while genv.is_py_class_scope or genv.is_c_class_scope:
2339 genv = genv.outer_scope
2341 if genv.is_closure_scope:
2342 rhs = ExprNodes.InnerFunctionNode(
2343 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2345 rhs = ExprNodes.PyCFunctionNode(
2346 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2348 if env.is_py_class_scope:
2349 if not self.is_staticmethod and not self.is_classmethod:
2352 self.assmt = SingleAssignmentNode(self.pos,
2353 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2355 self.assmt.analyse_declarations(env)
2356 self.assmt.analyse_expressions(env)
2358 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2360 sig = self.entry.signature
2361 if sig.has_dummy_arg or self.self_in_stararg:
2362 arg_code_list.append(
2363 "PyObject *%s" % Naming.self_cname)
2364 for arg in self.args:
2365 if not arg.is_generic:
2366 if arg.is_self_arg or arg.is_type_arg:
2367 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2369 arg_code_list.append(
2370 arg.hdr_type.declaration_code(arg.hdr_cname))
2371 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2372 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2373 if sig.has_generic_args:
2374 arg_code_list.append(
2375 "PyObject *%s, PyObject *%s"
2376 % (Naming.args_cname, Naming.kwds_cname))
2377 arg_code = ", ".join(arg_code_list)
2378 dc = self.return_type.declaration_code(self.entry.func_cname)
2379 mf = " ".join(self.modifiers).upper()
2381 header = "static %s%s(%s)" % (mf, dc, arg_code)
2382 code.putln("%s; /*proto*/" % header)
2385 if (Options.docstrings and self.entry.doc and
2386 not self.entry.scope.is_property_scope and
2387 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2388 docstr = self.entry.doc
2389 if docstr.is_unicode:
2390 docstr = docstr.utf8encode()
2392 'static char %s[] = "%s";' % (
2393 self.entry.doc_cname,
2394 split_string_literal(escape_byte_string(docstr))))
2395 if self.entry.is_special:
2397 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2400 "static PyMethodDef %s = " %
2401 self.entry.pymethdef_cname)
2402 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2403 if self.is_generator:
2404 code.putln("static PyObject *%s(PyObject *%s, PyObject *%s) /* generator body */\n{" %
2405 (self.generator_body_cname, Naming.self_cname, Naming.sent_value_cname))
2406 self.generator = GeneratorWrapperNode(self,
2407 func_cname=self.entry.func_cname,
2408 body_cname=self.generator_body_cname,
2411 code.putln("%s {" % header)
2413 def generate_argument_declarations(self, env, code):
2414 for arg in self.args:
2415 if arg.is_generic: # or arg.needs_conversion:
2416 if arg.needs_conversion:
2417 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2418 elif not arg.entry.in_closure:
2419 code.put_var_declaration(arg.entry)
2421 def generate_keyword_list(self, code):
2422 if self.signature_has_generic_args() and \
2423 self.signature_has_nongeneric_args():
2425 "static PyObject **%s[] = {" %
2426 Naming.pykwdlist_cname)
2427 for arg in self.args:
2429 pystring_cname = code.intern_identifier(arg.name)
2430 code.put('&%s,' % pystring_cname)
2433 def generate_argument_parsing_code(self, env, code):
2434 # Generate fast equivalent of PyArg_ParseTuple call for
2435 # generic arguments, if any, including args/kwargs
2436 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2437 # get rid of unused argument warning
2438 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2440 old_error_label = code.new_error_label()
2441 our_error_label = code.error_label
2442 end_label = code.new_label("argument_unpacking_done")
2444 has_kwonly_args = self.num_kwonly_args > 0
2445 has_star_or_kw_args = self.star_arg is not None \
2446 or self.starstar_arg is not None or has_kwonly_args
2448 for arg in self.args:
2449 if not arg.type.is_pyobject:
2450 done = arg.type.create_from_py_utility_code(env)
2451 if not done: pass # will fail later
2453 if not self.signature_has_generic_args():
2454 if has_star_or_kw_args:
2455 error(self.pos, "This method cannot have * or keyword arguments")
2456 self.generate_argument_conversion_code(code)
2458 elif not self.signature_has_nongeneric_args():
2459 # func(*args) or func(**kw) or func(*args, **kw)
2460 self.generate_stararg_copy_code(code)
2463 positional_args = []
2465 for arg in self.args:
2466 arg_entry = arg.entry
2469 if not arg.is_self_arg and not arg.is_type_arg:
2471 kw_only_args.append(arg)
2473 positional_args.append(arg)
2475 kw_only_args.append(arg)
2476 elif not arg.is_self_arg and not arg.is_type_arg:
2477 positional_args.append(arg)
2479 self.generate_tuple_and_keyword_parsing_code(
2480 positional_args, kw_only_args, end_label, code)
2482 code.error_label = old_error_label
2483 if code.label_used(our_error_label):
2484 if not code.label_used(end_label):
2485 code.put_goto(end_label)
2486 code.put_label(our_error_label)
2487 if has_star_or_kw_args:
2488 self.generate_arg_decref(self.star_arg, code)
2489 if self.starstar_arg:
2490 if self.starstar_arg.entry.xdecref_cleanup:
2491 code.put_var_xdecref_clear(self.starstar_arg.entry)
2493 code.put_var_decref_clear(self.starstar_arg.entry)
2494 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2495 # The arguments are put into the closure one after the
2496 # other, so when type errors are found, all references in
2497 # the closure instance must be properly ref-counted to
2498 # facilitate generic closure instance deallocation. In
2499 # the case of an argument type error, it's best to just
2500 # DECREF+clear the already handled references, as this
2501 # frees their references as early as possible.
2502 for arg in self.args:
2503 if arg.type.is_pyobject and arg.entry.in_closure:
2504 code.put_var_xdecref_clear(arg.entry)
2505 if self.needs_closure:
2506 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2507 code.put_finish_refcount_context()
2508 code.putln("return %s;" % self.error_value())
2509 if code.label_used(end_label):
2510 code.put_label(end_label)
2512 # fix refnanny view on closure variables here, instead of
2513 # doing it separately for each arg parsing special case
2514 if self.star_arg and self.star_arg.entry.in_closure:
2515 code.put_var_giveref(self.star_arg.entry)
2516 if self.starstar_arg and self.starstar_arg.entry.in_closure:
2517 code.put_var_giveref(self.starstar_arg.entry)
2518 for arg in self.args:
2519 if arg.type.is_pyobject and arg.entry.in_closure:
2520 code.put_var_giveref(arg.entry)
2522 def generate_arg_assignment(self, arg, item, code):
2523 if arg.type.is_pyobject:
2525 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2527 if entry.in_closure:
2528 code.put_incref(item, PyrexTypes.py_object_type)
2529 code.putln("%s = %s;" % (entry.cname, item))
2531 func = arg.type.from_py_function
2533 code.putln("%s = %s(%s); %s" % (
2537 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2539 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2541 def generate_arg_xdecref(self, arg, code):
2543 code.put_var_xdecref_clear(arg.entry)
2545 def generate_arg_decref(self, arg, code):
2547 code.put_var_decref_clear(arg.entry)
2549 def generate_stararg_copy_code(self, code):
2550 if not self.star_arg:
2551 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2552 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2554 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2555 self.name, Naming.args_cname, self.error_value()))
2558 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2560 if self.starstar_arg:
2562 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2564 kwarg_check = "%s" % Naming.kwds_cname
2566 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2567 Naming.kwds_cname, Naming.kwds_cname)
2569 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2570 kwarg_check, Naming.kwds_cname, self.name,
2571 bool(self.starstar_arg), self.error_value()))
2573 if self.starstar_arg:
2574 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2575 self.starstar_arg.entry.cname,
2578 code.putln("if (unlikely(!%s)) return %s;" % (
2579 self.starstar_arg.entry.cname, self.error_value()))
2580 self.starstar_arg.entry.xdecref_cleanup = 0
2581 code.put_gotref(self.starstar_arg.entry.cname)
2583 if self.self_in_stararg:
2584 # need to create a new tuple with 'self' inserted as first item
2585 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2586 self.star_arg.entry.cname,
2588 self.star_arg.entry.cname))
2589 if self.starstar_arg:
2591 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2592 code.putln("return %s;" % self.error_value())
2595 code.putln("return %s;" % self.error_value())
2596 code.put_gotref(self.star_arg.entry.cname)
2597 code.put_incref(Naming.self_cname, py_object_type)
2598 code.put_giveref(Naming.self_cname)
2599 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2600 self.star_arg.entry.cname, Naming.self_cname))
2601 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2602 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2603 temp, temp, Naming.args_cname, temp))
2604 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2605 Naming.args_cname, temp))
2606 code.put_incref("item", py_object_type)
2607 code.put_giveref("item")
2608 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2609 self.star_arg.entry.cname, temp))
2611 code.funcstate.release_temp(temp)
2612 self.star_arg.entry.xdecref_cleanup = 0
2614 code.put_incref(Naming.args_cname, py_object_type)
2615 code.putln("%s = %s;" % (
2616 self.star_arg.entry.cname,
2618 self.star_arg.entry.xdecref_cleanup = 0
2620 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2621 kw_only_args, success_label, code):
2622 argtuple_error_label = code.new_label("argtuple_error")
2624 min_positional_args = self.num_required_args - self.num_required_kw_args
2625 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2626 min_positional_args -= 1
2627 max_positional_args = len(positional_args)
2628 has_fixed_positional_count = not self.star_arg and \
2629 min_positional_args == max_positional_args
2631 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2632 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2633 if self.num_required_kw_args:
2634 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2636 if self.starstar_arg or self.star_arg:
2637 self.generate_stararg_init_code(max_positional_args, code)
2639 # --- optimised code when we receive keyword arguments
2640 if self.num_required_kw_args:
2641 likely_hint = "likely"
2643 likely_hint = "unlikely"
2644 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2645 self.generate_keyword_unpacking_code(
2646 min_positional_args, max_positional_args,
2647 has_fixed_positional_count,
2648 positional_args, kw_only_args, argtuple_error_label, code)
2650 # --- optimised code when we do not receive any keyword arguments
2651 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2652 # Python raises arg tuple related errors first, so we must
2653 # check the length here
2654 if min_positional_args == max_positional_args and not self.star_arg:
2658 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2659 Naming.args_cname, compare, min_positional_args))
2660 code.put_goto(argtuple_error_label)
2662 if self.num_required_kw_args:
2663 # pure error case: keywords required but not passed
2664 if max_positional_args > min_positional_args and not self.star_arg:
2665 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2666 Naming.args_cname, max_positional_args))
2667 code.put_goto(argtuple_error_label)
2668 code.putln('} else {')
2669 for i, arg in enumerate(kw_only_args):
2671 pystring_cname = code.intern_identifier(arg.name)
2672 # required keyword-only argument missing
2673 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2676 code.putln(code.error_goto(self.pos))
2679 elif min_positional_args == max_positional_args:
2680 # parse the exact number of positional arguments from the
2682 code.putln('} else {')
2683 for i, arg in enumerate(positional_args):
2684 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2685 self.generate_arg_assignment(arg, item, code)
2686 self.generate_arg_default_assignments(code)
2689 # parse the positional arguments from the variable length
2691 code.putln('} else {')
2692 self.generate_arg_default_assignments(code)
2693 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2695 code.putln('default:')
2696 reversed_args = list(enumerate(positional_args))[::-1]
2697 for i, arg in reversed_args:
2698 if i >= min_positional_args-1:
2699 if min_positional_args > 1:
2700 code.putln('case %2d:' % (i+1)) # pure code beautification
2702 code.put('case %2d: ' % (i+1))
2703 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2704 self.generate_arg_assignment(arg, item, code)
2705 if min_positional_args == 0:
2706 code.put('case 0: ')
2707 code.putln('break;')
2709 if min_positional_args:
2710 for i in range(min_positional_args-1, -1, -1):
2711 code.putln('case %2d:' % i)
2712 code.put_goto(argtuple_error_label)
2714 code.put('default: ')
2715 code.put_goto(argtuple_error_label)
2720 if code.label_used(argtuple_error_label):
2721 code.put_goto(success_label)
2722 code.put_label(argtuple_error_label)
2723 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2724 self.name, has_fixed_positional_count,
2725 min_positional_args, max_positional_args,
2727 code.putln(code.error_goto(self.pos))
2729 def generate_arg_default_assignments(self, code):
2730 for arg in self.args:
2731 if arg.is_generic and arg.default:
2735 arg.calculate_default_value_code(code)))
2737 def generate_stararg_init_code(self, max_positional_args, code):
2738 if self.starstar_arg:
2739 self.starstar_arg.entry.xdecref_cleanup = 0
2740 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2741 self.starstar_arg.entry.cname,
2742 self.starstar_arg.entry.cname,
2743 self.error_value()))
2744 code.put_gotref(self.starstar_arg.entry.cname)
2746 self.star_arg.entry.xdecref_cleanup = 0
2747 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2749 max_positional_args))
2750 code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2751 self.star_arg.entry.cname, Naming.args_cname,
2752 max_positional_args, Naming.args_cname))
2753 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2754 if self.starstar_arg:
2755 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2756 if self.needs_closure:
2757 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2758 code.put_finish_refcount_context()
2759 code.putln('return %s;' % self.error_value())
2761 code.put_gotref(self.star_arg.entry.cname)
2762 code.putln('} else {')
2763 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2764 code.put_incref(Naming.empty_tuple, py_object_type)
2767 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2768 has_fixed_positional_count, positional_args,
2769 kw_only_args, argtuple_error_label, code):
2770 all_args = tuple(positional_args) + tuple(kw_only_args)
2771 max_args = len(all_args)
2773 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2775 # the 'values' array collects borrowed references to arguments
2776 # before doing any type coercion etc.
2777 code.putln("PyObject* values[%d] = {%s};" % (
2778 max_args, ','.join('0'*max_args)))
2780 # assign borrowed Python default values to the values array,
2781 # so that they can be overwritten by received arguments below
2782 for i, arg in enumerate(all_args):
2783 if arg.default and arg.type.is_pyobject:
2784 default_value = arg.calculate_default_value_code(code)
2785 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2787 # parse the args tuple and check that it's not too long
2788 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2790 code.putln('default:')
2791 for i in range(max_positional_args-1, -1, -1):
2792 code.put('case %2d: ' % (i+1))
2793 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2794 i, Naming.args_cname, i))
2795 code.putln('case 0: break;')
2796 if not self.star_arg:
2797 code.put('default: ') # more arguments than allowed
2798 code.put_goto(argtuple_error_label)
2801 # now fill up the positional/required arguments with values
2803 if self.num_required_args or max_positional_args > 0:
2804 last_required_arg = -1
2805 for i, arg in enumerate(all_args):
2807 last_required_arg = i
2808 if last_required_arg < max_positional_args:
2809 last_required_arg = max_positional_args-1
2810 num_required_args = self.num_required_args
2811 if max_positional_args > 0:
2812 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2813 for i, arg in enumerate(all_args[:last_required_arg+1]):
2814 if max_positional_args > 0 and i <= max_positional_args:
2815 if self.star_arg and i == max_positional_args:
2816 code.putln('default:')
2818 code.putln('case %2d:' % i)
2819 pystring_cname = code.intern_identifier(arg.name)
2822 # handled separately below
2824 code.putln('if (kw_args > 0) {')
2825 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2826 Naming.kwds_cname, pystring_cname))
2827 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2830 num_required_args -= 1
2831 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2832 i, Naming.kwds_cname, pystring_cname))
2833 code.putln('if (likely(values[%d])) kw_args--;' % i);
2834 if i < min_positional_args:
2836 # special case: we know arg 0 is missing
2838 code.put_goto(argtuple_error_label)
2840 # print the correct number of values (args or
2841 # kwargs) that were passed into positional
2842 # arguments up to this point
2843 code.putln('else {')
2844 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2845 self.name, has_fixed_positional_count,
2846 min_positional_args, max_positional_args, i))
2847 code.putln(code.error_goto(self.pos))
2850 code.putln('else {')
2851 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2852 self.name, pystring_cname))
2853 code.putln(code.error_goto(self.pos))
2855 if max_positional_args > 0:
2858 if kw_only_args and not self.starstar_arg:
2859 # unpack optional keyword-only arguments
2860 # checking for interned strings in a dict is faster than iterating
2861 # but it's too likely that we must iterate if we expect **kwargs
2863 for i, arg in enumerate(all_args[max_positional_args:]):
2864 if not arg.kw_only or not arg.default:
2866 optional_args.append((i+max_positional_args, arg))
2868 # this mimics an unrolled loop so that we can "break" out of it
2869 code.putln('while (kw_args > 0) {')
2870 code.putln('PyObject* value;')
2871 for i, arg in optional_args:
2872 pystring_cname = code.intern_identifier(arg.name)
2874 'value = PyDict_GetItem(%s, %s);' % (
2875 Naming.kwds_cname, pystring_cname))
2877 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2878 code.putln('break;')
2881 code.putln('if (unlikely(kw_args > 0)) {')
2882 # non-positional/-required kw args left in dict: default args,
2883 # kw-only args, **kwargs or error
2885 # This is sort of a catch-all: except for checking required
2886 # arguments, this will always do the right thing for unpacking
2887 # keyword arguments, so that we can concentrate on optimising
2888 # common cases above.
2889 if max_positional_args == 0:
2892 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2893 Naming.args_cname, max_positional_args,
2894 Naming.args_cname, max_positional_args))
2895 pos_arg_count = "used_pos_args"
2897 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2898 code.globalstate.use_utility_code(parse_keywords_utility_code)
2900 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2902 Naming.pykwdlist_cname,
2903 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2906 code.putln(code.error_goto(self.pos))
2909 # convert arg values to their final type and assign them
2910 for i, arg in enumerate(all_args):
2911 if arg.default and not arg.type.is_pyobject:
2912 code.putln("if (values[%d]) {" % i)
2913 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2914 if arg.default and not arg.type.is_pyobject:
2915 code.putln('} else {')
2919 arg.calculate_default_value_code(code)))
2922 def generate_argument_conversion_code(self, code):
2923 # Generate code to convert arguments from signature type to
2924 # declared type, if needed. Also copies signature arguments
2925 # into closure fields.
2926 for arg in self.args:
2927 if arg.needs_conversion:
2928 self.generate_arg_conversion(arg, code)
2929 elif arg.entry.in_closure:
2930 if arg.type.is_pyobject:
2931 code.put_incref(arg.hdr_cname, py_object_type)
2932 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2934 def generate_arg_conversion(self, arg, code):
2935 # Generate conversion code for one argument.
2936 old_type = arg.hdr_type
2938 if old_type.is_pyobject:
2940 code.putln("if (%s) {" % arg.hdr_cname)
2942 code.putln("assert(%s); {" % arg.hdr_cname)
2943 self.generate_arg_conversion_from_pyobject(arg, code)
2945 elif new_type.is_pyobject:
2946 self.generate_arg_conversion_to_pyobject(arg, code)
2948 if new_type.assignable_from(old_type):
2950 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2953 "Cannot convert 1 argument from '%s' to '%s'" %
2954 (old_type, new_type))
2956 def generate_arg_conversion_from_pyobject(self, arg, code):
2958 func = new_type.from_py_function
2959 # copied from CoerceFromPyTypeNode
2961 lhs = arg.entry.cname
2962 rhs = "%s(%s)" % (func, arg.hdr_cname)
2963 if new_type.is_enum:
2964 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2965 code.putln("%s = %s; %s" % (
2968 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2971 "Cannot convert Python object argument to type '%s'"
2974 def generate_arg_conversion_to_pyobject(self, arg, code):
2975 old_type = arg.hdr_type
2976 func = old_type.to_py_function
2978 code.putln("%s = %s(%s); %s" % (
2982 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2983 code.put_var_gotref(arg.entry)
2986 "Cannot convert argument of type '%s' to Python object"
2989 def generate_argument_type_tests(self, code):
2990 # Generate type tests for args whose signature
2991 # type is PyObject * and whose declared type is
2992 # a subtype thereof.
2993 for arg in self.args:
2994 if arg.needs_type_test:
2995 self.generate_arg_type_test(arg, code)
2996 elif not arg.accept_none and arg.type.is_pyobject:
2997 self.generate_arg_none_check(arg, code)
2999 def error_value(self):
3000 return self.entry.signature.error_value
3002 def caller_will_check_exceptions(self):
3005 class OverrideCheckNode(StatNode):
3006 # A Node for dispatching to the def method if it
3015 child_attrs = ['body']
3019 def analyse_expressions(self, env):
3020 self.args = env.arg_entries
3021 if self.py_func.is_module_scope:
3026 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3027 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3028 call_node = ExprNodes.SimpleCallNode(self.pos,
3029 function=self.func_node,
3030 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3031 self.body = ReturnStatNode(self.pos, value=call_node)
3032 self.body.analyse_expressions(env)
3034 def generate_execution_code(self, code):
3035 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3036 # Check to see if we are an extension type
3037 if self.py_func.is_module_scope:
3038 self_arg = "((PyObject *)%s)" % Naming.module_cname
3040 self_arg = "((PyObject *)%s)" % self.args[0].cname
3041 code.putln("/* Check if called by wrapper */")
3042 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3043 code.putln("/* Check if overriden in Python */")
3044 if self.py_func.is_module_scope:
3045 code.putln("else {")
3047 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3048 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3049 self.func_node.set_cname(func_node_temp)
3050 # need to get attribute manually--scope would return cdef method
3051 err = code.error_goto_if_null(func_node_temp, self.pos)
3052 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3053 func_node_temp, self_arg, interned_attr_cname, err))
3054 code.put_gotref(func_node_temp)
3055 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3056 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3057 func_node_temp, self.py_func.entry.func_cname)
3058 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3059 self.body.generate_execution_code(code)
3061 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3062 code.funcstate.release_temp(func_node_temp)
3065 class ClassDefNode(StatNode, BlockNode):
3068 class PyClassDefNode(ClassDefNode):
3069 # A Python class definition.
3071 # name EncodedString Name of the class
3072 # doc string or None
3073 # body StatNode Attribute definition code
3074 # entry Symtab.Entry
3075 # scope PyClassScope
3076 # decorators [DecoratorNode] list of decorators or None
3078 # The following subnodes are constructed internally:
3080 # dict DictNode Class dictionary or Py3 namespace
3081 # classobj ClassNode Class object
3082 # target NameNode Variable to assign class object to
3084 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3086 py3_style_class = False # Python3 style class (bases+kwargs)
3088 def __init__(self, pos, name, bases, doc, body, decorators = None,
3089 keyword_args = None, starstar_arg = None):
3090 StatNode.__init__(self, pos)
3094 self.decorators = decorators
3096 if self.doc and Options.docstrings:
3097 doc = embed_position(self.pos, self.doc)
3098 doc_node = ExprNodes.StringNode(pos, value = doc)
3101 if keyword_args or starstar_arg:
3102 self.py3_style_class = True
3104 self.metaclass = None
3105 if keyword_args and not starstar_arg:
3106 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3107 if item.key.value == 'metaclass':
3108 if self.metaclass is not None:
3109 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3110 # special case: we already know the metaclass,
3111 # so we don't need to do the "build kwargs,
3112 # find metaclass" dance at runtime
3113 self.metaclass = item.value
3114 del keyword_args.key_value_pairs[i]
3115 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3116 self.mkw = ExprNodes.KeywordArgsNode(
3117 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3119 self.mkw = ExprNodes.NullNode(pos)
3120 if self.metaclass is None:
3121 self.metaclass = ExprNodes.PyClassMetaclassNode(
3122 pos, mkw = self.mkw, bases = self.bases)
3123 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3124 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3126 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3127 bases = self.bases, dict = self.dict, doc = doc_node,
3128 metaclass = self.metaclass, mkw = self.mkw)
3130 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3131 self.metaclass = None
3134 self.classobj = ExprNodes.ClassNode(pos, name = name,
3135 bases = bases, dict = self.dict, doc = doc_node)
3136 self.target = ExprNodes.NameNode(pos, name = name)
3138 def as_cclass(self):
3140 Return this node as if it were declared as an extension class
3142 if self.py3_style_class:
3143 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3145 bases = self.classobj.bases.args
3147 base_class_name = None
3148 base_class_module = None
3149 elif len(bases) == 1:
3152 from ExprNodes import AttributeNode, NameNode
3153 while isinstance(base, AttributeNode):
3154 path.insert(0, base.attribute)
3156 if isinstance(base, NameNode):
3157 path.insert(0, base.name)
3158 base_class_name = path[-1]
3160 base_class_module = u'.'.join(path[:-1])
3162 base_class_module = None
3164 error(self.classobj.bases.args.pos, "Invalid base class")
3166 error(self.classobj.bases.args.pos, "C class may only have one base class")
3169 return CClassDefNode(self.pos,
3170 visibility = 'private',
3172 class_name = self.name,
3173 base_class_module = base_class_module,
3174 base_class_name = base_class_name,
3175 decorators = self.decorators,
3180 def create_scope(self, env):
3182 while genv.is_py_class_scope or genv.is_c_class_scope:
3183 genv = genv.outer_scope
3184 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3187 def analyse_declarations(self, env):
3188 self.target.analyse_target_declaration(env)
3189 cenv = self.create_scope(env)
3190 cenv.directives = env.directives
3191 cenv.class_obj_cname = self.target.entry.cname
3192 self.body.analyse_declarations(cenv)
3194 def analyse_expressions(self, env):
3195 if self.py3_style_class:
3196 self.bases.analyse_expressions(env)
3197 self.metaclass.analyse_expressions(env)
3198 self.mkw.analyse_expressions(env)
3199 self.dict.analyse_expressions(env)
3200 self.classobj.analyse_expressions(env)
3201 genv = env.global_scope()
3203 self.body.analyse_expressions(cenv)
3204 self.target.analyse_target_expression(env, self.classobj)
3206 def generate_function_definitions(self, env, code):
3207 self.generate_lambda_definitions(self.scope, code)
3208 self.body.generate_function_definitions(self.scope, code)
3210 def generate_execution_code(self, code):
3211 code.pyclass_stack.append(self)
3213 if self.py3_style_class:
3214 self.bases.generate_evaluation_code(code)
3215 self.mkw.generate_evaluation_code(code)
3216 self.metaclass.generate_evaluation_code(code)
3217 self.dict.generate_evaluation_code(code)
3218 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3219 self.body.generate_execution_code(code)
3220 self.classobj.generate_evaluation_code(code)
3221 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3222 self.target.generate_assignment_code(self.classobj, code)
3223 self.dict.generate_disposal_code(code)
3224 self.dict.free_temps(code)
3225 if self.py3_style_class:
3226 self.mkw.generate_disposal_code(code)
3227 self.mkw.free_temps(code)
3228 self.metaclass.generate_disposal_code(code)
3229 self.metaclass.free_temps(code)
3230 self.bases.generate_disposal_code(code)
3231 self.bases.free_temps(code)
3232 code.pyclass_stack.pop()
3234 class CClassDefNode(ClassDefNode):
3235 # An extension type definition.
3237 # visibility 'private' or 'public' or 'extern'
3238 # typedef_flag boolean
3240 # module_name string or None For import of extern type objects
3241 # class_name string Unqualified name of class
3242 # as_name string or None Name to declare as in this scope
3243 # base_class_module string or None Module containing the base class
3244 # base_class_name string or None Name of the base class
3245 # objstruct_name string or None Specified C name of object struct
3246 # typeobj_name string or None Specified C name of type object
3247 # in_pxd boolean Is in a .pxd file
3248 # decorators [DecoratorNode] list of decorators or None
3249 # doc string or None
3250 # body StatNode or None
3251 # entry Symtab.Entry
3252 # base_type PyExtensionType or None
3253 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3254 # buffer_defaults_pos
3256 child_attrs = ["body"]
3257 buffer_defaults_node = None
3258 buffer_defaults_pos = None
3259 typedef_flag = False
3261 objstruct_name = None
3265 def analyse_declarations(self, env):
3266 #print "CClassDefNode.analyse_declarations:", self.class_name
3267 #print "...visibility =", self.visibility
3268 #print "...module_name =", self.module_name
3271 if self.buffer_defaults_node:
3272 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3273 env, [], self.buffer_defaults_node,
3274 need_complete=False)
3276 buffer_defaults = None
3278 if env.in_cinclude and not self.objstruct_name:
3279 error(self.pos, "Object struct name specification required for "
3280 "C class defined in 'extern from' block")
3281 self.base_type = None
3282 # Now that module imports are cached, we need to
3283 # import the modules for extern classes.
3284 if self.module_name:
3286 for module in env.cimported_modules:
3287 if module.name == self.module_name:
3288 self.module = module
3289 if self.module is None:
3290 self.module = ModuleScope(self.module_name, None, env.context)
3291 self.module.has_extern_class = 1
3292 env.add_imported_module(self.module)
3294 if self.base_class_name:
3295 if self.base_class_module:
3296 base_class_scope = env.find_module(self.base_class_module, self.pos)
3298 base_class_scope = env
3299 if self.base_class_name == 'object':
3300 # extension classes are special and don't need to inherit from object
3301 if base_class_scope is None or base_class_scope.lookup('object') is None:
3302 self.base_class_name = None
3303 self.base_class_module = None
3304 base_class_scope = None
3305 if base_class_scope:
3306 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3307 if base_class_entry:
3308 if not base_class_entry.is_type:
3309 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3310 elif not base_class_entry.type.is_extension_type and \
3311 not (base_class_entry.type.is_builtin_type and \
3312 base_class_entry.type.objstruct_cname):
3313 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3314 elif not base_class_entry.type.is_complete():
3315 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3316 self.base_class_name, self.class_name))
3317 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3318 base_class_entry.type.scope.directives['final']:
3319 error(self.pos, "Base class '%s' of type '%s' is final" % (
3320 self.base_class_name, self.class_name))
3321 elif base_class_entry.type.is_builtin_type and \
3322 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3323 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3324 % base_class_entry.type.name)
3326 self.base_type = base_class_entry.type
3327 has_body = self.body is not None
3328 if self.module_name and self.visibility != 'extern':
3329 module_path = self.module_name.split(".")
3330 home_scope = env.find_imported_module(module_path, self.pos)
3336 if self.visibility == 'extern':
3337 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3338 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3340 self.entry = home_scope.declare_c_class(
3341 name = self.class_name,
3343 defining = has_body and self.in_pxd,
3344 implementing = has_body and not self.in_pxd,
3345 module_name = self.module_name,
3346 base_type = self.base_type,
3347 objstruct_cname = self.objstruct_name,
3348 typeobj_cname = self.typeobj_name,
3349 visibility = self.visibility,
3350 typedef_flag = self.typedef_flag,
3352 buffer_defaults = buffer_defaults)
3353 if home_scope is not env and self.visibility == 'extern':
3354 env.add_imported_entry(self.class_name, self.entry, self.pos)
3355 self.scope = scope = self.entry.type.scope
3356 if scope is not None:
3357 scope.directives = env.directives
3359 if self.doc and Options.docstrings:
3360 scope.doc = embed_position(self.pos, self.doc)
3363 self.body.analyse_declarations(scope)
3367 scope.implemented = 1
3368 env.allocate_vtable_names(self.entry)
3370 def analyse_expressions(self, env):
3372 scope = self.entry.type.scope
3373 self.body.analyse_expressions(scope)
3375 def generate_function_definitions(self, env, code):
3377 self.generate_lambda_definitions(self.scope, code)
3378 self.body.generate_function_definitions(self.scope, code)
3380 def generate_execution_code(self, code):
3381 # This is needed to generate evaluation code for
3382 # default values of method arguments.
3384 self.body.generate_execution_code(code)
3386 def annotate(self, code):
3388 self.body.annotate(code)
3391 class PropertyNode(StatNode):
3392 # Definition of a property in an extension type.
3395 # doc EncodedString or None Doc string
3398 child_attrs = ["body"]
3400 def analyse_declarations(self, env):
3401 entry = env.declare_property(self.name, self.doc, self.pos)
3403 entry.scope.directives = env.directives
3404 self.body.analyse_declarations(entry.scope)
3406 def analyse_expressions(self, env):
3407 self.body.analyse_expressions(env)
3409 def generate_function_definitions(self, env, code):
3410 self.body.generate_function_definitions(env, code)
3412 def generate_execution_code(self, code):
3415 def annotate(self, code):
3416 self.body.annotate(code)
3419 class GlobalNode(StatNode):
3420 # Global variable declaration.
3426 def analyse_declarations(self, env):
3427 for name in self.names:
3428 env.declare_global(name, self.pos)
3430 def analyse_expressions(self, env):
3433 def generate_execution_code(self, code):
3437 class ExprStatNode(StatNode):
3438 # Expression used as a statement.
3442 child_attrs = ["expr"]
3444 def analyse_declarations(self, env):
3446 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3447 func = self.expr.function.as_cython_attribute()
3448 if func == u'declare':
3449 args, kwds = self.expr.explicit_args_kwds()
3451 error(self.expr.pos, "Variable names must be specified.")
3452 for var, type_node in kwds.key_value_pairs:
3453 type = type_node.analyse_as_type(env)
3455 error(type_node.pos, "Unknown type")
3457 env.declare_var(var.value, type, var.pos, is_cdef = True)
3458 self.__class__ = PassStatNode
3460 def analyse_expressions(self, env):
3461 self.expr.result_is_used = False # hint that .result() may safely be left empty
3462 self.expr.analyse_expressions(env)
3464 def generate_execution_code(self, code):
3465 self.expr.generate_evaluation_code(code)
3466 if not self.expr.is_temp and self.expr.result():
3467 code.putln("%s;" % self.expr.result())
3468 self.expr.generate_disposal_code(code)
3469 self.expr.free_temps(code)
3471 def generate_function_definitions(self, env, code):
3472 self.expr.generate_function_definitions(env, code)
3474 def annotate(self, code):
3475 self.expr.annotate(code)
3478 class AssignmentNode(StatNode):
3479 # Abstract base class for assignment nodes.
3481 # The analyse_expressions and generate_execution_code
3482 # phases of assignments are split into two sub-phases
3483 # each, to enable all the right hand sides of a
3484 # parallel assignment to be evaluated before assigning
3485 # to any of the left hand sides.
3487 def analyse_expressions(self, env):
3488 self.analyse_types(env)
3490 # def analyse_expressions(self, env):
3491 # self.analyse_expressions_1(env)
3492 # self.analyse_expressions_2(env)
3494 def generate_execution_code(self, code):
3495 self.generate_rhs_evaluation_code(code)
3496 self.generate_assignment_code(code)
3499 class SingleAssignmentNode(AssignmentNode):
3500 # The simplest case:
3504 # lhs ExprNode Left hand side
3505 # rhs ExprNode Right hand side
3506 # first bool Is this guaranteed the first assignment to lhs?
3508 child_attrs = ["lhs", "rhs"]
3510 declaration_only = False
3512 def analyse_declarations(self, env):
3515 # handle declarations of the form x = cython.foo()
3516 if isinstance(self.rhs, ExprNodes.CallNode):
3517 func_name = self.rhs.function.as_cython_attribute()
3519 args, kwds = self.rhs.explicit_args_kwds()
3521 if func_name in ['declare', 'typedef']:
3522 if len(args) > 2 or kwds is not None:
3523 error(self.rhs.pos, "Can only declare one type at a time.")
3525 type = args[0].analyse_as_type(env)
3527 error(args[0].pos, "Unknown type")
3530 if func_name == 'declare':
3531 if isinstance(lhs, ExprNodes.NameNode):
3532 vars = [(lhs.name, lhs.pos)]
3533 elif isinstance(lhs, ExprNodes.TupleNode):
3534 vars = [(var.name, var.pos) for var in lhs.args]
3536 error(lhs.pos, "Invalid declaration")
3538 for var, pos in vars:
3539 env.declare_var(var, type, pos, is_cdef = True)
3544 self.declaration_only = True
3546 self.declaration_only = True
3547 if not isinstance(lhs, ExprNodes.NameNode):
3548 error(lhs.pos, "Invalid declaration.")
3549 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3551 elif func_name in ['struct', 'union']:
3552 self.declaration_only = True
3553 if len(args) > 0 or kwds is None:
3554 error(self.rhs.pos, "Struct or union members must be given by name.")
3557 for member, type_node in kwds.key_value_pairs:
3558 type = type_node.analyse_as_type(env)
3560 error(type_node.pos, "Unknown type")
3562 members.append((member.value, type, member.pos))
3563 if len(members) < len(kwds.key_value_pairs):
3565 if not isinstance(self.lhs, ExprNodes.NameNode):
3566 error(self.lhs.pos, "Invalid declaration.")
3567 name = self.lhs.name
3568 scope = StructOrUnionScope(name)
3569 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3570 for member, type, pos in members:
3571 scope.declare_var(member, type, pos)
3573 if self.declaration_only:
3576 self.lhs.analyse_target_declaration(env)
3578 def analyse_types(self, env, use_temp = 0):
3579 self.rhs.analyse_types(env)
3580 self.lhs.analyse_target_types(env)
3581 self.lhs.gil_assignment_check(env)
3582 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3584 self.rhs = self.rhs.coerce_to_temp(env)
3586 def generate_rhs_evaluation_code(self, code):
3587 self.rhs.generate_evaluation_code(code)
3589 def generate_assignment_code(self, code):
3590 self.lhs.generate_assignment_code(self.rhs, code)
3592 def generate_function_definitions(self, env, code):
3593 self.rhs.generate_function_definitions(env, code)
3595 def annotate(self, code):
3596 self.lhs.annotate(code)
3597 self.rhs.annotate(code)
3600 class CascadedAssignmentNode(AssignmentNode):
3601 # An assignment with multiple left hand sides:
3605 # lhs_list [ExprNode] Left hand sides
3606 # rhs ExprNode Right hand sides
3610 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3612 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3613 coerced_rhs_list = None
3615 def analyse_declarations(self, env):
3616 for lhs in self.lhs_list:
3617 lhs.analyse_target_declaration(env)
3619 def analyse_types(self, env, use_temp = 0):
3620 self.rhs.analyse_types(env)
3621 if not self.rhs.is_simple():
3623 self.rhs = self.rhs.coerce_to_temp(env)
3625 self.rhs = self.rhs.coerce_to_simple(env)
3626 from ExprNodes import CloneNode
3627 self.coerced_rhs_list = []
3628 for lhs in self.lhs_list:
3629 lhs.analyse_target_types(env)
3630 lhs.gil_assignment_check(env)
3631 rhs = CloneNode(self.rhs)
3632 rhs = rhs.coerce_to(lhs.type, env)
3633 self.coerced_rhs_list.append(rhs)
3635 def generate_rhs_evaluation_code(self, code):
3636 self.rhs.generate_evaluation_code(code)
3638 def generate_assignment_code(self, code):
3639 for i in range(len(self.lhs_list)):
3640 lhs = self.lhs_list[i]
3641 rhs = self.coerced_rhs_list[i]
3642 rhs.generate_evaluation_code(code)
3643 lhs.generate_assignment_code(rhs, code)
3644 # Assignment has disposed of the cloned RHS
3645 self.rhs.generate_disposal_code(code)
3646 self.rhs.free_temps(code)
3648 def generate_function_definitions(self, env, code):
3649 self.rhs.generate_function_definitions(env, code)
3651 def annotate(self, code):
3652 for i in range(len(self.lhs_list)):
3653 lhs = self.lhs_list[i].annotate(code)
3654 rhs = self.coerced_rhs_list[i].annotate(code)
3655 self.rhs.annotate(code)
3658 class ParallelAssignmentNode(AssignmentNode):
3659 # A combined packing/unpacking assignment:
3663 # This has been rearranged by the parser into
3665 # a = d ; b = e ; c = f
3667 # but we must evaluate all the right hand sides
3668 # before assigning to any of the left hand sides.
3670 # stats [AssignmentNode] The constituent assignments
3672 child_attrs = ["stats"]
3674 def analyse_declarations(self, env):
3675 for stat in self.stats:
3676 stat.analyse_declarations(env)
3678 def analyse_expressions(self, env):
3679 for stat in self.stats:
3680 stat.analyse_types(env, use_temp = 1)
3682 # def analyse_expressions(self, env):
3683 # for stat in self.stats:
3684 # stat.analyse_expressions_1(env, use_temp = 1)
3685 # for stat in self.stats:
3686 # stat.analyse_expressions_2(env)
3688 def generate_execution_code(self, code):
3689 for stat in self.stats:
3690 stat.generate_rhs_evaluation_code(code)
3691 for stat in self.stats:
3692 stat.generate_assignment_code(code)
3694 def generate_function_definitions(self, env, code):
3695 for stat in self.stats:
3696 stat.generate_function_definitions(env, code)
3698 def annotate(self, code):
3699 for stat in self.stats:
3703 class InPlaceAssignmentNode(AssignmentNode):
3704 # An in place arithmetic operand:
3710 # lhs ExprNode Left hand side
3711 # rhs ExprNode Right hand side
3712 # op char one of "+-*/%^&|"
3713 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3715 # This code is a bit tricky because in order to obey Python
3716 # semantics the sub-expressions (e.g. indices) of the lhs must
3717 # not be evaluated twice. So we must re-use the values calculated
3718 # in evaluation phase for the assignment phase as well.
3719 # Fortunately, the type of the lhs node is fairly constrained
3720 # (it must be a NameNode, AttributeNode, or IndexNode).
3722 child_attrs = ["lhs", "rhs"]
3724 def analyse_declarations(self, env):
3725 self.lhs.analyse_target_declaration(env)
3727 def analyse_types(self, env):
3728 self.rhs.analyse_types(env)
3729 self.lhs.analyse_target_types(env)
3731 def generate_execution_code(self, code):
3733 self.rhs.generate_evaluation_code(code)
3734 self.lhs.generate_subexpr_evaluation_code(code)
3735 c_op = self.operator
3739 error(self.pos, "No C inplace power operator")
3740 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3741 if self.lhs.type.is_pyobject:
3742 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3743 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3744 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3745 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3748 # TODO: make sure overload is declared
3749 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3750 self.lhs.generate_subexpr_disposal_code(code)
3751 self.lhs.free_subexpr_temps(code)
3752 self.rhs.generate_disposal_code(code)
3753 self.rhs.free_temps(code)
3755 def annotate(self, code):
3756 self.lhs.annotate(code)
3757 self.rhs.annotate(code)
3759 def create_binop_node(self):
3761 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3764 class PrintStatNode(StatNode):
3767 # arg_tuple TupleNode
3768 # stream ExprNode or None (stdout)
3769 # append_newline boolean
3771 child_attrs = ["arg_tuple", "stream"]
3773 def analyse_expressions(self, env):
3775 self.stream.analyse_expressions(env)
3776 self.stream = self.stream.coerce_to_pyobject(env)
3777 self.arg_tuple.analyse_expressions(env)
3778 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3779 env.use_utility_code(printing_utility_code)
3780 if len(self.arg_tuple.args) == 1 and self.append_newline:
3781 env.use_utility_code(printing_one_utility_code)
3783 nogil_check = Node.gil_error
3784 gil_message = "Python print statement"
3786 def generate_execution_code(self, code):
3788 self.stream.generate_evaluation_code(code)
3789 stream_result = self.stream.py_result()
3792 if len(self.arg_tuple.args) == 1 and self.append_newline:
3793 arg = self.arg_tuple.args[0]
3794 arg.generate_evaluation_code(code)
3797 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3800 code.error_goto(self.pos)))
3801 arg.generate_disposal_code(code)
3802 arg.free_temps(code)
3804 self.arg_tuple.generate_evaluation_code(code)
3806 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3808 self.arg_tuple.py_result(),
3809 self.append_newline,
3810 code.error_goto(self.pos)))
3811 self.arg_tuple.generate_disposal_code(code)
3812 self.arg_tuple.free_temps(code)
3815 self.stream.generate_disposal_code(code)
3816 self.stream.free_temps(code)
3818 def generate_function_definitions(self, env, code):
3820 self.stream.generate_function_definitions(env, code)
3821 self.arg_tuple.generate_function_definitions(env, code)
3823 def annotate(self, code):
3825 self.stream.annotate(code)
3826 self.arg_tuple.annotate(code)
3829 class ExecStatNode(StatNode):
3834 child_attrs = ["args"]
3836 def analyse_expressions(self, env):
3837 for i, arg in enumerate(self.args):
3838 arg.analyse_expressions(env)
3839 arg = arg.coerce_to_pyobject(env)
3841 env.use_utility_code(Builtin.pyexec_utility_code)
3843 nogil_check = Node.gil_error
3844 gil_message = "Python exec statement"
3846 def generate_execution_code(self, code):
3848 for arg in self.args:
3849 arg.generate_evaluation_code(code)
3850 args.append( arg.py_result() )
3851 args = tuple(args + ['0', '0'][:3-len(args)])
3852 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3853 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3854 (temp_result,) + args))
3855 for arg in self.args:
3856 arg.generate_disposal_code(code)
3857 arg.free_temps(code)
3859 code.error_goto_if_null(temp_result, self.pos))
3860 code.put_gotref(temp_result)
3861 code.put_decref_clear(temp_result, py_object_type)
3862 code.funcstate.release_temp(temp_result)
3864 def annotate(self, code):
3865 for arg in self.args:
3869 class DelStatNode(StatNode):
3874 child_attrs = ["args"]
3876 def analyse_declarations(self, env):
3877 for arg in self.args:
3878 arg.analyse_target_declaration(env)
3880 def analyse_expressions(self, env):
3881 for arg in self.args:
3882 arg.analyse_target_expression(env, None)
3883 if arg.type.is_pyobject:
3885 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3887 elif arg.type.is_cpp_class:
3888 error(arg.pos, "Deletion of non-heap C++ object")
3890 error(arg.pos, "Deletion of non-Python, non-C++ object")
3891 #arg.release_target_temp(env)
3893 def nogil_check(self, env):
3894 for arg in self.args:
3895 if arg.type.is_pyobject:
3898 gil_message = "Deleting Python object"
3900 def generate_execution_code(self, code):
3901 for arg in self.args:
3902 if arg.type.is_pyobject:
3903 arg.generate_deletion_code(code)
3904 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3905 arg.generate_result_code(code)
3906 code.putln("delete %s;" % arg.result())
3907 # else error reported earlier
3909 def annotate(self, code):
3910 for arg in self.args:
3914 class PassStatNode(StatNode):
3919 def analyse_expressions(self, env):
3922 def generate_execution_code(self, code):
3926 class BreakStatNode(StatNode):
3930 def analyse_expressions(self, env):
3933 def generate_execution_code(self, code):
3934 if not code.break_label:
3935 error(self.pos, "break statement not inside loop")
3937 code.put_goto(code.break_label)
3940 class ContinueStatNode(StatNode):
3944 def analyse_expressions(self, env):
3947 def generate_execution_code(self, code):
3948 if code.funcstate.in_try_finally:
3949 error(self.pos, "continue statement inside try of try...finally")
3950 elif not code.continue_label:
3951 error(self.pos, "continue statement not inside loop")
3953 code.put_goto(code.continue_label)
3956 class ReturnStatNode(StatNode):
3959 # value ExprNode or None
3960 # return_type PyrexType
3962 child_attrs = ["value"]
3964 def analyse_expressions(self, env):
3965 return_type = env.return_type
3966 self.return_type = return_type
3968 error(self.pos, "Return not inside a function body")
3971 self.value.analyse_types(env)
3972 if return_type.is_void or return_type.is_returncode:
3973 error(self.value.pos,
3974 "Return with value in void function")
3976 self.value = self.value.coerce_to(env.return_type, env)
3978 if (not return_type.is_void
3979 and not return_type.is_pyobject
3980 and not return_type.is_returncode):
3981 error(self.pos, "Return value required")
3983 def nogil_check(self, env):
3984 if self.return_type.is_pyobject:
3987 gil_message = "Returning Python object"
3989 def generate_execution_code(self, code):
3990 code.mark_pos(self.pos)
3991 if not self.return_type:
3992 # error reported earlier
3994 if self.return_type.is_pyobject:
3995 code.put_xdecref(Naming.retval_cname,
3998 self.value.generate_evaluation_code(code)
3999 self.value.make_owned_reference(code)
4002 Naming.retval_cname,
4003 self.value.result_as(self.return_type)))
4004 self.value.generate_post_assignment_code(code)
4005 self.value.free_temps(code)
4007 if self.return_type.is_pyobject:
4008 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4009 elif self.return_type.is_returncode:
4012 Naming.retval_cname,
4013 self.return_type.default_value))
4014 for cname, type in code.funcstate.temps_holding_reference():
4015 code.put_decref_clear(cname, type)
4016 code.put_goto(code.return_label)
4018 def generate_function_definitions(self, env, code):
4019 if self.value is not None:
4020 self.value.generate_function_definitions(env, code)
4022 def annotate(self, code):
4024 self.value.annotate(code)
4027 class RaiseStatNode(StatNode):
4030 # exc_type ExprNode or None
4031 # exc_value ExprNode or None
4032 # exc_tb ExprNode or None
4034 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4036 def analyse_expressions(self, env):
4038 self.exc_type.analyse_types(env)
4039 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4041 self.exc_value.analyse_types(env)
4042 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4044 self.exc_tb.analyse_types(env)
4045 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4046 env.use_utility_code(raise_utility_code)
4048 nogil_check = Node.gil_error
4049 gil_message = "Raising exception"
4051 def generate_execution_code(self, code):
4053 self.exc_type.generate_evaluation_code(code)
4054 type_code = self.exc_type.py_result()
4058 self.exc_value.generate_evaluation_code(code)
4059 value_code = self.exc_value.py_result()
4063 self.exc_tb.generate_evaluation_code(code)
4064 tb_code = self.exc_tb.py_result()
4068 "__Pyx_Raise(%s, %s, %s);" % (
4072 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4074 obj.generate_disposal_code(code)
4075 obj.free_temps(code)
4077 code.error_goto(self.pos))
4079 def generate_function_definitions(self, env, code):
4080 if self.exc_type is not None:
4081 self.exc_type.generate_function_definitions(env, code)
4082 if self.exc_value is not None:
4083 self.exc_value.generate_function_definitions(env, code)
4084 if self.exc_tb is not None:
4085 self.exc_tb.generate_function_definitions(env, code)
4087 def annotate(self, code):
4089 self.exc_type.annotate(code)
4091 self.exc_value.annotate(code)
4093 self.exc_tb.annotate(code)
4096 class ReraiseStatNode(StatNode):
4100 def analyse_expressions(self, env):
4101 env.use_utility_code(restore_exception_utility_code)
4103 nogil_check = Node.gil_error
4104 gil_message = "Raising exception"
4106 def generate_execution_code(self, code):
4107 vars = code.funcstate.exc_vars
4109 for varname in vars:
4110 code.put_giveref(varname)
4111 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4112 for varname in vars:
4113 code.put("%s = 0; " % varname)
4115 code.putln(code.error_goto(self.pos))
4117 error(self.pos, "Reraise not inside except clause")
4120 class AssertStatNode(StatNode):
4124 # value ExprNode or None
4126 child_attrs = ["cond", "value"]
4128 def analyse_expressions(self, env):
4129 self.cond = self.cond.analyse_boolean_expression(env)
4131 self.value.analyse_types(env)
4132 self.value = self.value.coerce_to_pyobject(env)
4134 nogil_check = Node.gil_error
4135 gil_message = "Raising exception"
4137 def generate_execution_code(self, code):
4138 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4139 self.cond.generate_evaluation_code(code)
4141 "if (unlikely(!%s)) {" %
4144 self.value.generate_evaluation_code(code)
4146 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4147 self.value.py_result())
4148 self.value.generate_disposal_code(code)
4149 self.value.free_temps(code)
4152 "PyErr_SetNone(PyExc_AssertionError);")
4154 code.error_goto(self.pos))
4157 self.cond.generate_disposal_code(code)
4158 self.cond.free_temps(code)
4159 code.putln("#endif")
4161 def generate_function_definitions(self, env, code):
4162 self.cond.generate_function_definitions(env, code)
4163 if self.value is not None:
4164 self.value.generate_function_definitions(env, code)
4166 def annotate(self, code):
4167 self.cond.annotate(code)
4169 self.value.annotate(code)
4172 class IfStatNode(StatNode):
4175 # if_clauses [IfClauseNode]
4176 # else_clause StatNode or None
4178 child_attrs = ["if_clauses", "else_clause"]
4180 def analyse_control_flow(self, env):
4181 env.start_branching(self.pos)
4182 for if_clause in self.if_clauses:
4183 if_clause.analyse_control_flow(env)
4184 env.next_branch(if_clause.end_pos())
4185 if self.else_clause:
4186 self.else_clause.analyse_control_flow(env)
4187 env.finish_branching(self.end_pos())
4189 def analyse_declarations(self, env):
4190 for if_clause in self.if_clauses:
4191 if_clause.analyse_declarations(env)
4192 if self.else_clause:
4193 self.else_clause.analyse_declarations(env)
4195 def analyse_expressions(self, env):
4196 for if_clause in self.if_clauses:
4197 if_clause.analyse_expressions(env)
4198 if self.else_clause:
4199 self.else_clause.analyse_expressions(env)
4201 def generate_execution_code(self, code):
4202 code.mark_pos(self.pos)
4203 end_label = code.new_label()
4204 for if_clause in self.if_clauses:
4205 if_clause.generate_execution_code(code, end_label)
4206 if self.else_clause:
4207 code.putln("/*else*/ {")
4208 self.else_clause.generate_execution_code(code)
4210 code.put_label(end_label)
4212 def generate_function_definitions(self, env, code):
4213 for clause in self.if_clauses:
4214 clause.generate_function_definitions(env, code)
4215 if self.else_clause is not None:
4216 self.else_clause.generate_function_definitions(env, code)
4218 def annotate(self, code):
4219 for if_clause in self.if_clauses:
4220 if_clause.annotate(code)
4221 if self.else_clause:
4222 self.else_clause.annotate(code)
4225 class IfClauseNode(Node):
4226 # if or elif clause in an if statement
4228 # condition ExprNode
4231 child_attrs = ["condition", "body"]
4233 def analyse_control_flow(self, env):
4234 self.body.analyse_control_flow(env)
4236 def analyse_declarations(self, env):
4237 self.body.analyse_declarations(env)
4239 def analyse_expressions(self, env):
4241 self.condition.analyse_temp_boolean_expression(env)
4242 self.body.analyse_expressions(env)
4244 def get_constant_condition_result(self):
4245 if self.condition.has_constant_result():
4246 return bool(self.condition.constant_result)
4250 def generate_execution_code(self, code, end_label):
4251 self.condition.generate_evaluation_code(code)
4254 self.condition.result())
4255 self.condition.generate_disposal_code(code)
4256 self.condition.free_temps(code)
4257 self.body.generate_execution_code(code)
4258 code.put_goto(end_label)
4261 def generate_function_definitions(self, env, code):
4262 self.condition.generate_function_definitions(env, code)
4263 self.body.generate_function_definitions(env, code)
4265 def annotate(self, code):
4266 self.condition.annotate(code)
4267 self.body.annotate(code)
4270 class SwitchCaseNode(StatNode):
4271 # Generated in the optimization of an if-elif-else node
4273 # conditions [ExprNode]
4276 child_attrs = ['conditions', 'body']
4278 def generate_execution_code(self, code):
4279 for cond in self.conditions:
4280 code.mark_pos(cond.pos)
4281 cond.generate_evaluation_code(code)
4282 code.putln("case %s:" % cond.result())
4283 self.body.generate_execution_code(code)
4284 code.putln("break;")
4286 def generate_function_definitions(self, env, code):
4287 for cond in self.conditions:
4288 cond.generate_function_definitions(env, code)
4289 self.body.generate_function_definitions(env, code)
4291 def annotate(self, code):
4292 for cond in self.conditions:
4294 self.body.annotate(code)
4296 class SwitchStatNode(StatNode):
4297 # Generated in the optimization of an if-elif-else node
4300 # cases [SwitchCaseNode]
4301 # else_clause StatNode or None
4303 child_attrs = ['test', 'cases', 'else_clause']
4305 def generate_execution_code(self, code):
4306 self.test.generate_evaluation_code(code)
4307 code.putln("switch (%s) {" % self.test.result())
4308 for case in self.cases:
4309 case.generate_execution_code(code)
4310 if self.else_clause is not None:
4311 code.putln("default:")
4312 self.else_clause.generate_execution_code(code)
4313 code.putln("break;")
4316 def generate_function_definitions(self, env, code):
4317 self.test.generate_function_definitions(env, code)
4318 for case in self.cases:
4319 case.generate_function_definitions(env, code)
4320 if self.else_clause is not None:
4321 self.else_clause.generate_function_definitions(env, code)
4323 def annotate(self, code):
4324 self.test.annotate(code)
4325 for case in self.cases:
4327 if self.else_clause is not None:
4328 self.else_clause.annotate(code)
4330 class LoopNode(object):
4332 def analyse_control_flow(self, env):
4333 env.start_branching(self.pos)
4334 self.body.analyse_control_flow(env)
4335 env.next_branch(self.body.end_pos())
4336 if self.else_clause:
4337 self.else_clause.analyse_control_flow(env)
4338 env.finish_branching(self.end_pos())
4341 class WhileStatNode(LoopNode, StatNode):
4344 # condition ExprNode
4346 # else_clause StatNode
4348 child_attrs = ["condition", "body", "else_clause"]
4350 def analyse_declarations(self, env):
4351 self.body.analyse_declarations(env)
4352 if self.else_clause:
4353 self.else_clause.analyse_declarations(env)
4355 def analyse_expressions(self, env):
4357 self.condition.analyse_temp_boolean_expression(env)
4358 self.body.analyse_expressions(env)
4359 if self.else_clause:
4360 self.else_clause.analyse_expressions(env)
4362 def generate_execution_code(self, code):
4363 old_loop_labels = code.new_loop_labels()
4366 self.condition.generate_evaluation_code(code)
4367 self.condition.generate_disposal_code(code)
4370 self.condition.result())
4371 self.condition.free_temps(code)
4372 self.body.generate_execution_code(code)
4373 code.put_label(code.continue_label)
4375 break_label = code.break_label
4376 code.set_loop_labels(old_loop_labels)
4377 if self.else_clause:
4378 code.putln("/*else*/ {")
4379 self.else_clause.generate_execution_code(code)
4381 code.put_label(break_label)
4383 def generate_function_definitions(self, env, code):
4384 self.condition.generate_function_definitions(env, code)
4385 self.body.generate_function_definitions(env, code)
4386 if self.else_clause is not None:
4387 self.else_clause.generate_function_definitions(env, code)
4389 def annotate(self, code):
4390 self.condition.annotate(code)
4391 self.body.annotate(code)
4392 if self.else_clause:
4393 self.else_clause.annotate(code)
4396 def ForStatNode(pos, **kw):
4397 if 'iterator' in kw:
4398 return ForInStatNode(pos, **kw)
4400 return ForFromStatNode(pos, **kw)
4402 class ForInStatNode(LoopNode, StatNode):
4406 # iterator IteratorNode
4408 # else_clause StatNode
4409 # item NextNode used internally
4411 child_attrs = ["target", "iterator", "body", "else_clause"]
4414 def analyse_declarations(self, env):
4415 self.target.analyse_target_declaration(env)
4416 self.body.analyse_declarations(env)
4417 if self.else_clause:
4418 self.else_clause.analyse_declarations(env)
4420 def analyse_expressions(self, env):
4422 self.target.analyse_target_types(env)
4423 self.iterator.analyse_expressions(env)
4424 self.item = ExprNodes.NextNode(self.iterator, env)
4425 self.item = self.item.coerce_to(self.target.type, env)
4426 self.body.analyse_expressions(env)
4427 if self.else_clause:
4428 self.else_clause.analyse_expressions(env)
4430 def generate_execution_code(self, code):
4431 old_loop_labels = code.new_loop_labels()
4432 self.iterator.allocate_counter_temp(code)
4433 self.iterator.generate_evaluation_code(code)
4436 self.item.generate_evaluation_code(code)
4437 self.target.generate_assignment_code(self.item, code)
4438 self.body.generate_execution_code(code)
4439 code.put_label(code.continue_label)
4442 break_label = code.break_label
4443 code.set_loop_labels(old_loop_labels)
4445 if self.else_clause:
4446 # in nested loops, the 'else' block can contain a
4447 # 'continue' statement for the outer loop, but we may need
4448 # to generate cleanup code before taking that path, so we
4450 orig_continue_label = code.continue_label
4451 code.continue_label = code.new_label('outer_continue')
4453 code.putln("/*else*/ {")
4454 self.else_clause.generate_execution_code(code)
4457 if code.label_used(code.continue_label):
4458 code.put_goto(break_label)
4459 code.put_label(code.continue_label)
4460 self.iterator.generate_disposal_code(code)
4461 code.put_goto(orig_continue_label)
4462 code.set_loop_labels(old_loop_labels)
4464 if code.label_used(break_label):
4465 code.put_label(break_label)
4466 self.iterator.release_counter_temp(code)
4467 self.iterator.generate_disposal_code(code)
4468 self.iterator.free_temps(code)
4470 def generate_function_definitions(self, env, code):
4471 self.target.generate_function_definitions(env, code)
4472 self.iterator.generate_function_definitions(env, code)
4473 self.body.generate_function_definitions(env, code)
4474 if self.else_clause is not None:
4475 self.else_clause.generate_function_definitions(env, code)
4477 def annotate(self, code):
4478 self.target.annotate(code)
4479 self.iterator.annotate(code)
4480 self.body.annotate(code)
4481 if self.else_clause:
4482 self.else_clause.annotate(code)
4483 self.item.annotate(code)
4486 class ForFromStatNode(LoopNode, StatNode):
4487 # for name from expr rel name rel expr
4494 # step ExprNode or None
4496 # else_clause StatNode or None
4502 # loopvar_node ExprNode (usually a NameNode or temp node)
4503 # py_loopvar_node PyTempNode or None
4504 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4506 is_py_target = False
4508 py_loopvar_node = None
4511 gil_message = "For-loop using object bounds or target"
4513 def nogil_check(self, env):
4514 for x in (self.target, self.bound1, self.bound2):
4515 if x.type.is_pyobject:
4518 def analyse_declarations(self, env):
4519 self.target.analyse_target_declaration(env)
4520 self.body.analyse_declarations(env)
4521 if self.else_clause:
4522 self.else_clause.analyse_declarations(env)
4524 def analyse_expressions(self, env):
4526 self.target.analyse_target_types(env)
4527 self.bound1.analyse_types(env)
4528 self.bound2.analyse_types(env)
4529 if self.step is not None:
4530 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4531 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4532 self.step.analyse_types(env)
4534 target_type = self.target.type
4535 if self.target.type.is_numeric:
4536 loop_type = self.target.type
4538 loop_type = PyrexTypes.c_int_type
4539 if not self.bound1.type.is_pyobject:
4540 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4541 if not self.bound2.type.is_pyobject:
4542 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4543 if self.step is not None and not self.step.type.is_pyobject:
4544 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4545 self.bound1 = self.bound1.coerce_to(loop_type, env)
4546 self.bound2 = self.bound2.coerce_to(loop_type, env)
4547 if not self.bound2.is_literal:
4548 self.bound2 = self.bound2.coerce_to_temp(env)
4549 if self.step is not None:
4550 self.step = self.step.coerce_to(loop_type, env)
4551 if not self.step.is_literal:
4552 self.step = self.step.coerce_to_temp(env)
4554 target_type = self.target.type
4555 if not (target_type.is_pyobject or target_type.is_numeric):
4556 error(self.target.pos,
4557 "for-from loop variable must be c numeric type or Python object")
4558 if target_type.is_numeric:
4559 self.is_py_target = False
4560 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4561 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4562 self.loopvar_node = self.target
4563 self.py_loopvar_node = None
4565 self.is_py_target = True
4566 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4567 self.loopvar_node = c_loopvar_node
4568 self.py_loopvar_node = \
4569 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4570 self.body.analyse_expressions(env)
4571 if self.else_clause:
4572 self.else_clause.analyse_expressions(env)
4574 def generate_execution_code(self, code):
4575 old_loop_labels = code.new_loop_labels()
4576 from_range = self.from_range
4577 self.bound1.generate_evaluation_code(code)
4578 self.bound2.generate_evaluation_code(code)
4579 offset, incop = self.relation_table[self.relation1]
4580 if self.step is not None:
4581 self.step.generate_evaluation_code(code)
4582 step = self.step.result()
4583 incop = "%s=%s" % (incop[0], step)
4585 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4586 self.loopvar_node.allocate(code)
4587 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4588 self.py_loopvar_node.allocate(code)
4590 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4592 loopvar_name = self.loopvar_node.result()
4594 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4596 self.bound1.result(), offset,
4597 loopvar_name, self.relation2, self.bound2.result(),
4598 loopvar_name, incop))
4599 if self.py_loopvar_node:
4600 self.py_loopvar_node.generate_evaluation_code(code)
4601 self.target.generate_assignment_code(self.py_loopvar_node, code)
4603 code.putln("%s = %s;" % (
4604 self.target.result(), loopvar_name))
4605 self.body.generate_execution_code(code)
4606 code.put_label(code.continue_label)
4607 if self.py_loopvar_node:
4608 # This mess is to make for..from loops with python targets behave
4609 # exactly like those with C targets with regards to re-assignment
4610 # of the loop variable.
4612 if self.target.entry.is_pyglobal:
4613 # We know target is a NameNode, this is the only ugly case.
4614 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4615 target_node.allocate(code)
4616 interned_cname = code.intern_identifier(self.target.entry.name)
4617 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4618 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4619 target_node.result(),
4620 Naming.module_cname,
4622 code.error_goto_if_null(target_node.result(), self.target.pos)))
4623 code.put_gotref(target_node.result())
4625 target_node = self.target
4626 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4627 from_py_node.temp_code = loopvar_name
4628 from_py_node.generate_result_code(code)
4629 if self.target.entry.is_pyglobal:
4630 code.put_decref(target_node.result(), target_node.type)
4631 target_node.release(code)
4633 if self.py_loopvar_node:
4634 # This is potentially wasteful, but we don't want the semantics to
4635 # depend on whether or not the loop is a python type.
4636 self.py_loopvar_node.generate_evaluation_code(code)
4637 self.target.generate_assignment_code(self.py_loopvar_node, code)
4639 code.funcstate.release_temp(loopvar_name)
4640 break_label = code.break_label
4641 code.set_loop_labels(old_loop_labels)
4642 if self.else_clause:
4643 code.putln("/*else*/ {")
4644 self.else_clause.generate_execution_code(code)
4646 code.put_label(break_label)
4647 self.bound1.generate_disposal_code(code)
4648 self.bound1.free_temps(code)
4649 self.bound2.generate_disposal_code(code)
4650 self.bound2.free_temps(code)
4651 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4652 self.loopvar_node.release(code)
4653 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4654 self.py_loopvar_node.release(code)
4655 if self.step is not None:
4656 self.step.generate_disposal_code(code)
4657 self.step.free_temps(code)
4660 # {relop : (initial offset, increment op)}
4667 def generate_function_definitions(self, env, code):
4668 self.target.generate_function_definitions(env, code)
4669 self.bound1.generate_function_definitions(env, code)
4670 self.bound2.generate_function_definitions(env, code)
4671 if self.step is not None:
4672 self.step.generate_function_definitions(env, code)
4673 self.body.generate_function_definitions(env, code)
4674 if self.else_clause is not None:
4675 self.else_clause.generate_function_definitions(env, code)
4677 def annotate(self, code):
4678 self.target.annotate(code)
4679 self.bound1.annotate(code)
4680 self.bound2.annotate(code)
4682 self.step.annotate(code)
4683 self.body.annotate(code)
4684 if self.else_clause:
4685 self.else_clause.annotate(code)
4688 class WithStatNode(StatNode):
4690 Represents a Python with statement.
4692 This is only used at parse tree level; and is not present in
4693 analysis or generation phases.
4695 # manager The with statement manager object
4696 # target Node (lhs expression)
4698 child_attrs = ["manager", "target", "body"]
4700 class TryExceptStatNode(StatNode):
4701 # try .. except statement
4704 # except_clauses [ExceptClauseNode]
4705 # else_clause StatNode or None
4707 child_attrs = ["body", "except_clauses", "else_clause"]
4709 def analyse_control_flow(self, env):
4710 env.start_branching(self.pos)
4711 self.body.analyse_control_flow(env)
4712 successful_try = env.control_flow # grab this for later
4713 env.next_branch(self.body.end_pos())
4714 env.finish_branching(self.body.end_pos())
4716 env.start_branching(self.except_clauses[0].pos)
4717 for except_clause in self.except_clauses:
4718 except_clause.analyse_control_flow(env)
4719 env.next_branch(except_clause.end_pos())
4721 # the else cause it executed only when the try clause finishes
4722 env.control_flow.incoming = successful_try
4723 if self.else_clause:
4724 self.else_clause.analyse_control_flow(env)
4725 env.finish_branching(self.end_pos())
4727 def analyse_declarations(self, env):
4728 self.body.analyse_declarations(env)
4729 for except_clause in self.except_clauses:
4730 except_clause.analyse_declarations(env)
4731 if self.else_clause:
4732 self.else_clause.analyse_declarations(env)
4733 env.use_utility_code(reset_exception_utility_code)
4735 def analyse_expressions(self, env):
4736 self.body.analyse_expressions(env)
4737 default_clause_seen = 0
4738 for except_clause in self.except_clauses:
4739 except_clause.analyse_expressions(env)
4740 if default_clause_seen:
4741 error(except_clause.pos, "default 'except:' must be last")
4742 if not except_clause.pattern:
4743 default_clause_seen = 1
4744 self.has_default_clause = default_clause_seen
4745 if self.else_clause:
4746 self.else_clause.analyse_expressions(env)
4748 nogil_check = Node.gil_error
4749 gil_message = "Try-except statement"
4751 def generate_execution_code(self, code):
4752 old_return_label = code.return_label
4753 old_break_label = code.break_label
4754 old_continue_label = code.continue_label
4755 old_error_label = code.new_error_label()
4756 our_error_label = code.error_label
4757 except_end_label = code.new_label('exception_handled')
4758 except_error_label = code.new_label('except_error')
4759 except_return_label = code.new_label('except_return')
4760 try_return_label = code.new_label('try_return')
4761 try_break_label = code.new_label('try_break')
4762 try_continue_label = code.new_label('try_continue')
4763 try_end_label = code.new_label('try_end')
4765 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4768 code.putln("__Pyx_ExceptionSave(%s);" %
4769 ', '.join(['&%s' % var for var in exc_save_vars]))
4770 for var in exc_save_vars:
4771 code.put_xgotref(var)
4774 code.return_label = try_return_label
4775 code.break_label = try_break_label
4776 code.continue_label = try_continue_label
4777 self.body.generate_execution_code(code)
4780 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4781 code.error_label = except_error_label
4782 code.return_label = except_return_label
4783 if self.else_clause:
4786 self.else_clause.generate_execution_code(code)
4789 for var in exc_save_vars:
4790 code.put_xdecref_clear(var, py_object_type)
4791 code.put_goto(try_end_label)
4792 if code.label_used(try_return_label):
4793 code.put_label(try_return_label)
4794 for var in exc_save_vars: code.put_xgiveref(var)
4795 code.putln("__Pyx_ExceptionReset(%s);" %
4796 ', '.join(exc_save_vars))
4797 code.put_goto(old_return_label)
4798 code.put_label(our_error_label)
4799 for temp_name, type in temps_to_clean_up:
4800 code.put_xdecref_clear(temp_name, type)
4801 for except_clause in self.except_clauses:
4802 except_clause.generate_handling_code(code, except_end_label)
4804 error_label_used = code.label_used(except_error_label)
4805 if error_label_used or not self.has_default_clause:
4806 if error_label_used:
4807 code.put_label(except_error_label)
4808 for var in exc_save_vars: code.put_xgiveref(var)
4809 code.putln("__Pyx_ExceptionReset(%s);" %
4810 ', '.join(exc_save_vars))
4811 code.put_goto(old_error_label)
4813 for exit_label, old_label in zip(
4814 [try_break_label, try_continue_label, except_return_label],
4815 [old_break_label, old_continue_label, old_return_label]):
4817 if code.label_used(exit_label):
4818 code.put_label(exit_label)
4819 for var in exc_save_vars: code.put_xgiveref(var)
4820 code.putln("__Pyx_ExceptionReset(%s);" %
4821 ', '.join(exc_save_vars))
4822 code.put_goto(old_label)
4824 if code.label_used(except_end_label):
4825 code.put_label(except_end_label)
4826 for var in exc_save_vars: code.put_xgiveref(var)
4827 code.putln("__Pyx_ExceptionReset(%s);" %
4828 ', '.join(exc_save_vars))
4829 code.put_label(try_end_label)
4832 for cname in exc_save_vars:
4833 code.funcstate.release_temp(cname)
4835 code.return_label = old_return_label
4836 code.break_label = old_break_label
4837 code.continue_label = old_continue_label
4838 code.error_label = old_error_label
4840 def generate_function_definitions(self, env, code):
4841 self.body.generate_function_definitions(env, code)
4842 for except_clause in self.except_clauses:
4843 except_clause.generate_function_definitions(env, code)
4844 if self.else_clause is not None:
4845 self.else_clause.generate_function_definitions(env, code)
4847 def annotate(self, code):
4848 self.body.annotate(code)
4849 for except_node in self.except_clauses:
4850 except_node.annotate(code)
4851 if self.else_clause:
4852 self.else_clause.annotate(code)
4855 class ExceptClauseNode(Node):
4856 # Part of try ... except statement.
4858 # pattern [ExprNode]
4859 # target ExprNode or None
4861 # excinfo_target NameNode or None optional target for exception info
4862 # match_flag string result of exception match
4863 # exc_value ExcValueNode used internally
4864 # function_name string qualified name of enclosing function
4865 # exc_vars (string * 3) local exception variables
4867 # excinfo_target is never set by the parser, but can be set by a transform
4868 # in order to extract more extensive information about the exception as a
4869 # sys.exc_info()-style tuple into a target variable
4871 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4874 excinfo_target = None
4876 def analyse_declarations(self, env):
4878 self.target.analyse_target_declaration(env)
4879 if self.excinfo_target is not None:
4880 self.excinfo_target.analyse_target_declaration(env)
4881 self.body.analyse_declarations(env)
4883 def analyse_expressions(self, env):
4885 genv = env.global_scope()
4886 self.function_name = env.qualified_name
4888 # normalise/unpack self.pattern into a list
4889 for i, pattern in enumerate(self.pattern):
4890 pattern.analyse_expressions(env)
4891 self.pattern[i] = pattern.coerce_to_pyobject(env)
4894 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4895 self.target.analyse_target_expression(env, self.exc_value)
4896 if self.excinfo_target is not None:
4898 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4899 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4900 self.excinfo_tuple.analyse_expressions(env)
4901 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4903 self.body.analyse_expressions(env)
4905 def generate_handling_code(self, code, end_label):
4906 code.mark_pos(self.pos)
4909 for pattern in self.pattern:
4910 pattern.generate_evaluation_code(code)
4911 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4913 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4915 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4916 for pattern in self.pattern:
4917 pattern.generate_disposal_code(code)
4918 pattern.free_temps(code)
4922 code.funcstate.release_temp(match_flag)
4924 code.putln("/*except:*/ {")
4926 if not getattr(self.body, 'stats', True) and \
4927 self.excinfo_target is None and self.target is None:
4928 # most simple case: no exception variable, empty body (pass)
4929 # => reset the exception state, done
4930 code.putln("PyErr_Restore(0,0,0);")
4931 code.put_goto(end_label)
4935 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4938 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4939 # We always have to fetch the exception value even if
4940 # there is no target, because this also normalises the
4941 # exception and stores it in the thread state.
4942 code.globalstate.use_utility_code(get_exception_utility_code)
4943 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4944 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4945 code.error_goto(self.pos)))
4949 self.exc_value.set_var(exc_vars[1])
4950 self.exc_value.generate_evaluation_code(code)
4951 self.target.generate_assignment_code(self.exc_value, code)
4952 if self.excinfo_target is not None:
4953 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4954 node.set_var(tempvar)
4955 self.excinfo_tuple.generate_evaluation_code(code)
4956 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4958 old_break_label, old_continue_label = code.break_label, code.continue_label
4959 code.break_label = code.new_label('except_break')
4960 code.continue_label = code.new_label('except_continue')
4962 old_exc_vars = code.funcstate.exc_vars
4963 code.funcstate.exc_vars = exc_vars
4964 self.body.generate_execution_code(code)
4965 code.funcstate.exc_vars = old_exc_vars
4966 for var in exc_vars:
4967 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4968 code.put_goto(end_label)
4970 if code.label_used(code.break_label):
4971 code.put_label(code.break_label)
4972 for var in exc_vars:
4973 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4974 code.put_goto(old_break_label)
4975 code.break_label = old_break_label
4977 if code.label_used(code.continue_label):
4978 code.put_label(code.continue_label)
4979 for var in exc_vars:
4980 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4981 code.put_goto(old_continue_label)
4982 code.continue_label = old_continue_label
4984 for temp in exc_vars:
4985 code.funcstate.release_temp(temp)
4990 def generate_function_definitions(self, env, code):
4991 if self.target is not None:
4992 self.target.generate_function_definitions(env, code)
4993 self.body.generate_function_definitions(env, code)
4995 def annotate(self, code):
4997 for pattern in self.pattern:
4998 pattern.annotate(code)
5000 self.target.annotate(code)
5001 self.body.annotate(code)
5004 class TryFinallyStatNode(StatNode):
5005 # try ... finally statement
5008 # finally_clause StatNode
5010 # The plan is that we funnel all continue, break
5011 # return and error gotos into the beginning of the
5012 # finally block, setting a variable to remember which
5013 # one we're doing. At the end of the finally block, we
5014 # switch on the variable to figure out where to go.
5015 # In addition, if we're doing an error, we save the
5016 # exception on entry to the finally block and restore
5019 child_attrs = ["body", "finally_clause"]
5021 preserve_exception = 1
5023 disallow_continue_in_try_finally = 0
5024 # There doesn't seem to be any point in disallowing
5025 # continue in the try block, since we have no problem
5028 def create_analysed(pos, env, body, finally_clause):
5029 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5031 create_analysed = staticmethod(create_analysed)
5033 def analyse_control_flow(self, env):
5034 env.start_branching(self.pos)
5035 self.body.analyse_control_flow(env)
5036 env.next_branch(self.body.end_pos())
5037 env.finish_branching(self.body.end_pos())
5038 self.finally_clause.analyse_control_flow(env)
5040 def analyse_declarations(self, env):
5041 self.body.analyse_declarations(env)
5042 self.finally_clause.analyse_declarations(env)
5044 def analyse_expressions(self, env):
5045 self.body.analyse_expressions(env)
5046 self.finally_clause.analyse_expressions(env)
5048 nogil_check = Node.gil_error
5049 gil_message = "Try-finally statement"
5051 def generate_execution_code(self, code):
5052 old_error_label = code.error_label
5053 old_labels = code.all_new_labels()
5054 new_labels = code.get_all_labels()
5055 new_error_label = code.error_label
5056 catch_label = code.new_label()
5059 if self.disallow_continue_in_try_finally:
5060 was_in_try_finally = code.funcstate.in_try_finally
5061 code.funcstate.in_try_finally = 1
5062 self.body.generate_execution_code(code)
5063 if self.disallow_continue_in_try_finally:
5064 code.funcstate.in_try_finally = was_in_try_finally
5067 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5068 code.mark_pos(self.finally_clause.pos)
5072 error_label_used = 0
5073 for i, new_label in enumerate(new_labels):
5074 if new_label in code.labels_used:
5075 cases_used.append(i)
5076 if new_label == new_error_label:
5077 error_label_used = 1
5078 error_label_case = i
5082 if error_label_used and self.preserve_exception:
5084 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5086 "int %s;" % Naming.exc_lineno_name)
5087 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5088 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5089 code.putln(exc_var_init_zero)
5091 exc_var_init_zero = None
5092 code.use_label(catch_label)
5094 "__pyx_why = 0; goto %s;" % catch_label)
5095 for i in cases_used:
5096 new_label = new_labels[i]
5097 #if new_label and new_label != "<try>":
5098 if new_label == new_error_label and self.preserve_exception:
5099 self.put_error_catcher(code,
5100 new_error_label, i+1, catch_label, temps_to_clean_up)
5102 code.put('%s: ' % new_label)
5103 if exc_var_init_zero:
5104 code.putln(exc_var_init_zero)
5105 code.putln("__pyx_why = %s; goto %s;" % (
5108 code.put_label(catch_label)
5109 code.set_all_labels(old_labels)
5110 if error_label_used:
5111 code.new_error_label()
5112 finally_error_label = code.error_label
5113 self.finally_clause.generate_execution_code(code)
5114 if error_label_used:
5115 if finally_error_label in code.labels_used and self.preserve_exception:
5116 over_label = code.new_label()
5117 code.put_goto(over_label);
5118 code.put_label(finally_error_label)
5119 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5120 for var in Naming.exc_vars:
5121 code.putln("Py_XDECREF(%s);" % var)
5123 code.put_goto(old_error_label)
5124 code.put_label(over_label)
5125 code.error_label = old_error_label
5128 "switch (__pyx_why) {")
5129 for i in cases_used:
5130 old_label = old_labels[i]
5131 if old_label == old_error_label and self.preserve_exception:
5132 self.put_error_uncatcher(code, i+1, old_error_label)
5134 code.use_label(old_label)
5136 "case %s: goto %s;" % (
5144 def generate_function_definitions(self, env, code):
5145 self.body.generate_function_definitions(env, code)
5146 self.finally_clause.generate_function_definitions(env, code)
5148 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5149 code.globalstate.use_utility_code(restore_exception_utility_code)
5156 for temp_name, type in temps_to_clean_up:
5157 code.put_xdecref_clear(temp_name, type)
5159 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5163 Naming.exc_lineno_name, Naming.lineno_cname))
5164 code.put_goto(catch_label)
5167 def put_error_uncatcher(self, code, i, error_label):
5168 code.globalstate.use_utility_code(restore_exception_utility_code)
5173 "__Pyx_ErrRestore(%s, %s, %s);" %
5177 Naming.lineno_cname, Naming.exc_lineno_name))
5178 for var in Naming.exc_vars:
5182 code.put_goto(error_label)
5186 def annotate(self, code):
5187 self.body.annotate(code)
5188 self.finally_clause.annotate(code)
5191 class GILStatNode(TryFinallyStatNode):
5192 # 'with gil' or 'with nogil' statement
5194 # state string 'gil' or 'nogil'
5198 preserve_exception = 0
5200 def __init__(self, pos, state, body):
5202 TryFinallyStatNode.__init__(self, pos,
5204 finally_clause = GILExitNode(pos, state = state))
5206 def analyse_expressions(self, env):
5207 env.use_utility_code(force_init_threads_utility_code)
5208 was_nogil = env.nogil
5210 TryFinallyStatNode.analyse_expressions(self, env)
5211 env.nogil = was_nogil
5215 def generate_execution_code(self, code):
5216 code.mark_pos(self.pos)
5218 if self.state == 'gil':
5219 code.putln("#ifdef WITH_THREAD")
5220 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5221 code.putln("#endif")
5223 code.putln("#ifdef WITH_THREAD")
5224 code.putln("PyThreadState *_save;")
5225 code.putln("#endif")
5226 code.putln("Py_UNBLOCK_THREADS")
5227 TryFinallyStatNode.generate_execution_code(self, code)
5231 class GILExitNode(StatNode):
5232 # Used as the 'finally' block in a GILStatNode
5234 # state string 'gil' or 'nogil'
5238 def analyse_expressions(self, env):
5241 def generate_execution_code(self, code):
5242 if self.state == 'gil':
5243 code.putln("#ifdef WITH_THREAD")
5244 code.putln("PyGILState_Release(_save);")
5245 code.putln("#endif")
5247 code.putln("Py_BLOCK_THREADS")
5250 class CImportStatNode(StatNode):
5253 # module_name string Qualified name of module being imported
5254 # as_name string or None Name specified in "as" clause, if any
5258 def analyse_declarations(self, env):
5259 if not env.is_module_scope:
5260 error(self.pos, "cimport only allowed at module level")
5262 module_scope = env.find_module(self.module_name, self.pos)
5263 if "." in self.module_name:
5264 names = [EncodedString(name) for name in self.module_name.split(".")]
5266 top_module_scope = env.context.find_submodule(top_name)
5267 module_scope = top_module_scope
5268 for name in names[1:]:
5269 submodule_scope = module_scope.find_submodule(name)
5270 module_scope.declare_module(name, submodule_scope, self.pos)
5271 module_scope = submodule_scope
5273 env.declare_module(self.as_name, module_scope, self.pos)
5275 env.declare_module(top_name, top_module_scope, self.pos)
5277 name = self.as_name or self.module_name
5278 env.declare_module(name, module_scope, self.pos)
5280 def analyse_expressions(self, env):
5283 def generate_execution_code(self, code):
5287 class FromCImportStatNode(StatNode):
5288 # from ... cimport statement
5290 # module_name string Qualified name of module
5291 # imported_names [(pos, name, as_name, kind)] Names to be imported
5295 def analyse_declarations(self, env):
5296 if not env.is_module_scope:
5297 error(self.pos, "cimport only allowed at module level")
5299 module_scope = env.find_module(self.module_name, self.pos)
5300 env.add_imported_module(module_scope)
5301 for pos, name, as_name, kind in self.imported_names:
5303 for local_name, entry in module_scope.entries.items():
5304 env.add_imported_entry(local_name, entry, pos)
5306 entry = module_scope.lookup(name)
5308 if kind and not self.declaration_matches(entry, kind):
5309 entry.redeclared(pos)
5311 if kind == 'struct' or kind == 'union':
5312 entry = module_scope.declare_struct_or_union(name,
5313 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5314 elif kind == 'class':
5315 entry = module_scope.declare_c_class(name, pos = pos,
5316 module_name = self.module_name)
5318 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5319 if submodule_scope.parent_module is module_scope:
5320 env.declare_module(as_name or name, submodule_scope, self.pos)
5322 error(pos, "Name '%s' not declared in module '%s'"
5323 % (name, self.module_name))
5326 local_name = as_name or name
5327 env.add_imported_entry(local_name, entry, pos)
5329 def declaration_matches(self, entry, kind):
5330 if not entry.is_type:
5334 if not type.is_extension_type:
5337 if not type.is_struct_or_union:
5339 if kind != type.kind:
5343 def analyse_expressions(self, env):
5346 def generate_execution_code(self, code):
5350 class FromImportStatNode(StatNode):
5351 # from ... import statement
5354 # items [(string, NameNode)]
5355 # interned_items [(string, NameNode, ExprNode)]
5356 # item PyTempNode used internally
5357 # import_star boolean used internally
5359 child_attrs = ["module"]
5362 def analyse_declarations(self, env):
5363 for name, target in self.items:
5365 if not env.is_module_scope:
5366 error(self.pos, "import * only allowed at module level")
5368 env.has_import_star = 1
5369 self.import_star = 1
5371 target.analyse_target_declaration(env)
5373 def analyse_expressions(self, env):
5375 self.module.analyse_expressions(env)
5376 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5377 self.interned_items = []
5378 for name, target in self.items:
5380 for _, entry in env.entries.items():
5381 if not entry.is_type and entry.type.is_extension_type:
5382 env.use_utility_code(ExprNodes.type_test_utility_code)
5385 entry = env.lookup(target.name)
5386 # check whether or not entry is already cimported
5387 if (entry.is_type and entry.type.name == name
5388 and hasattr(entry.type, 'module_name')):
5389 if entry.type.module_name == self.module.module_name.value:
5390 # cimported with absolute name
5393 # cimported with relative name
5394 module = env.find_module(self.module.module_name.value,
5396 if entry.type.module_name == module.qualified_name:
5398 except AttributeError:
5400 target.analyse_target_expression(env, None)
5401 if target.type is py_object_type:
5404 coerced_item = self.item.coerce_to(target.type, env)
5405 self.interned_items.append((name, target, coerced_item))
5407 def generate_execution_code(self, code):
5408 self.module.generate_evaluation_code(code)
5409 if self.import_star:
5411 'if (%s(%s) < 0) %s;' % (
5413 self.module.py_result(),
5414 code.error_goto(self.pos)))
5415 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5416 self.item.set_cname(item_temp)
5417 for name, target, coerced_item in self.interned_items:
5418 cname = code.intern_identifier(name)
5420 '%s = PyObject_GetAttr(%s, %s); %s' % (
5422 self.module.py_result(),
5424 code.error_goto_if_null(item_temp, self.pos)))
5425 code.put_gotref(item_temp)
5426 if coerced_item is None:
5427 target.generate_assignment_code(self.item, code)
5429 coerced_item.allocate_temp_result(code)
5430 coerced_item.generate_result_code(code)
5431 target.generate_assignment_code(coerced_item, code)
5432 code.put_decref_clear(item_temp, py_object_type)
5433 code.funcstate.release_temp(item_temp)
5434 self.module.generate_disposal_code(code)
5435 self.module.free_temps(code)
5439 #------------------------------------------------------------------------------------
5441 # Runtime support code
5443 #------------------------------------------------------------------------------------
5445 utility_function_predeclarations = \
5447 /* inline attribute */
5448 #ifndef CYTHON_INLINE
5449 #if defined(__GNUC__)
5450 #define CYTHON_INLINE __inline__
5451 #elif defined(_MSC_VER)
5452 #define CYTHON_INLINE __inline
5453 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5454 #define CYTHON_INLINE inline
5456 #define CYTHON_INLINE
5460 /* unused attribute */
5461 #ifndef CYTHON_UNUSED
5462 # if defined(__GNUC__)
5463 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5464 # define CYTHON_UNUSED __attribute__ ((__unused__))
5466 # define CYTHON_UNUSED
5468 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5469 # define CYTHON_UNUSED __attribute__ ((__unused__))
5471 # define CYTHON_UNUSED
5475 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*/
5479 if Options.gcc_branch_hints:
5480 branch_prediction_macros = \
5483 /* Test for GCC > 2.95 */
5484 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5485 #define likely(x) __builtin_expect(!!(x), 1)
5486 #define unlikely(x) __builtin_expect(!!(x), 0)
5487 #else /* __GNUC__ > 2 ... */
5488 #define likely(x) (x)
5489 #define unlikely(x) (x)
5490 #endif /* __GNUC__ > 2 ... */
5491 #else /* __GNUC__ */
5492 #define likely(x) (x)
5493 #define unlikely(x) (x)
5494 #endif /* __GNUC__ */
5497 branch_prediction_macros = \
5499 #define likely(x) (x)
5500 #define unlikely(x) (x)
5503 #get_name_predeclaration = \
5504 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5506 #get_name_interned_predeclaration = \
5507 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5509 #------------------------------------------------------------------------------------
5511 printing_utility_code = UtilityCode(
5513 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5514 #if PY_MAJOR_VERSION >= 3
5515 static PyObject* %s = 0;
5516 static PyObject* %s = 0;
5518 """ % (Naming.print_function, Naming.print_function_kwargs),
5520 #if PY_MAJOR_VERSION >= 3
5524 """ % (Naming.print_function, Naming.print_function_kwargs),
5526 #if PY_MAJOR_VERSION < 3
5527 static PyObject *__Pyx_GetStdout(void) {
5528 PyObject *f = PySys_GetObject((char *)"stdout");
5530 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5535 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5540 if (!(f = __Pyx_GetStdout()))
5543 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5544 if (PyFile_SoftSpace(f, 1)) {
5545 if (PyFile_WriteString(" ", f) < 0)
5548 v = PyTuple_GET_ITEM(arg_tuple, i);
5549 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5551 if (PyString_Check(v)) {
5552 char *s = PyString_AsString(v);
5553 Py_ssize_t len = PyString_Size(v);
5555 isspace(Py_CHARMASK(s[len-1])) &&
5557 PyFile_SoftSpace(f, 0);
5561 if (PyFile_WriteString("\n", f) < 0)
5563 PyFile_SoftSpace(f, 0);
5568 #else /* Python 3 has a print function */
5570 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5571 PyObject* kwargs = 0;
5572 PyObject* result = 0;
5573 PyObject* end_string;
5574 if (unlikely(!%(PRINT_FUNCTION)s)) {
5575 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5576 if (!%(PRINT_FUNCTION)s)
5580 kwargs = PyDict_New();
5581 if (unlikely(!kwargs))
5583 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5586 end_string = PyUnicode_FromStringAndSize(" ", 1);
5587 if (unlikely(!end_string))
5589 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5590 Py_DECREF(end_string);
5593 Py_DECREF(end_string);
5595 } else if (!newline) {
5596 if (unlikely(!%(PRINT_KWARGS)s)) {
5597 %(PRINT_KWARGS)s = PyDict_New();
5598 if (unlikely(!%(PRINT_KWARGS)s))
5600 end_string = PyUnicode_FromStringAndSize(" ", 1);
5601 if (unlikely(!end_string))
5603 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5604 Py_DECREF(end_string);
5607 Py_DECREF(end_string);
5609 kwargs = %(PRINT_KWARGS)s;
5611 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5612 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5619 if (kwargs != %(PRINT_KWARGS)s)
5625 """ % {'BUILTINS' : Naming.builtins_cname,
5626 'PRINT_FUNCTION' : Naming.print_function,
5627 'PRINT_KWARGS' : Naming.print_function_kwargs}
5631 printing_one_utility_code = UtilityCode(
5633 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5636 #if PY_MAJOR_VERSION < 3
5638 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5640 if (!(f = __Pyx_GetStdout()))
5643 if (PyFile_SoftSpace(f, 0)) {
5644 if (PyFile_WriteString(" ", f) < 0)
5647 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5649 if (PyFile_WriteString("\n", f) < 0)
5652 /* the line below is just to avoid compiler
5653 * compiler warnings about unused functions */
5654 return __Pyx_Print(f, NULL, 0);
5657 #else /* Python 3 has a print function */
5659 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5661 PyObject* arg_tuple = PyTuple_New(1);
5662 if (unlikely(!arg_tuple))
5665 PyTuple_SET_ITEM(arg_tuple, 0, o);
5666 res = __Pyx_Print(stream, arg_tuple, 1);
5667 Py_DECREF(arg_tuple);
5673 requires=[printing_utility_code])
5677 #------------------------------------------------------------------------------------
5679 # Exception raising code
5681 # Exceptions are raised by __Pyx_Raise() and stored as plain
5682 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5683 # 'except' statement, curexc_* is moved over to exc_* by
5684 # __Pyx_GetException()
5686 restore_exception_utility_code = UtilityCode(
5688 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5689 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5692 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5693 PyObject *tmp_type, *tmp_value, *tmp_tb;
5694 PyThreadState *tstate = PyThreadState_GET();
5696 tmp_type = tstate->curexc_type;
5697 tmp_value = tstate->curexc_value;
5698 tmp_tb = tstate->curexc_traceback;
5699 tstate->curexc_type = type;
5700 tstate->curexc_value = value;
5701 tstate->curexc_traceback = tb;
5702 Py_XDECREF(tmp_type);
5703 Py_XDECREF(tmp_value);
5707 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5708 PyThreadState *tstate = PyThreadState_GET();
5709 *type = tstate->curexc_type;
5710 *value = tstate->curexc_value;
5711 *tb = tstate->curexc_traceback;
5713 tstate->curexc_type = 0;
5714 tstate->curexc_value = 0;
5715 tstate->curexc_traceback = 0;
5720 # The following function is based on do_raise() from ceval.c. There
5721 # are separate versions for Python2 and Python3 as exception handling
5722 # has changed quite a lot between the two versions.
5724 raise_utility_code = UtilityCode(
5726 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5729 #if PY_MAJOR_VERSION < 3
5730 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5734 /* First, check the traceback argument, replacing None with NULL. */
5735 if (tb == Py_None) {
5739 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5740 PyErr_SetString(PyExc_TypeError,
5741 "raise: arg 3 must be a traceback or None");
5744 /* Next, replace a missing value with None */
5745 if (value == NULL) {
5749 #if PY_VERSION_HEX < 0x02050000
5750 if (!PyClass_Check(type))
5752 if (!PyType_Check(type))
5755 /* Raising an instance. The value should be a dummy. */
5756 if (value != Py_None) {
5757 PyErr_SetString(PyExc_TypeError,
5758 "instance exception may not have a separate value");
5761 /* Normalize to raise <class>, <instance> */
5764 #if PY_VERSION_HEX < 0x02050000
5765 if (PyInstance_Check(type)) {
5766 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5771 PyErr_SetString(PyExc_TypeError,
5772 "raise: exception must be an old-style class or instance");
5776 type = (PyObject*) Py_TYPE(type);
5778 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5779 PyErr_SetString(PyExc_TypeError,
5780 "raise: exception class must be a subclass of BaseException");
5786 __Pyx_ErrRestore(type, value, tb);
5795 #else /* Python 3+ */
5797 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5798 if (tb == Py_None) {
5800 } else if (tb && !PyTraceBack_Check(tb)) {
5801 PyErr_SetString(PyExc_TypeError,
5802 "raise: arg 3 must be a traceback or None");
5805 if (value == Py_None)
5808 if (PyExceptionInstance_Check(type)) {
5810 PyErr_SetString(PyExc_TypeError,
5811 "instance exception may not have a separate value");
5815 type = (PyObject*) Py_TYPE(value);
5816 } else if (!PyExceptionClass_Check(type)) {
5817 PyErr_SetString(PyExc_TypeError,
5818 "raise: exception class must be a subclass of BaseException");
5822 PyErr_SetObject(type, value);
5825 PyThreadState *tstate = PyThreadState_GET();
5826 PyObject* tmp_tb = tstate->curexc_traceback;
5829 tstate->curexc_traceback = tb;
5839 requires=[restore_exception_utility_code])
5841 #------------------------------------------------------------------------------------
5843 get_exception_utility_code = UtilityCode(
5845 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5848 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5849 PyObject *local_type, *local_value, *local_tb;
5850 PyObject *tmp_type, *tmp_value, *tmp_tb;
5851 PyThreadState *tstate = PyThreadState_GET();
5852 local_type = tstate->curexc_type;
5853 local_value = tstate->curexc_value;
5854 local_tb = tstate->curexc_traceback;
5855 tstate->curexc_type = 0;
5856 tstate->curexc_value = 0;
5857 tstate->curexc_traceback = 0;
5858 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5859 if (unlikely(tstate->curexc_type))
5861 #if PY_MAJOR_VERSION >= 3
5862 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5866 *value = local_value;
5868 Py_INCREF(local_type);
5869 Py_INCREF(local_value);
5870 Py_INCREF(local_tb);
5871 tmp_type = tstate->exc_type;
5872 tmp_value = tstate->exc_value;
5873 tmp_tb = tstate->exc_traceback;
5874 tstate->exc_type = local_type;
5875 tstate->exc_value = local_value;
5876 tstate->exc_traceback = local_tb;
5877 /* Make sure tstate is in a consistent state when we XDECREF
5878 these objects (XDECREF may run arbitrary code). */
5879 Py_XDECREF(tmp_type);
5880 Py_XDECREF(tmp_value);
5887 Py_XDECREF(local_type);
5888 Py_XDECREF(local_value);
5889 Py_XDECREF(local_tb);
5895 #------------------------------------------------------------------------------------
5897 get_exception_tuple_utility_code = UtilityCode(proto="""
5898 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5900 # I doubt that calling __Pyx_GetException() here is correct as it moves
5901 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5902 # exception handlers later on from receiving it.
5904 static PyObject *__Pyx_GetExceptionTuple(void) {
5905 PyObject *type = NULL, *value = NULL, *tb = NULL;
5906 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5907 PyObject* exc_info = PyTuple_New(3);
5912 PyTuple_SET_ITEM(exc_info, 0, type);
5913 PyTuple_SET_ITEM(exc_info, 1, value);
5914 PyTuple_SET_ITEM(exc_info, 2, tb);
5921 requires=[get_exception_utility_code])
5923 #------------------------------------------------------------------------------------
5925 reset_exception_utility_code = UtilityCode(
5927 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5928 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5931 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5932 PyThreadState *tstate = PyThreadState_GET();
5933 *type = tstate->exc_type;
5934 *value = tstate->exc_value;
5935 *tb = tstate->exc_traceback;
5941 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5942 PyObject *tmp_type, *tmp_value, *tmp_tb;
5943 PyThreadState *tstate = PyThreadState_GET();
5944 tmp_type = tstate->exc_type;
5945 tmp_value = tstate->exc_value;
5946 tmp_tb = tstate->exc_traceback;
5947 tstate->exc_type = type;
5948 tstate->exc_value = value;
5949 tstate->exc_traceback = tb;
5950 Py_XDECREF(tmp_type);
5951 Py_XDECREF(tmp_value);
5956 #------------------------------------------------------------------------------------
5958 arg_type_test_utility_code = UtilityCode(
5960 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5961 const char *name, int exact); /*proto*/
5964 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5965 const char *name, int exact)
5968 PyErr_Format(PyExc_SystemError, "Missing type object");
5971 if (none_allowed && obj == Py_None) return 1;
5973 if (Py_TYPE(obj) == type) return 1;
5976 if (PyObject_TypeCheck(obj, type)) return 1;
5978 PyErr_Format(PyExc_TypeError,
5979 "Argument '%s' has incorrect type (expected %s, got %s)",
5980 name, type->tp_name, Py_TYPE(obj)->tp_name);
5985 #------------------------------------------------------------------------------------
5987 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5988 # many or too few positional arguments were found. This handles
5989 # Py_ssize_t formatting correctly.
5991 raise_argtuple_invalid_utility_code = UtilityCode(
5993 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5994 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5997 static void __Pyx_RaiseArgtupleInvalid(
5998 const char* func_name,
6002 Py_ssize_t num_found)
6004 Py_ssize_t num_expected;
6005 const char *number, *more_or_less;
6007 if (num_found < num_min) {
6008 num_expected = num_min;
6009 more_or_less = "at least";
6011 num_expected = num_max;
6012 more_or_less = "at most";
6015 more_or_less = "exactly";
6017 number = (num_expected == 1) ? "" : "s";
6018 PyErr_Format(PyExc_TypeError,
6019 #if PY_VERSION_HEX < 0x02050000
6020 "%s() takes %s %d positional argument%s (%d given)",
6022 "%s() takes %s %zd positional argument%s (%zd given)",
6024 func_name, more_or_less, num_expected, number, num_found);
6028 raise_keyword_required_utility_code = UtilityCode(
6030 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6033 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6034 const char* func_name,
6037 PyErr_Format(PyExc_TypeError,
6038 #if PY_MAJOR_VERSION >= 3
6039 "%s() needs keyword-only argument %U", func_name, kw_name);
6041 "%s() needs keyword-only argument %s", func_name,
6042 PyString_AS_STRING(kw_name));
6047 raise_double_keywords_utility_code = UtilityCode(
6049 static void __Pyx_RaiseDoubleKeywordsError(
6050 const char* func_name, PyObject* kw_name); /*proto*/
6053 static void __Pyx_RaiseDoubleKeywordsError(
6054 const char* func_name,
6057 PyErr_Format(PyExc_TypeError,
6058 #if PY_MAJOR_VERSION >= 3
6059 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6061 "%s() got multiple values for keyword argument '%s'", func_name,
6062 PyString_AS_STRING(kw_name));
6067 #------------------------------------------------------------------------------------
6069 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6070 # were passed to a function, or if any keywords were passed to a
6071 # function that does not accept them.
6073 keyword_string_check_utility_code = UtilityCode(
6075 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6076 const char* function_name, int kw_allowed); /*proto*/
6079 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6081 const char* function_name,
6086 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6087 #if PY_MAJOR_VERSION < 3
6088 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6090 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6092 goto invalid_keyword_type;
6094 if ((!kw_allowed) && unlikely(key))
6095 goto invalid_keyword;
6097 invalid_keyword_type:
6098 PyErr_Format(PyExc_TypeError,
6099 "%s() keywords must be strings", function_name);
6102 PyErr_Format(PyExc_TypeError,
6103 #if PY_MAJOR_VERSION < 3
6104 "%s() got an unexpected keyword argument '%s'",
6105 function_name, PyString_AsString(key));
6107 "%s() got an unexpected keyword argument '%U'",
6108 function_name, key);
6114 #------------------------------------------------------------------------------------
6116 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6117 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6118 # keywords will raise an invalid keyword error.
6120 # Three kinds of errors are checked: 1) non-string keywords, 2)
6121 # unexpected keywords and 3) overlap with positional arguments.
6123 # If num_posargs is greater 0, it denotes the number of positional
6124 # arguments that were passed and that must therefore not appear
6125 # amongst the keywords as well.
6127 # This method does not check for required keyword arguments.
6130 parse_keywords_utility_code = UtilityCode(
6132 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6133 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6134 const char* function_name); /*proto*/
6137 static int __Pyx_ParseOptionalKeywords(
6139 PyObject **argnames[],
6142 Py_ssize_t num_pos_args,
6143 const char* function_name)
6145 PyObject *key = 0, *value = 0;
6148 PyObject*** first_kw_arg = argnames + num_pos_args;
6150 while (PyDict_Next(kwds, &pos, &key, &value)) {
6151 name = first_kw_arg;
6152 while (*name && (**name != key)) name++;
6154 values[name-argnames] = value;
6156 #if PY_MAJOR_VERSION < 3
6157 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6159 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6161 goto invalid_keyword_type;
6163 for (name = first_kw_arg; *name; name++) {
6164 #if PY_MAJOR_VERSION >= 3
6165 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6166 PyUnicode_Compare(**name, key) == 0) break;
6168 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6169 _PyString_Eq(**name, key)) break;
6173 values[name-argnames] = value;
6175 /* unexpected keyword found */
6176 for (name=argnames; name != first_kw_arg; name++) {
6177 if (**name == key) goto arg_passed_twice;
6178 #if PY_MAJOR_VERSION >= 3
6179 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6180 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6182 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6183 _PyString_Eq(**name, key)) goto arg_passed_twice;
6187 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6189 goto invalid_keyword;
6197 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6199 invalid_keyword_type:
6200 PyErr_Format(PyExc_TypeError,
6201 "%s() keywords must be strings", function_name);
6204 PyErr_Format(PyExc_TypeError,
6205 #if PY_MAJOR_VERSION < 3
6206 "%s() got an unexpected keyword argument '%s'",
6207 function_name, PyString_AsString(key));
6209 "%s() got an unexpected keyword argument '%U'",
6210 function_name, key);
6217 #------------------------------------------------------------------------------------
6219 traceback_utility_code = UtilityCode(
6221 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6224 #include "compile.h"
6225 #include "frameobject.h"
6226 #include "traceback.h"
6228 static void __Pyx_AddTraceback(const char *funcname) {
6229 PyObject *py_srcfile = 0;
6230 PyObject *py_funcname = 0;
6231 PyObject *py_globals = 0;
6232 PyCodeObject *py_code = 0;
6233 PyFrameObject *py_frame = 0;
6235 #if PY_MAJOR_VERSION < 3
6236 py_srcfile = PyString_FromString(%(FILENAME)s);
6238 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6240 if (!py_srcfile) goto bad;
6242 #if PY_MAJOR_VERSION < 3
6243 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6245 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6249 #if PY_MAJOR_VERSION < 3
6250 py_funcname = PyString_FromString(funcname);
6252 py_funcname = PyUnicode_FromString(funcname);
6255 if (!py_funcname) goto bad;
6256 py_globals = PyModule_GetDict(%(GLOBALS)s);
6257 if (!py_globals) goto bad;
6258 py_code = PyCode_New(
6259 0, /*int argcount,*/
6260 #if PY_MAJOR_VERSION >= 3
6261 0, /*int kwonlyargcount,*/
6264 0, /*int stacksize,*/
6266 %(EMPTY_BYTES)s, /*PyObject *code,*/
6267 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6268 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6269 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6270 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6271 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6272 py_srcfile, /*PyObject *filename,*/
6273 py_funcname, /*PyObject *name,*/
6274 %(LINENO)s, /*int firstlineno,*/
6275 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6277 if (!py_code) goto bad;
6278 py_frame = PyFrame_New(
6279 PyThreadState_GET(), /*PyThreadState *tstate,*/
6280 py_code, /*PyCodeObject *code,*/
6281 py_globals, /*PyObject *globals,*/
6282 0 /*PyObject *locals*/
6284 if (!py_frame) goto bad;
6285 py_frame->f_lineno = %(LINENO)s;
6286 PyTraceBack_Here(py_frame);
6288 Py_XDECREF(py_srcfile);
6289 Py_XDECREF(py_funcname);
6290 Py_XDECREF(py_code);
6291 Py_XDECREF(py_frame);
6294 'FILENAME': Naming.filename_cname,
6295 'LINENO': Naming.lineno_cname,
6296 'CFILENAME': Naming.cfilenm_cname,
6297 'CLINENO': Naming.clineno_cname,
6298 'GLOBALS': Naming.module_cname,
6299 'EMPTY_TUPLE' : Naming.empty_tuple,
6300 'EMPTY_BYTES' : Naming.empty_bytes,
6303 #------------------------------------------------------------------------------------
6305 unraisable_exception_utility_code = UtilityCode(
6307 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6310 static void __Pyx_WriteUnraisable(const char *name) {
6311 PyObject *old_exc, *old_val, *old_tb;
6313 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6314 #if PY_MAJOR_VERSION < 3
6315 ctx = PyString_FromString(name);
6317 ctx = PyUnicode_FromString(name);
6319 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6321 PyErr_WriteUnraisable(Py_None);
6323 PyErr_WriteUnraisable(ctx);
6328 requires=[restore_exception_utility_code])
6330 #------------------------------------------------------------------------------------
6332 set_vtable_utility_code = UtilityCode(
6334 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6337 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6338 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6339 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6341 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6345 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6355 #------------------------------------------------------------------------------------
6357 get_vtable_utility_code = UtilityCode(
6359 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6362 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6363 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6366 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6367 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6369 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6371 if (!*(void **)vtabptr)
6381 #------------------------------------------------------------------------------------
6383 init_string_tab_utility_code = UtilityCode(
6385 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6388 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6390 #if PY_MAJOR_VERSION < 3
6391 if (t->is_unicode) {
6392 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6393 } else if (t->intern) {
6394 *t->p = PyString_InternFromString(t->s);
6396 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6398 #else /* Python 3+ has unicode identifiers */
6399 if (t->is_unicode | t->is_str) {
6401 *t->p = PyUnicode_InternFromString(t->s);
6402 } else if (t->encoding) {
6403 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6405 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6408 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6419 #------------------------------------------------------------------------------------
6421 force_init_threads_utility_code = UtilityCode(
6423 #ifndef __PYX_FORCE_INIT_THREADS
6424 #if PY_VERSION_HEX < 0x02040200
6425 #define __PYX_FORCE_INIT_THREADS 1
6427 #define __PYX_FORCE_INIT_THREADS 0
6432 #------------------------------------------------------------------------------------
6434 # Note that cPython ignores PyTrace_EXCEPTION,
6435 # but maybe some other profilers don't.
6437 profile_utility_code = UtilityCode(proto="""
6438 #ifndef CYTHON_PROFILE
6439 #define CYTHON_PROFILE 1
6442 #ifndef CYTHON_PROFILE_REUSE_FRAME
6443 #define CYTHON_PROFILE_REUSE_FRAME 0
6448 #include "compile.h"
6449 #include "frameobject.h"
6450 #include "traceback.h"
6452 #if CYTHON_PROFILE_REUSE_FRAME
6453 #define CYTHON_FRAME_MODIFIER static
6454 #define CYTHON_FRAME_DEL
6456 #define CYTHON_FRAME_MODIFIER
6457 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6460 #define __Pyx_TraceDeclarations \\
6461 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6462 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6463 int __Pyx_use_tracing = 0;
6465 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6466 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6467 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6470 #define __Pyx_TraceException() \\
6471 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6472 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6474 PyThreadState_GET()->c_profilefunc( \\
6475 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6476 Py_DECREF(exc_info); \\
6480 #define __Pyx_TraceReturn(result) \\
6481 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6482 PyThreadState_GET()->c_profilefunc( \\
6483 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6484 CYTHON_FRAME_DEL; \\
6487 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6488 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6492 #define __Pyx_TraceDeclarations
6493 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6494 #define __Pyx_TraceException()
6495 #define __Pyx_TraceReturn(result)
6497 #endif /* CYTHON_PROFILE */
6500 "FRAME": Naming.frame_cname,
6501 "FRAME_CODE": Naming.frame_code_cname,
6507 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6508 PyFrameObject** frame,
6509 const char *funcname,
6510 const char *srcfile,
6512 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6513 if (*code == NULL) {
6514 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6515 if (*code == NULL) return 0;
6517 *frame = PyFrame_New(
6518 PyThreadState_GET(), /*PyThreadState *tstate*/
6519 *code, /*PyCodeObject *code*/
6520 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6521 0 /*PyObject *locals*/
6523 if (*frame == NULL) return 0;
6526 (*frame)->f_tstate = PyThreadState_GET();
6528 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6531 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6532 PyObject *py_srcfile = 0;
6533 PyObject *py_funcname = 0;
6534 PyCodeObject *py_code = 0;
6536 #if PY_MAJOR_VERSION < 3
6537 py_funcname = PyString_FromString(funcname);
6538 py_srcfile = PyString_FromString(srcfile);
6540 py_funcname = PyUnicode_FromString(funcname);
6541 py_srcfile = PyUnicode_FromString(srcfile);
6543 if (!py_funcname | !py_srcfile) goto bad;
6545 py_code = PyCode_New(
6546 0, /*int argcount,*/
6547 #if PY_MAJOR_VERSION >= 3
6548 0, /*int kwonlyargcount,*/
6551 0, /*int stacksize,*/
6553 %(EMPTY_BYTES)s, /*PyObject *code,*/
6554 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6555 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6556 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6557 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6558 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6559 py_srcfile, /*PyObject *filename,*/
6560 py_funcname, /*PyObject *name,*/
6561 firstlineno, /*int firstlineno,*/
6562 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6566 Py_XDECREF(py_srcfile);
6567 Py_XDECREF(py_funcname);
6572 #endif /* CYTHON_PROFILE */
6574 'EMPTY_TUPLE' : Naming.empty_tuple,
6575 'EMPTY_BYTES' : Naming.empty_bytes,
6576 "MODULE": Naming.module_cname,