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.temp_allocator = ClosureTempAllocator(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: /* raise 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 cenv = env.outer_scope # XXX: correct?
1914 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1915 cenv = cenv.outer_scope
1916 lenv = self.def_node.local_scope
1917 code.enter_cfunc_scope()
1919 code.putln('%s {' % self.header)
1920 code.put_declare_refcount_context()
1921 self.def_node.generate_keyword_list(code)
1922 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1924 code.put_setup_refcount_context(self.def_node.entry.name)
1925 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1926 Naming.cur_scope_cname,
1927 lenv.scope_class.type.declaration_code(''),
1928 lenv.scope_class.type.typeptr_cname,
1929 lenv.scope_class.type.typeptr_cname,
1930 Naming.empty_tuple))
1931 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1932 code.put_finish_refcount_context()
1933 code.putln("return NULL;");
1935 code.put_gotref(Naming.cur_scope_cname)
1937 if self.def_node.needs_outer_scope:
1938 outer_scope_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.outer_scope_cname)
1939 code.putln("%s = (%s)%s;" % (
1941 cenv.scope_class.type.declaration_code(''),
1943 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1944 code.put_giveref(outer_scope_cname)
1946 self.def_node.generate_preamble(env, code)
1948 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
1950 code.putln('%s.resume_label = 0;' % generator_cname)
1951 code.putln('%s.body = %s;' % (generator_cname, self.body_cname))
1952 code.put_giveref(Naming.cur_scope_cname)
1953 code.put_finish_refcount_context()
1954 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
1956 code.exit_cfunc_scope()
1958 class DefNode(FuncDefNode):
1959 # A Python function definition.
1961 # name string the Python name of the function
1962 # lambda_name string the internal name of a lambda 'function'
1963 # decorators [DecoratorNode] list of decorators
1964 # args [CArgDeclNode] formal arguments
1965 # star_arg PyArgDeclNode or None * argument
1966 # starstar_arg PyArgDeclNode or None ** argument
1967 # doc EncodedString or None
1969 # return_type_annotation
1970 # ExprNode or None the Py3 return type annotation
1972 # The following subnode is constructed internally
1973 # when the def statement is inside a Python class definition.
1975 # assmt AssignmentNode Function construction/assignment
1977 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1982 num_required_kw_args = 0
1983 reqd_kw_flags_cname = "0"
1986 return_type_annotation = None
1991 def __init__(self, pos, **kwds):
1992 FuncDefNode.__init__(self, pos, **kwds)
1994 for arg in self.args:
2001 self.num_kwonly_args = k
2002 self.num_required_kw_args = rk
2003 self.num_required_args = r
2005 def as_cfunction(self, cfunc=None, scope=None):
2007 error(self.star_arg.pos, "cdef function cannot have star argument")
2008 if self.starstar_arg:
2009 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
2012 for formal_arg in self.args:
2013 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
2014 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
2016 type = py_object_type,
2017 pos = formal_arg.pos))
2018 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
2020 has_varargs = False,
2021 exception_value = None,
2022 exception_check = False,
2025 is_overridable = True)
2026 cfunc = CVarDefNode(self.pos, type=cfunc_type)
2030 cfunc_type = cfunc.type
2031 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2032 error(self.pos, "wrong number of arguments")
2033 error(cfunc.pos, "previous declaration here")
2034 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2035 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2036 is_self_arg = (i == 0 and scope.is_c_class_scope))
2037 if type is None or type is PyrexTypes.py_object_type:
2038 formal_arg.type = type_arg.type
2039 formal_arg.name_declarator = name_declarator
2041 if cfunc_type.exception_value is None:
2042 exception_value = None
2044 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2045 declarator = CFuncDeclaratorNode(self.pos,
2046 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2048 has_varargs = False,
2049 exception_check = cfunc_type.exception_check,
2050 exception_value = exception_value,
2051 with_gil = cfunc_type.with_gil,
2052 nogil = cfunc_type.nogil)
2053 return CFuncDefNode(self.pos,
2055 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2056 declarator = declarator,
2059 overridable = cfunc_type.is_overridable,
2061 with_gil = cfunc_type.with_gil,
2062 nogil = cfunc_type.nogil,
2063 visibility = 'private',
2065 directive_locals = getattr(cfunc, 'directive_locals', {}))
2067 def analyse_declarations(self, env):
2068 self.is_classmethod = self.is_staticmethod = False
2070 for decorator in self.decorators:
2071 func = decorator.decorator
2073 self.is_classmethod |= func.name == 'classmethod'
2074 self.is_staticmethod |= func.name == 'staticmethod'
2076 if self.is_classmethod and env.lookup_here('classmethod'):
2077 # classmethod() was overridden - not much we can do here ...
2078 self.is_classmethod = False
2079 if self.is_staticmethod and env.lookup_here('staticmethod'):
2080 # staticmethod() was overridden - not much we can do here ...
2081 self.is_staticmethod = False
2083 if self.name == '__new__':
2084 self.is_staticmethod = 1
2086 self.analyse_argument_types(env)
2087 if self.name == '<lambda>':
2088 self.declare_lambda_function(env)
2090 self.declare_pyfunction(env)
2091 self.analyse_signature(env)
2092 self.return_type = self.entry.signature.return_type()
2093 self.create_local_scope(env)
2095 def analyse_argument_types(self, env):
2096 directive_locals = self.directive_locals = env.directives['locals']
2097 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2098 for arg in self.args:
2099 if hasattr(arg, 'name'):
2101 name_declarator = None
2103 base_type = arg.base_type.analyse(env)
2104 name_declarator, type = \
2105 arg.declarator.analyse(base_type, env)
2106 arg.name = name_declarator.name
2107 if arg.name in directive_locals:
2108 type_node = directive_locals[arg.name]
2109 other_type = type_node.analyse_as_type(env)
2110 if other_type is None:
2111 error(type_node.pos, "Not a type")
2112 elif (type is not PyrexTypes.py_object_type
2113 and not type.same_as(other_type)):
2114 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2115 error(type_node.pos, "Previous declaration here")
2118 if name_declarator and name_declarator.cname:
2120 "Python function argument cannot have C name specification")
2121 arg.type = type.as_argument_type()
2123 arg.needs_conversion = 0
2124 arg.needs_type_test = 0
2126 if arg.type.is_pyobject:
2128 arg.accept_none = True
2130 arg.accept_none = False
2131 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2132 if arg.default and arg.default.constant_result is None:
2133 # special case: def func(MyType obj = None)
2134 arg.accept_none = True
2136 # default depends on compiler directive
2137 arg.accept_none = allow_none_for_extension_args
2139 # probably just a plain 'object'
2140 arg.accept_none = True
2142 arg.accept_none = True # won't be used, but must be there
2144 error(arg.pos, "Only Python type arguments can have 'not None'")
2146 error(arg.pos, "Only Python type arguments can have 'or None'")
2148 def analyse_signature(self, env):
2149 if self.entry.is_special:
2150 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2151 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2152 # Use the simpler calling signature for zero- and one-argument functions.
2153 if self.entry.signature is TypeSlots.pyfunction_signature:
2154 if len(self.args) == 0:
2155 self.entry.signature = TypeSlots.pyfunction_noargs
2156 elif len(self.args) == 1:
2157 if self.args[0].default is None and not self.args[0].kw_only:
2158 self.entry.signature = TypeSlots.pyfunction_onearg
2159 elif self.entry.signature is TypeSlots.pymethod_signature:
2160 if len(self.args) == 1:
2161 self.entry.signature = TypeSlots.unaryfunc
2162 elif len(self.args) == 2:
2163 if self.args[1].default is None and not self.args[1].kw_only:
2164 self.entry.signature = TypeSlots.ibinaryfunc
2166 sig = self.entry.signature
2167 nfixed = sig.num_fixed_args()
2168 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2169 and len(self.args) == 0 and self.star_arg:
2170 # this is the only case where a diverging number of
2171 # arguments is not an error - when we have no explicit
2172 # 'self' parameter as in method(*args)
2173 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2174 self.self_in_stararg = 1
2177 for i in range(min(nfixed, len(self.args))):
2180 if sig.is_self_arg(i) and not self.is_staticmethod:
2181 if self.is_classmethod:
2183 arg.hdr_type = arg.type = Builtin.type_type
2186 arg.hdr_type = arg.type = env.parent_type
2187 arg.needs_conversion = 0
2189 arg.hdr_type = sig.fixed_arg_type(i)
2190 if not arg.type.same_as(arg.hdr_type):
2191 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2192 arg.needs_type_test = 1
2194 arg.needs_conversion = 1
2195 if arg.needs_conversion:
2196 arg.hdr_cname = Naming.arg_prefix + arg.name
2198 arg.hdr_cname = Naming.var_prefix + arg.name
2200 if nfixed > len(self.args):
2201 self.bad_signature()
2203 elif nfixed < len(self.args):
2204 if not sig.has_generic_args:
2205 self.bad_signature()
2206 for arg in self.args:
2207 if arg.is_generic and \
2208 (arg.type.is_extension_type or arg.type.is_builtin_type):
2209 arg.needs_type_test = 1
2211 def bad_signature(self):
2212 sig = self.entry.signature
2213 expected_str = "%d" % sig.num_fixed_args()
2214 if sig.has_generic_args:
2215 expected_str = expected_str + " or more"
2217 if name.startswith("__") and name.endswith("__"):
2218 desc = "Special method"
2222 "%s %s has wrong number of arguments "
2223 "(%d declared, %s expected)" % (
2224 desc, self.name, len(self.args), expected_str))
2226 def signature_has_nongeneric_args(self):
2227 argcount = len(self.args)
2228 if argcount == 0 or (
2229 argcount == 1 and (self.args[0].is_self_arg or
2230 self.args[0].is_type_arg)):
2234 def signature_has_generic_args(self):
2235 return self.entry.signature.has_generic_args
2237 def declare_pyfunction(self, env):
2238 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2240 entry = env.lookup_here(name)
2241 if entry and entry.type.is_cfunction and not self.is_wrapper:
2242 warning(self.pos, "Overriding cdef method with def method.", 5)
2243 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2245 prefix = env.next_id(env.scope_prefix)
2247 entry.func_cname = \
2248 Naming.pyfunc_prefix + prefix + name
2249 entry.pymethdef_cname = \
2250 Naming.pymethdef_prefix + prefix + name
2252 if self.is_generator:
2253 self.generator_body_cname = Naming.genbody_prefix + env.next_id(env.scope_prefix) + name
2255 if Options.docstrings:
2256 entry.doc = embed_position(self.pos, self.doc)
2258 Naming.funcdoc_prefix + prefix + name
2259 if entry.is_special:
2260 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2261 entry.wrapperbase_cname = None
2263 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2267 def declare_lambda_function(self, env):
2269 prefix = env.scope_prefix
2271 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2272 entry = env.declare_lambda_function(func_cname, self.pos)
2273 entry.pymethdef_cname = \
2274 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2275 entry.qualified_name = env.qualify_name(self.lambda_name)
2279 def declare_arguments(self, env):
2280 for arg in self.args:
2282 error(arg.pos, "Missing argument name")
2284 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2285 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2286 if arg.needs_conversion:
2287 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2288 if arg.type.is_pyobject:
2289 arg.entry.init = "0"
2290 arg.entry.init_to_none = 0
2292 arg.entry = self.declare_argument(env, arg)
2294 arg.entry.is_self_arg = arg.is_self_arg
2296 if arg.is_self_arg or arg.is_type_arg or \
2297 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2298 arg.entry.is_declared_generic = 1
2299 self.declare_python_arg(env, self.star_arg)
2300 self.declare_python_arg(env, self.starstar_arg)
2302 def declare_python_arg(self, env, arg):
2304 if env.directives['infer_types'] != False:
2305 type = PyrexTypes.unspecified_type
2307 type = py_object_type
2308 entry = env.declare_var(arg.name, type, arg.pos)
2311 entry.init_to_none = 0
2312 entry.xdecref_cleanup = 1
2314 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2316 def analyse_expressions(self, env):
2317 self.local_scope.directives = env.directives
2318 self.analyse_default_values(env)
2319 if self.needs_assignment_synthesis(env):
2320 # Shouldn't we be doing this at the module level too?
2321 self.synthesize_assignment_node(env)
2323 def needs_assignment_synthesis(self, env, code=None):
2324 # Should enable for module level as well, that will require more testing...
2325 if self.entry.is_anonymous:
2327 if env.is_module_scope:
2329 return env.directives['binding']
2331 return code.globalstate.directives['binding']
2332 return env.is_py_class_scope or env.is_closure_scope
2334 def synthesize_assignment_node(self, env):
2337 while genv.is_py_class_scope or genv.is_c_class_scope:
2338 genv = genv.outer_scope
2340 if genv.is_closure_scope:
2341 rhs = ExprNodes.InnerFunctionNode(
2342 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2344 rhs = ExprNodes.PyCFunctionNode(
2345 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2347 if env.is_py_class_scope:
2348 if not self.is_staticmethod and not self.is_classmethod:
2351 self.assmt = SingleAssignmentNode(self.pos,
2352 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2354 self.assmt.analyse_declarations(env)
2355 self.assmt.analyse_expressions(env)
2357 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2359 sig = self.entry.signature
2360 if sig.has_dummy_arg or self.self_in_stararg:
2361 arg_code_list.append(
2362 "PyObject *%s" % Naming.self_cname)
2363 for arg in self.args:
2364 if not arg.is_generic:
2365 if arg.is_self_arg or arg.is_type_arg:
2366 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2368 arg_code_list.append(
2369 arg.hdr_type.declaration_code(arg.hdr_cname))
2370 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2371 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2372 if sig.has_generic_args:
2373 arg_code_list.append(
2374 "PyObject *%s, PyObject *%s"
2375 % (Naming.args_cname, Naming.kwds_cname))
2376 arg_code = ", ".join(arg_code_list)
2377 dc = self.return_type.declaration_code(self.entry.func_cname)
2378 mf = " ".join(self.modifiers).upper()
2380 header = "static %s%s(%s)" % (mf, dc, arg_code)
2381 code.putln("%s; /*proto*/" % header)
2384 if (Options.docstrings and self.entry.doc and
2385 not self.entry.scope.is_property_scope and
2386 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2387 docstr = self.entry.doc
2388 if docstr.is_unicode:
2389 docstr = docstr.utf8encode()
2391 'static char %s[] = "%s";' % (
2392 self.entry.doc_cname,
2393 split_string_literal(escape_byte_string(docstr))))
2394 if self.entry.is_special:
2396 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2399 "static PyMethodDef %s = " %
2400 self.entry.pymethdef_cname)
2401 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2402 if self.is_generator:
2403 code.putln("static PyObject *%s(PyObject *%s, PyObject *%s) /* generator body */\n{" %
2404 (self.generator_body_cname, Naming.self_cname, Naming.sent_value_cname))
2405 self.generator = GeneratorWrapperNode(self,
2406 func_cname=self.entry.func_cname,
2407 body_cname=self.generator_body_cname,
2410 code.putln("%s {" % header)
2412 def generate_argument_declarations(self, env, code):
2413 for arg in self.args:
2414 if arg.is_generic: # or arg.needs_conversion:
2415 if arg.needs_conversion:
2416 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2417 elif not arg.entry.in_closure:
2418 code.put_var_declaration(arg.entry)
2420 def generate_keyword_list(self, code):
2421 if self.signature_has_generic_args() and \
2422 self.signature_has_nongeneric_args():
2424 "static PyObject **%s[] = {" %
2425 Naming.pykwdlist_cname)
2426 for arg in self.args:
2428 pystring_cname = code.intern_identifier(arg.name)
2429 code.put('&%s,' % pystring_cname)
2432 def generate_argument_parsing_code(self, env, code):
2433 # Generate fast equivalent of PyArg_ParseTuple call for
2434 # generic arguments, if any, including args/kwargs
2435 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2436 # get rid of unused argument warning
2437 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2439 old_error_label = code.new_error_label()
2440 our_error_label = code.error_label
2441 end_label = code.new_label("argument_unpacking_done")
2443 has_kwonly_args = self.num_kwonly_args > 0
2444 has_star_or_kw_args = self.star_arg is not None \
2445 or self.starstar_arg is not None or has_kwonly_args
2447 for arg in self.args:
2448 if not arg.type.is_pyobject:
2449 done = arg.type.create_from_py_utility_code(env)
2450 if not done: pass # will fail later
2452 if not self.signature_has_generic_args():
2453 if has_star_or_kw_args:
2454 error(self.pos, "This method cannot have * or keyword arguments")
2455 self.generate_argument_conversion_code(code)
2457 elif not self.signature_has_nongeneric_args():
2458 # func(*args) or func(**kw) or func(*args, **kw)
2459 self.generate_stararg_copy_code(code)
2462 positional_args = []
2464 for arg in self.args:
2465 arg_entry = arg.entry
2468 if not arg.is_self_arg and not arg.is_type_arg:
2470 kw_only_args.append(arg)
2472 positional_args.append(arg)
2474 kw_only_args.append(arg)
2475 elif not arg.is_self_arg and not arg.is_type_arg:
2476 positional_args.append(arg)
2478 self.generate_tuple_and_keyword_parsing_code(
2479 positional_args, kw_only_args, end_label, code)
2481 code.error_label = old_error_label
2482 if code.label_used(our_error_label):
2483 if not code.label_used(end_label):
2484 code.put_goto(end_label)
2485 code.put_label(our_error_label)
2486 if has_star_or_kw_args:
2487 self.generate_arg_decref(self.star_arg, code)
2488 if self.starstar_arg:
2489 if self.starstar_arg.entry.xdecref_cleanup:
2490 code.put_var_xdecref_clear(self.starstar_arg.entry)
2492 code.put_var_decref_clear(self.starstar_arg.entry)
2493 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2494 # The arguments are put into the closure one after the
2495 # other, so when type errors are found, all references in
2496 # the closure instance must be properly ref-counted to
2497 # facilitate generic closure instance deallocation. In
2498 # the case of an argument type error, it's best to just
2499 # DECREF+clear the already handled references, as this
2500 # frees their references as early as possible.
2501 for arg in self.args:
2502 if arg.type.is_pyobject and arg.entry.in_closure:
2503 code.put_var_xdecref_clear(arg.entry)
2504 if self.needs_closure:
2505 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2506 code.put_finish_refcount_context()
2507 code.putln("return %s;" % self.error_value())
2508 if code.label_used(end_label):
2509 code.put_label(end_label)
2511 # fix refnanny view on closure variables here, instead of
2512 # doing it separately for each arg parsing special case
2513 if self.star_arg and self.star_arg.entry.in_closure:
2514 code.put_var_giveref(self.star_arg.entry)
2515 if self.starstar_arg and self.starstar_arg.entry.in_closure:
2516 code.put_var_giveref(self.starstar_arg.entry)
2517 for arg in self.args:
2518 if arg.type.is_pyobject and arg.entry.in_closure:
2519 code.put_var_giveref(arg.entry)
2521 def generate_arg_assignment(self, arg, item, code):
2522 if arg.type.is_pyobject:
2524 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2526 if entry.in_closure:
2527 code.put_incref(item, PyrexTypes.py_object_type)
2528 code.putln("%s = %s;" % (entry.cname, item))
2530 func = arg.type.from_py_function
2532 code.putln("%s = %s(%s); %s" % (
2536 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2538 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2540 def generate_arg_xdecref(self, arg, code):
2542 code.put_var_xdecref_clear(arg.entry)
2544 def generate_arg_decref(self, arg, code):
2546 code.put_var_decref_clear(arg.entry)
2548 def generate_stararg_copy_code(self, code):
2549 if not self.star_arg:
2550 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2551 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2553 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2554 self.name, Naming.args_cname, self.error_value()))
2557 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2559 if self.starstar_arg:
2561 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2563 kwarg_check = "%s" % Naming.kwds_cname
2565 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2566 Naming.kwds_cname, Naming.kwds_cname)
2568 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2569 kwarg_check, Naming.kwds_cname, self.name,
2570 bool(self.starstar_arg), self.error_value()))
2572 if self.starstar_arg:
2573 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2574 self.starstar_arg.entry.cname,
2577 code.putln("if (unlikely(!%s)) return %s;" % (
2578 self.starstar_arg.entry.cname, self.error_value()))
2579 self.starstar_arg.entry.xdecref_cleanup = 0
2580 code.put_gotref(self.starstar_arg.entry.cname)
2582 if self.self_in_stararg:
2583 # need to create a new tuple with 'self' inserted as first item
2584 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2585 self.star_arg.entry.cname,
2587 self.star_arg.entry.cname))
2588 if self.starstar_arg:
2590 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2591 code.putln("return %s;" % self.error_value())
2594 code.putln("return %s;" % self.error_value())
2595 code.put_gotref(self.star_arg.entry.cname)
2596 code.put_incref(Naming.self_cname, py_object_type)
2597 code.put_giveref(Naming.self_cname)
2598 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2599 self.star_arg.entry.cname, Naming.self_cname))
2600 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2601 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2602 temp, temp, Naming.args_cname, temp))
2603 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2604 Naming.args_cname, temp))
2605 code.put_incref("item", py_object_type)
2606 code.put_giveref("item")
2607 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2608 self.star_arg.entry.cname, temp))
2610 code.funcstate.release_temp(temp)
2611 self.star_arg.entry.xdecref_cleanup = 0
2613 code.put_incref(Naming.args_cname, py_object_type)
2614 code.putln("%s = %s;" % (
2615 self.star_arg.entry.cname,
2617 self.star_arg.entry.xdecref_cleanup = 0
2619 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2620 kw_only_args, success_label, code):
2621 argtuple_error_label = code.new_label("argtuple_error")
2623 min_positional_args = self.num_required_args - self.num_required_kw_args
2624 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2625 min_positional_args -= 1
2626 max_positional_args = len(positional_args)
2627 has_fixed_positional_count = not self.star_arg and \
2628 min_positional_args == max_positional_args
2630 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2631 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2632 if self.num_required_kw_args:
2633 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2635 if self.starstar_arg or self.star_arg:
2636 self.generate_stararg_init_code(max_positional_args, code)
2638 # --- optimised code when we receive keyword arguments
2639 if self.num_required_kw_args:
2640 likely_hint = "likely"
2642 likely_hint = "unlikely"
2643 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2644 self.generate_keyword_unpacking_code(
2645 min_positional_args, max_positional_args,
2646 has_fixed_positional_count,
2647 positional_args, kw_only_args, argtuple_error_label, code)
2649 # --- optimised code when we do not receive any keyword arguments
2650 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2651 # Python raises arg tuple related errors first, so we must
2652 # check the length here
2653 if min_positional_args == max_positional_args and not self.star_arg:
2657 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2658 Naming.args_cname, compare, min_positional_args))
2659 code.put_goto(argtuple_error_label)
2661 if self.num_required_kw_args:
2662 # pure error case: keywords required but not passed
2663 if max_positional_args > min_positional_args and not self.star_arg:
2664 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2665 Naming.args_cname, max_positional_args))
2666 code.put_goto(argtuple_error_label)
2667 code.putln('} else {')
2668 for i, arg in enumerate(kw_only_args):
2670 pystring_cname = code.intern_identifier(arg.name)
2671 # required keyword-only argument missing
2672 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2675 code.putln(code.error_goto(self.pos))
2678 elif min_positional_args == max_positional_args:
2679 # parse the exact number of positional arguments from the
2681 code.putln('} else {')
2682 for i, arg in enumerate(positional_args):
2683 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2684 self.generate_arg_assignment(arg, item, code)
2685 self.generate_arg_default_assignments(code)
2688 # parse the positional arguments from the variable length
2690 code.putln('} else {')
2691 self.generate_arg_default_assignments(code)
2692 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2694 code.putln('default:')
2695 reversed_args = list(enumerate(positional_args))[::-1]
2696 for i, arg in reversed_args:
2697 if i >= min_positional_args-1:
2698 if min_positional_args > 1:
2699 code.putln('case %2d:' % (i+1)) # pure code beautification
2701 code.put('case %2d: ' % (i+1))
2702 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2703 self.generate_arg_assignment(arg, item, code)
2704 if min_positional_args == 0:
2705 code.put('case 0: ')
2706 code.putln('break;')
2708 if min_positional_args:
2709 for i in range(min_positional_args-1, -1, -1):
2710 code.putln('case %2d:' % i)
2711 code.put_goto(argtuple_error_label)
2713 code.put('default: ')
2714 code.put_goto(argtuple_error_label)
2719 if code.label_used(argtuple_error_label):
2720 code.put_goto(success_label)
2721 code.put_label(argtuple_error_label)
2722 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2723 self.name, has_fixed_positional_count,
2724 min_positional_args, max_positional_args,
2726 code.putln(code.error_goto(self.pos))
2728 def generate_arg_default_assignments(self, code):
2729 for arg in self.args:
2730 if arg.is_generic and arg.default:
2734 arg.calculate_default_value_code(code)))
2736 def generate_stararg_init_code(self, max_positional_args, code):
2737 if self.starstar_arg:
2738 self.starstar_arg.entry.xdecref_cleanup = 0
2739 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2740 self.starstar_arg.entry.cname,
2741 self.starstar_arg.entry.cname,
2742 self.error_value()))
2743 code.put_gotref(self.starstar_arg.entry.cname)
2745 self.star_arg.entry.xdecref_cleanup = 0
2746 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2748 max_positional_args))
2749 code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2750 self.star_arg.entry.cname, Naming.args_cname,
2751 max_positional_args, Naming.args_cname))
2752 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2753 if self.starstar_arg:
2754 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2755 if self.needs_closure:
2756 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2757 code.put_finish_refcount_context()
2758 code.putln('return %s;' % self.error_value())
2760 code.put_gotref(self.star_arg.entry.cname)
2761 code.putln('} else {')
2762 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2763 code.put_incref(Naming.empty_tuple, py_object_type)
2766 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2767 has_fixed_positional_count, positional_args,
2768 kw_only_args, argtuple_error_label, code):
2769 all_args = tuple(positional_args) + tuple(kw_only_args)
2770 max_args = len(all_args)
2772 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2774 # the 'values' array collects borrowed references to arguments
2775 # before doing any type coercion etc.
2776 code.putln("PyObject* values[%d] = {%s};" % (
2777 max_args, ','.join('0'*max_args)))
2779 # assign borrowed Python default values to the values array,
2780 # so that they can be overwritten by received arguments below
2781 for i, arg in enumerate(all_args):
2782 if arg.default and arg.type.is_pyobject:
2783 default_value = arg.calculate_default_value_code(code)
2784 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2786 # parse the args tuple and check that it's not too long
2787 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2789 code.putln('default:')
2790 for i in range(max_positional_args-1, -1, -1):
2791 code.put('case %2d: ' % (i+1))
2792 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2793 i, Naming.args_cname, i))
2794 code.putln('case 0: break;')
2795 if not self.star_arg:
2796 code.put('default: ') # more arguments than allowed
2797 code.put_goto(argtuple_error_label)
2800 # now fill up the positional/required arguments with values
2802 if self.num_required_args or max_positional_args > 0:
2803 last_required_arg = -1
2804 for i, arg in enumerate(all_args):
2806 last_required_arg = i
2807 if last_required_arg < max_positional_args:
2808 last_required_arg = max_positional_args-1
2809 num_required_args = self.num_required_args
2810 if max_positional_args > 0:
2811 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2812 for i, arg in enumerate(all_args[:last_required_arg+1]):
2813 if max_positional_args > 0 and i <= max_positional_args:
2814 if self.star_arg and i == max_positional_args:
2815 code.putln('default:')
2817 code.putln('case %2d:' % i)
2818 pystring_cname = code.intern_identifier(arg.name)
2821 # handled separately below
2823 code.putln('if (kw_args > 0) {')
2824 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2825 Naming.kwds_cname, pystring_cname))
2826 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2829 num_required_args -= 1
2830 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2831 i, Naming.kwds_cname, pystring_cname))
2832 code.putln('if (likely(values[%d])) kw_args--;' % i);
2833 if i < min_positional_args:
2835 # special case: we know arg 0 is missing
2837 code.put_goto(argtuple_error_label)
2839 # print the correct number of values (args or
2840 # kwargs) that were passed into positional
2841 # arguments up to this point
2842 code.putln('else {')
2843 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2844 self.name, has_fixed_positional_count,
2845 min_positional_args, max_positional_args, i))
2846 code.putln(code.error_goto(self.pos))
2849 code.putln('else {')
2850 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2851 self.name, pystring_cname))
2852 code.putln(code.error_goto(self.pos))
2854 if max_positional_args > 0:
2857 if kw_only_args and not self.starstar_arg:
2858 # unpack optional keyword-only arguments
2859 # checking for interned strings in a dict is faster than iterating
2860 # but it's too likely that we must iterate if we expect **kwargs
2862 for i, arg in enumerate(all_args[max_positional_args:]):
2863 if not arg.kw_only or not arg.default:
2865 optional_args.append((i+max_positional_args, arg))
2867 # this mimics an unrolled loop so that we can "break" out of it
2868 code.putln('while (kw_args > 0) {')
2869 code.putln('PyObject* value;')
2870 for i, arg in optional_args:
2871 pystring_cname = code.intern_identifier(arg.name)
2873 'value = PyDict_GetItem(%s, %s);' % (
2874 Naming.kwds_cname, pystring_cname))
2876 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2877 code.putln('break;')
2880 code.putln('if (unlikely(kw_args > 0)) {')
2881 # non-positional/-required kw args left in dict: default args,
2882 # kw-only args, **kwargs or error
2884 # This is sort of a catch-all: except for checking required
2885 # arguments, this will always do the right thing for unpacking
2886 # keyword arguments, so that we can concentrate on optimising
2887 # common cases above.
2888 if max_positional_args == 0:
2891 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2892 Naming.args_cname, max_positional_args,
2893 Naming.args_cname, max_positional_args))
2894 pos_arg_count = "used_pos_args"
2896 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2897 code.globalstate.use_utility_code(parse_keywords_utility_code)
2899 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2901 Naming.pykwdlist_cname,
2902 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2905 code.putln(code.error_goto(self.pos))
2908 # convert arg values to their final type and assign them
2909 for i, arg in enumerate(all_args):
2910 if arg.default and not arg.type.is_pyobject:
2911 code.putln("if (values[%d]) {" % i)
2912 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2913 if arg.default and not arg.type.is_pyobject:
2914 code.putln('} else {')
2918 arg.calculate_default_value_code(code)))
2921 def generate_argument_conversion_code(self, code):
2922 # Generate code to convert arguments from signature type to
2923 # declared type, if needed. Also copies signature arguments
2924 # into closure fields.
2925 for arg in self.args:
2926 if arg.needs_conversion:
2927 self.generate_arg_conversion(arg, code)
2928 elif arg.entry.in_closure:
2929 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2930 if arg.type.is_pyobject:
2931 code.put_var_incref(arg.entry)
2933 def generate_arg_conversion(self, arg, code):
2934 # Generate conversion code for one argument.
2935 old_type = arg.hdr_type
2937 if old_type.is_pyobject:
2939 code.putln("if (%s) {" % arg.hdr_cname)
2941 code.putln("assert(%s); {" % arg.hdr_cname)
2942 self.generate_arg_conversion_from_pyobject(arg, code)
2944 elif new_type.is_pyobject:
2945 self.generate_arg_conversion_to_pyobject(arg, code)
2947 if new_type.assignable_from(old_type):
2949 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2952 "Cannot convert 1 argument from '%s' to '%s'" %
2953 (old_type, new_type))
2955 def generate_arg_conversion_from_pyobject(self, arg, code):
2957 func = new_type.from_py_function
2958 # copied from CoerceFromPyTypeNode
2960 lhs = arg.entry.cname
2961 rhs = "%s(%s)" % (func, arg.hdr_cname)
2962 if new_type.is_enum:
2963 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2964 code.putln("%s = %s; %s" % (
2967 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2970 "Cannot convert Python object argument to type '%s'"
2973 def generate_arg_conversion_to_pyobject(self, arg, code):
2974 old_type = arg.hdr_type
2975 func = old_type.to_py_function
2977 code.putln("%s = %s(%s); %s" % (
2981 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2982 code.put_var_gotref(arg.entry)
2985 "Cannot convert argument of type '%s' to Python object"
2988 def generate_argument_type_tests(self, code):
2989 # Generate type tests for args whose signature
2990 # type is PyObject * and whose declared type is
2991 # a subtype thereof.
2992 for arg in self.args:
2993 if arg.needs_type_test:
2994 self.generate_arg_type_test(arg, code)
2995 elif not arg.accept_none and arg.type.is_pyobject:
2996 self.generate_arg_none_check(arg, code)
2998 def error_value(self):
2999 return self.entry.signature.error_value
3001 def caller_will_check_exceptions(self):
3004 class OverrideCheckNode(StatNode):
3005 # A Node for dispatching to the def method if it
3014 child_attrs = ['body']
3018 def analyse_expressions(self, env):
3019 self.args = env.arg_entries
3020 if self.py_func.is_module_scope:
3025 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3026 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3027 call_node = ExprNodes.SimpleCallNode(self.pos,
3028 function=self.func_node,
3029 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3030 self.body = ReturnStatNode(self.pos, value=call_node)
3031 self.body.analyse_expressions(env)
3033 def generate_execution_code(self, code):
3034 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3035 # Check to see if we are an extension type
3036 if self.py_func.is_module_scope:
3037 self_arg = "((PyObject *)%s)" % Naming.module_cname
3039 self_arg = "((PyObject *)%s)" % self.args[0].cname
3040 code.putln("/* Check if called by wrapper */")
3041 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3042 code.putln("/* Check if overriden in Python */")
3043 if self.py_func.is_module_scope:
3044 code.putln("else {")
3046 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3047 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3048 self.func_node.set_cname(func_node_temp)
3049 # need to get attribute manually--scope would return cdef method
3050 err = code.error_goto_if_null(func_node_temp, self.pos)
3051 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3052 func_node_temp, self_arg, interned_attr_cname, err))
3053 code.put_gotref(func_node_temp)
3054 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3055 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3056 func_node_temp, self.py_func.entry.func_cname)
3057 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3058 self.body.generate_execution_code(code)
3060 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3061 code.funcstate.release_temp(func_node_temp)
3064 class ClassDefNode(StatNode, BlockNode):
3067 class PyClassDefNode(ClassDefNode):
3068 # A Python class definition.
3070 # name EncodedString Name of the class
3071 # doc string or None
3072 # body StatNode Attribute definition code
3073 # entry Symtab.Entry
3074 # scope PyClassScope
3075 # decorators [DecoratorNode] list of decorators or None
3077 # The following subnodes are constructed internally:
3079 # dict DictNode Class dictionary or Py3 namespace
3080 # classobj ClassNode Class object
3081 # target NameNode Variable to assign class object to
3083 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3085 py3_style_class = False # Python3 style class (bases+kwargs)
3087 def __init__(self, pos, name, bases, doc, body, decorators = None,
3088 keyword_args = None, starstar_arg = None):
3089 StatNode.__init__(self, pos)
3093 self.decorators = decorators
3095 if self.doc and Options.docstrings:
3096 doc = embed_position(self.pos, self.doc)
3097 doc_node = ExprNodes.StringNode(pos, value = doc)
3100 if keyword_args or starstar_arg:
3101 self.py3_style_class = True
3103 self.metaclass = None
3104 if keyword_args and not starstar_arg:
3105 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3106 if item.key.value == 'metaclass':
3107 if self.metaclass is not None:
3108 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3109 # special case: we already know the metaclass,
3110 # so we don't need to do the "build kwargs,
3111 # find metaclass" dance at runtime
3112 self.metaclass = item.value
3113 del keyword_args.key_value_pairs[i]
3114 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3115 self.mkw = ExprNodes.KeywordArgsNode(
3116 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3118 self.mkw = ExprNodes.NullNode(pos)
3119 if self.metaclass is None:
3120 self.metaclass = ExprNodes.PyClassMetaclassNode(
3121 pos, mkw = self.mkw, bases = self.bases)
3122 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3123 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3125 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3126 bases = self.bases, dict = self.dict, doc = doc_node,
3127 metaclass = self.metaclass, mkw = self.mkw)
3129 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3130 self.metaclass = None
3133 self.classobj = ExprNodes.ClassNode(pos, name = name,
3134 bases = bases, dict = self.dict, doc = doc_node)
3135 self.target = ExprNodes.NameNode(pos, name = name)
3137 def as_cclass(self):
3139 Return this node as if it were declared as an extension class
3141 if self.py3_style_class:
3142 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3144 bases = self.classobj.bases.args
3146 base_class_name = None
3147 base_class_module = None
3148 elif len(bases) == 1:
3151 from ExprNodes import AttributeNode, NameNode
3152 while isinstance(base, AttributeNode):
3153 path.insert(0, base.attribute)
3155 if isinstance(base, NameNode):
3156 path.insert(0, base.name)
3157 base_class_name = path[-1]
3159 base_class_module = u'.'.join(path[:-1])
3161 base_class_module = None
3163 error(self.classobj.bases.args.pos, "Invalid base class")
3165 error(self.classobj.bases.args.pos, "C class may only have one base class")
3168 return CClassDefNode(self.pos,
3169 visibility = 'private',
3171 class_name = self.name,
3172 base_class_module = base_class_module,
3173 base_class_name = base_class_name,
3174 decorators = self.decorators,
3179 def create_scope(self, env):
3181 while genv.is_py_class_scope or genv.is_c_class_scope:
3182 genv = genv.outer_scope
3183 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3186 def analyse_declarations(self, env):
3187 self.target.analyse_target_declaration(env)
3188 cenv = self.create_scope(env)
3189 cenv.directives = env.directives
3190 cenv.class_obj_cname = self.target.entry.cname
3191 self.body.analyse_declarations(cenv)
3193 def analyse_expressions(self, env):
3194 if self.py3_style_class:
3195 self.bases.analyse_expressions(env)
3196 self.metaclass.analyse_expressions(env)
3197 self.mkw.analyse_expressions(env)
3198 self.dict.analyse_expressions(env)
3199 self.classobj.analyse_expressions(env)
3200 genv = env.global_scope()
3202 self.body.analyse_expressions(cenv)
3203 self.target.analyse_target_expression(env, self.classobj)
3205 def generate_function_definitions(self, env, code):
3206 self.generate_lambda_definitions(self.scope, code)
3207 self.body.generate_function_definitions(self.scope, code)
3209 def generate_execution_code(self, code):
3210 code.pyclass_stack.append(self)
3212 if self.py3_style_class:
3213 self.bases.generate_evaluation_code(code)
3214 self.mkw.generate_evaluation_code(code)
3215 self.metaclass.generate_evaluation_code(code)
3216 self.dict.generate_evaluation_code(code)
3217 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3218 self.body.generate_execution_code(code)
3219 self.classobj.generate_evaluation_code(code)
3220 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3221 self.target.generate_assignment_code(self.classobj, code)
3222 self.dict.generate_disposal_code(code)
3223 self.dict.free_temps(code)
3224 if self.py3_style_class:
3225 self.mkw.generate_disposal_code(code)
3226 self.mkw.free_temps(code)
3227 self.metaclass.generate_disposal_code(code)
3228 self.metaclass.free_temps(code)
3229 self.bases.generate_disposal_code(code)
3230 self.bases.free_temps(code)
3231 code.pyclass_stack.pop()
3233 class CClassDefNode(ClassDefNode):
3234 # An extension type definition.
3236 # visibility 'private' or 'public' or 'extern'
3237 # typedef_flag boolean
3239 # module_name string or None For import of extern type objects
3240 # class_name string Unqualified name of class
3241 # as_name string or None Name to declare as in this scope
3242 # base_class_module string or None Module containing the base class
3243 # base_class_name string or None Name of the base class
3244 # objstruct_name string or None Specified C name of object struct
3245 # typeobj_name string or None Specified C name of type object
3246 # in_pxd boolean Is in a .pxd file
3247 # decorators [DecoratorNode] list of decorators or None
3248 # doc string or None
3249 # body StatNode or None
3250 # entry Symtab.Entry
3251 # base_type PyExtensionType or None
3252 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3253 # buffer_defaults_pos
3255 child_attrs = ["body"]
3256 buffer_defaults_node = None
3257 buffer_defaults_pos = None
3258 typedef_flag = False
3260 objstruct_name = None
3264 def analyse_declarations(self, env):
3265 #print "CClassDefNode.analyse_declarations:", self.class_name
3266 #print "...visibility =", self.visibility
3267 #print "...module_name =", self.module_name
3270 if self.buffer_defaults_node:
3271 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3272 env, [], self.buffer_defaults_node,
3273 need_complete=False)
3275 buffer_defaults = None
3277 if env.in_cinclude and not self.objstruct_name:
3278 error(self.pos, "Object struct name specification required for "
3279 "C class defined in 'extern from' block")
3280 self.base_type = None
3281 # Now that module imports are cached, we need to
3282 # import the modules for extern classes.
3283 if self.module_name:
3285 for module in env.cimported_modules:
3286 if module.name == self.module_name:
3287 self.module = module
3288 if self.module is None:
3289 self.module = ModuleScope(self.module_name, None, env.context)
3290 self.module.has_extern_class = 1
3291 env.add_imported_module(self.module)
3293 if self.base_class_name:
3294 if self.base_class_module:
3295 base_class_scope = env.find_module(self.base_class_module, self.pos)
3297 base_class_scope = env
3298 if self.base_class_name == 'object':
3299 # extension classes are special and don't need to inherit from object
3300 if base_class_scope is None or base_class_scope.lookup('object') is None:
3301 self.base_class_name = None
3302 self.base_class_module = None
3303 base_class_scope = None
3304 if base_class_scope:
3305 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3306 if base_class_entry:
3307 if not base_class_entry.is_type:
3308 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3309 elif not base_class_entry.type.is_extension_type and \
3310 not (base_class_entry.type.is_builtin_type and \
3311 base_class_entry.type.objstruct_cname):
3312 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3313 elif not base_class_entry.type.is_complete():
3314 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3315 self.base_class_name, self.class_name))
3316 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3317 base_class_entry.type.scope.directives['final']:
3318 error(self.pos, "Base class '%s' of type '%s' is final" % (
3319 self.base_class_name, self.class_name))
3320 elif base_class_entry.type.is_builtin_type and \
3321 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3322 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3323 % base_class_entry.type.name)
3325 self.base_type = base_class_entry.type
3326 has_body = self.body is not None
3327 if self.module_name and self.visibility != 'extern':
3328 module_path = self.module_name.split(".")
3329 home_scope = env.find_imported_module(module_path, self.pos)
3335 if self.visibility == 'extern':
3336 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3337 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3339 self.entry = home_scope.declare_c_class(
3340 name = self.class_name,
3342 defining = has_body and self.in_pxd,
3343 implementing = has_body and not self.in_pxd,
3344 module_name = self.module_name,
3345 base_type = self.base_type,
3346 objstruct_cname = self.objstruct_name,
3347 typeobj_cname = self.typeobj_name,
3348 visibility = self.visibility,
3349 typedef_flag = self.typedef_flag,
3351 buffer_defaults = buffer_defaults)
3352 if home_scope is not env and self.visibility == 'extern':
3353 env.add_imported_entry(self.class_name, self.entry, self.pos)
3354 self.scope = scope = self.entry.type.scope
3355 if scope is not None:
3356 scope.directives = env.directives
3358 if self.doc and Options.docstrings:
3359 scope.doc = embed_position(self.pos, self.doc)
3362 self.body.analyse_declarations(scope)
3366 scope.implemented = 1
3367 env.allocate_vtable_names(self.entry)
3369 def analyse_expressions(self, env):
3371 scope = self.entry.type.scope
3372 self.body.analyse_expressions(scope)
3374 def generate_function_definitions(self, env, code):
3376 self.generate_lambda_definitions(self.scope, code)
3377 self.body.generate_function_definitions(self.scope, code)
3379 def generate_execution_code(self, code):
3380 # This is needed to generate evaluation code for
3381 # default values of method arguments.
3383 self.body.generate_execution_code(code)
3385 def annotate(self, code):
3387 self.body.annotate(code)
3390 class PropertyNode(StatNode):
3391 # Definition of a property in an extension type.
3394 # doc EncodedString or None Doc string
3397 child_attrs = ["body"]
3399 def analyse_declarations(self, env):
3400 entry = env.declare_property(self.name, self.doc, self.pos)
3402 entry.scope.directives = env.directives
3403 self.body.analyse_declarations(entry.scope)
3405 def analyse_expressions(self, env):
3406 self.body.analyse_expressions(env)
3408 def generate_function_definitions(self, env, code):
3409 self.body.generate_function_definitions(env, code)
3411 def generate_execution_code(self, code):
3414 def annotate(self, code):
3415 self.body.annotate(code)
3418 class GlobalNode(StatNode):
3419 # Global variable declaration.
3425 def analyse_declarations(self, env):
3426 for name in self.names:
3427 env.declare_global(name, self.pos)
3429 def analyse_expressions(self, env):
3432 def generate_execution_code(self, code):
3436 class ExprStatNode(StatNode):
3437 # Expression used as a statement.
3441 child_attrs = ["expr"]
3443 def analyse_declarations(self, env):
3445 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3446 func = self.expr.function.as_cython_attribute()
3447 if func == u'declare':
3448 args, kwds = self.expr.explicit_args_kwds()
3450 error(self.expr.pos, "Variable names must be specified.")
3451 for var, type_node in kwds.key_value_pairs:
3452 type = type_node.analyse_as_type(env)
3454 error(type_node.pos, "Unknown type")
3456 env.declare_var(var.value, type, var.pos, is_cdef = True)
3457 self.__class__ = PassStatNode
3459 def analyse_expressions(self, env):
3460 self.expr.result_is_used = False # hint that .result() may safely be left empty
3461 self.expr.analyse_expressions(env)
3463 def generate_execution_code(self, code):
3464 self.expr.generate_evaluation_code(code)
3465 if not self.expr.is_temp and self.expr.result():
3466 code.putln("%s;" % self.expr.result())
3467 self.expr.generate_disposal_code(code)
3468 self.expr.free_temps(code)
3470 def generate_function_definitions(self, env, code):
3471 self.expr.generate_function_definitions(env, code)
3473 def annotate(self, code):
3474 self.expr.annotate(code)
3477 class AssignmentNode(StatNode):
3478 # Abstract base class for assignment nodes.
3480 # The analyse_expressions and generate_execution_code
3481 # phases of assignments are split into two sub-phases
3482 # each, to enable all the right hand sides of a
3483 # parallel assignment to be evaluated before assigning
3484 # to any of the left hand sides.
3486 def analyse_expressions(self, env):
3487 self.analyse_types(env)
3489 # def analyse_expressions(self, env):
3490 # self.analyse_expressions_1(env)
3491 # self.analyse_expressions_2(env)
3493 def generate_execution_code(self, code):
3494 self.generate_rhs_evaluation_code(code)
3495 self.generate_assignment_code(code)
3498 class SingleAssignmentNode(AssignmentNode):
3499 # The simplest case:
3503 # lhs ExprNode Left hand side
3504 # rhs ExprNode Right hand side
3505 # first bool Is this guaranteed the first assignment to lhs?
3507 child_attrs = ["lhs", "rhs"]
3509 declaration_only = False
3511 def analyse_declarations(self, env):
3514 # handle declarations of the form x = cython.foo()
3515 if isinstance(self.rhs, ExprNodes.CallNode):
3516 func_name = self.rhs.function.as_cython_attribute()
3518 args, kwds = self.rhs.explicit_args_kwds()
3520 if func_name in ['declare', 'typedef']:
3521 if len(args) > 2 or kwds is not None:
3522 error(self.rhs.pos, "Can only declare one type at a time.")
3524 type = args[0].analyse_as_type(env)
3526 error(args[0].pos, "Unknown type")
3529 if func_name == 'declare':
3530 if isinstance(lhs, ExprNodes.NameNode):
3531 vars = [(lhs.name, lhs.pos)]
3532 elif isinstance(lhs, ExprNodes.TupleNode):
3533 vars = [(var.name, var.pos) for var in lhs.args]
3535 error(lhs.pos, "Invalid declaration")
3537 for var, pos in vars:
3538 env.declare_var(var, type, pos, is_cdef = True)
3543 self.declaration_only = True
3545 self.declaration_only = True
3546 if not isinstance(lhs, ExprNodes.NameNode):
3547 error(lhs.pos, "Invalid declaration.")
3548 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3550 elif func_name in ['struct', 'union']:
3551 self.declaration_only = True
3552 if len(args) > 0 or kwds is None:
3553 error(self.rhs.pos, "Struct or union members must be given by name.")
3556 for member, type_node in kwds.key_value_pairs:
3557 type = type_node.analyse_as_type(env)
3559 error(type_node.pos, "Unknown type")
3561 members.append((member.value, type, member.pos))
3562 if len(members) < len(kwds.key_value_pairs):
3564 if not isinstance(self.lhs, ExprNodes.NameNode):
3565 error(self.lhs.pos, "Invalid declaration.")
3566 name = self.lhs.name
3567 scope = StructOrUnionScope(name)
3568 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3569 for member, type, pos in members:
3570 scope.declare_var(member, type, pos)
3572 if self.declaration_only:
3575 self.lhs.analyse_target_declaration(env)
3577 def analyse_types(self, env, use_temp = 0):
3578 self.rhs.analyse_types(env)
3579 self.lhs.analyse_target_types(env)
3580 self.lhs.gil_assignment_check(env)
3581 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3583 self.rhs = self.rhs.coerce_to_temp(env)
3585 def generate_rhs_evaluation_code(self, code):
3586 self.rhs.generate_evaluation_code(code)
3588 def generate_assignment_code(self, code):
3589 self.lhs.generate_assignment_code(self.rhs, code)
3591 def generate_function_definitions(self, env, code):
3592 self.rhs.generate_function_definitions(env, code)
3594 def annotate(self, code):
3595 self.lhs.annotate(code)
3596 self.rhs.annotate(code)
3599 class CascadedAssignmentNode(AssignmentNode):
3600 # An assignment with multiple left hand sides:
3604 # lhs_list [ExprNode] Left hand sides
3605 # rhs ExprNode Right hand sides
3609 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3611 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3612 coerced_rhs_list = None
3614 def analyse_declarations(self, env):
3615 for lhs in self.lhs_list:
3616 lhs.analyse_target_declaration(env)
3618 def analyse_types(self, env, use_temp = 0):
3619 self.rhs.analyse_types(env)
3620 if not self.rhs.is_simple():
3622 self.rhs = self.rhs.coerce_to_temp(env)
3624 self.rhs = self.rhs.coerce_to_simple(env)
3625 from ExprNodes import CloneNode
3626 self.coerced_rhs_list = []
3627 for lhs in self.lhs_list:
3628 lhs.analyse_target_types(env)
3629 lhs.gil_assignment_check(env)
3630 rhs = CloneNode(self.rhs)
3631 rhs = rhs.coerce_to(lhs.type, env)
3632 self.coerced_rhs_list.append(rhs)
3634 def generate_rhs_evaluation_code(self, code):
3635 self.rhs.generate_evaluation_code(code)
3637 def generate_assignment_code(self, code):
3638 for i in range(len(self.lhs_list)):
3639 lhs = self.lhs_list[i]
3640 rhs = self.coerced_rhs_list[i]
3641 rhs.generate_evaluation_code(code)
3642 lhs.generate_assignment_code(rhs, code)
3643 # Assignment has disposed of the cloned RHS
3644 self.rhs.generate_disposal_code(code)
3645 self.rhs.free_temps(code)
3647 def generate_function_definitions(self, env, code):
3648 self.rhs.generate_function_definitions(env, code)
3650 def annotate(self, code):
3651 for i in range(len(self.lhs_list)):
3652 lhs = self.lhs_list[i].annotate(code)
3653 rhs = self.coerced_rhs_list[i].annotate(code)
3654 self.rhs.annotate(code)
3657 class ParallelAssignmentNode(AssignmentNode):
3658 # A combined packing/unpacking assignment:
3662 # This has been rearranged by the parser into
3664 # a = d ; b = e ; c = f
3666 # but we must evaluate all the right hand sides
3667 # before assigning to any of the left hand sides.
3669 # stats [AssignmentNode] The constituent assignments
3671 child_attrs = ["stats"]
3673 def analyse_declarations(self, env):
3674 for stat in self.stats:
3675 stat.analyse_declarations(env)
3677 def analyse_expressions(self, env):
3678 for stat in self.stats:
3679 stat.analyse_types(env, use_temp = 1)
3681 # def analyse_expressions(self, env):
3682 # for stat in self.stats:
3683 # stat.analyse_expressions_1(env, use_temp = 1)
3684 # for stat in self.stats:
3685 # stat.analyse_expressions_2(env)
3687 def generate_execution_code(self, code):
3688 for stat in self.stats:
3689 stat.generate_rhs_evaluation_code(code)
3690 for stat in self.stats:
3691 stat.generate_assignment_code(code)
3693 def generate_function_definitions(self, env, code):
3694 for stat in self.stats:
3695 stat.generate_function_definitions(env, code)
3697 def annotate(self, code):
3698 for stat in self.stats:
3702 class InPlaceAssignmentNode(AssignmentNode):
3703 # An in place arithmetic operand:
3709 # lhs ExprNode Left hand side
3710 # rhs ExprNode Right hand side
3711 # op char one of "+-*/%^&|"
3712 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3714 # This code is a bit tricky because in order to obey Python
3715 # semantics the sub-expressions (e.g. indices) of the lhs must
3716 # not be evaluated twice. So we must re-use the values calculated
3717 # in evaluation phase for the assignment phase as well.
3718 # Fortunately, the type of the lhs node is fairly constrained
3719 # (it must be a NameNode, AttributeNode, or IndexNode).
3721 child_attrs = ["lhs", "rhs"]
3723 def analyse_declarations(self, env):
3724 self.lhs.analyse_target_declaration(env)
3726 def analyse_types(self, env):
3727 self.rhs.analyse_types(env)
3728 self.lhs.analyse_target_types(env)
3730 def generate_execution_code(self, code):
3732 self.rhs.generate_evaluation_code(code)
3733 self.lhs.generate_subexpr_evaluation_code(code)
3734 c_op = self.operator
3738 error(self.pos, "No C inplace power operator")
3739 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3740 if self.lhs.type.is_pyobject:
3741 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3742 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3743 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3744 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3747 # TODO: make sure overload is declared
3748 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3749 self.lhs.generate_subexpr_disposal_code(code)
3750 self.lhs.free_subexpr_temps(code)
3751 self.rhs.generate_disposal_code(code)
3752 self.rhs.free_temps(code)
3754 def annotate(self, code):
3755 self.lhs.annotate(code)
3756 self.rhs.annotate(code)
3758 def create_binop_node(self):
3760 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3763 class PrintStatNode(StatNode):
3766 # arg_tuple TupleNode
3767 # stream ExprNode or None (stdout)
3768 # append_newline boolean
3770 child_attrs = ["arg_tuple", "stream"]
3772 def analyse_expressions(self, env):
3774 self.stream.analyse_expressions(env)
3775 self.stream = self.stream.coerce_to_pyobject(env)
3776 self.arg_tuple.analyse_expressions(env)
3777 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3778 env.use_utility_code(printing_utility_code)
3779 if len(self.arg_tuple.args) == 1 and self.append_newline:
3780 env.use_utility_code(printing_one_utility_code)
3782 nogil_check = Node.gil_error
3783 gil_message = "Python print statement"
3785 def generate_execution_code(self, code):
3787 self.stream.generate_evaluation_code(code)
3788 stream_result = self.stream.py_result()
3791 if len(self.arg_tuple.args) == 1 and self.append_newline:
3792 arg = self.arg_tuple.args[0]
3793 arg.generate_evaluation_code(code)
3796 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3799 code.error_goto(self.pos)))
3800 arg.generate_disposal_code(code)
3801 arg.free_temps(code)
3803 self.arg_tuple.generate_evaluation_code(code)
3805 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3807 self.arg_tuple.py_result(),
3808 self.append_newline,
3809 code.error_goto(self.pos)))
3810 self.arg_tuple.generate_disposal_code(code)
3811 self.arg_tuple.free_temps(code)
3814 self.stream.generate_disposal_code(code)
3815 self.stream.free_temps(code)
3817 def generate_function_definitions(self, env, code):
3819 self.stream.generate_function_definitions(env, code)
3820 self.arg_tuple.generate_function_definitions(env, code)
3822 def annotate(self, code):
3824 self.stream.annotate(code)
3825 self.arg_tuple.annotate(code)
3828 class ExecStatNode(StatNode):
3833 child_attrs = ["args"]
3835 def analyse_expressions(self, env):
3836 for i, arg in enumerate(self.args):
3837 arg.analyse_expressions(env)
3838 arg = arg.coerce_to_pyobject(env)
3840 env.use_utility_code(Builtin.pyexec_utility_code)
3842 nogil_check = Node.gil_error
3843 gil_message = "Python exec statement"
3845 def generate_execution_code(self, code):
3847 for arg in self.args:
3848 arg.generate_evaluation_code(code)
3849 args.append( arg.py_result() )
3850 args = tuple(args + ['0', '0'][:3-len(args)])
3851 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3852 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3853 (temp_result,) + args))
3854 for arg in self.args:
3855 arg.generate_disposal_code(code)
3856 arg.free_temps(code)
3858 code.error_goto_if_null(temp_result, self.pos))
3859 code.put_gotref(temp_result)
3860 code.put_decref_clear(temp_result, py_object_type)
3861 code.funcstate.release_temp(temp_result)
3863 def annotate(self, code):
3864 for arg in self.args:
3868 class DelStatNode(StatNode):
3873 child_attrs = ["args"]
3875 def analyse_declarations(self, env):
3876 for arg in self.args:
3877 arg.analyse_target_declaration(env)
3879 def analyse_expressions(self, env):
3880 for arg in self.args:
3881 arg.analyse_target_expression(env, None)
3882 if arg.type.is_pyobject:
3884 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3886 elif arg.type.is_cpp_class:
3887 error(arg.pos, "Deletion of non-heap C++ object")
3889 error(arg.pos, "Deletion of non-Python, non-C++ object")
3890 #arg.release_target_temp(env)
3892 def nogil_check(self, env):
3893 for arg in self.args:
3894 if arg.type.is_pyobject:
3897 gil_message = "Deleting Python object"
3899 def generate_execution_code(self, code):
3900 for arg in self.args:
3901 if arg.type.is_pyobject:
3902 arg.generate_deletion_code(code)
3903 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3904 arg.generate_result_code(code)
3905 code.putln("delete %s;" % arg.result())
3906 # else error reported earlier
3908 def annotate(self, code):
3909 for arg in self.args:
3913 class PassStatNode(StatNode):
3918 def analyse_expressions(self, env):
3921 def generate_execution_code(self, code):
3925 class BreakStatNode(StatNode):
3929 def analyse_expressions(self, env):
3932 def generate_execution_code(self, code):
3933 if not code.break_label:
3934 error(self.pos, "break statement not inside loop")
3936 code.put_goto(code.break_label)
3939 class ContinueStatNode(StatNode):
3943 def analyse_expressions(self, env):
3946 def generate_execution_code(self, code):
3947 if code.funcstate.in_try_finally:
3948 error(self.pos, "continue statement inside try of try...finally")
3949 elif not code.continue_label:
3950 error(self.pos, "continue statement not inside loop")
3952 code.put_goto(code.continue_label)
3955 class ReturnStatNode(StatNode):
3958 # value ExprNode or None
3959 # return_type PyrexType
3961 child_attrs = ["value"]
3963 def analyse_expressions(self, env):
3964 return_type = env.return_type
3965 self.return_type = return_type
3967 error(self.pos, "Return not inside a function body")
3970 self.value.analyse_types(env)
3971 if return_type.is_void or return_type.is_returncode:
3972 error(self.value.pos,
3973 "Return with value in void function")
3975 self.value = self.value.coerce_to(env.return_type, env)
3977 if (not return_type.is_void
3978 and not return_type.is_pyobject
3979 and not return_type.is_returncode):
3980 error(self.pos, "Return value required")
3982 def nogil_check(self, env):
3983 if self.return_type.is_pyobject:
3986 gil_message = "Returning Python object"
3988 def generate_execution_code(self, code):
3989 code.mark_pos(self.pos)
3990 if not self.return_type:
3991 # error reported earlier
3993 if self.return_type.is_pyobject:
3994 code.put_xdecref(Naming.retval_cname,
3997 self.value.generate_evaluation_code(code)
3998 self.value.make_owned_reference(code)
4001 Naming.retval_cname,
4002 self.value.result_as(self.return_type)))
4003 self.value.generate_post_assignment_code(code)
4004 self.value.free_temps(code)
4006 if self.return_type.is_pyobject:
4007 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4008 elif self.return_type.is_returncode:
4011 Naming.retval_cname,
4012 self.return_type.default_value))
4013 for cname, type in code.funcstate.temps_holding_reference():
4014 code.put_decref_clear(cname, type)
4015 code.put_goto(code.return_label)
4017 def generate_function_definitions(self, env, code):
4018 if self.value is not None:
4019 self.value.generate_function_definitions(env, code)
4021 def annotate(self, code):
4023 self.value.annotate(code)
4026 class RaiseStatNode(StatNode):
4029 # exc_type ExprNode or None
4030 # exc_value ExprNode or None
4031 # exc_tb ExprNode or None
4033 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4035 def analyse_expressions(self, env):
4037 self.exc_type.analyse_types(env)
4038 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4040 self.exc_value.analyse_types(env)
4041 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4043 self.exc_tb.analyse_types(env)
4044 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4045 env.use_utility_code(raise_utility_code)
4047 nogil_check = Node.gil_error
4048 gil_message = "Raising exception"
4050 def generate_execution_code(self, code):
4052 self.exc_type.generate_evaluation_code(code)
4053 type_code = self.exc_type.py_result()
4057 self.exc_value.generate_evaluation_code(code)
4058 value_code = self.exc_value.py_result()
4062 self.exc_tb.generate_evaluation_code(code)
4063 tb_code = self.exc_tb.py_result()
4067 "__Pyx_Raise(%s, %s, %s);" % (
4071 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4073 obj.generate_disposal_code(code)
4074 obj.free_temps(code)
4076 code.error_goto(self.pos))
4078 def generate_function_definitions(self, env, code):
4079 if self.exc_type is not None:
4080 self.exc_type.generate_function_definitions(env, code)
4081 if self.exc_value is not None:
4082 self.exc_value.generate_function_definitions(env, code)
4083 if self.exc_tb is not None:
4084 self.exc_tb.generate_function_definitions(env, code)
4086 def annotate(self, code):
4088 self.exc_type.annotate(code)
4090 self.exc_value.annotate(code)
4092 self.exc_tb.annotate(code)
4095 class ReraiseStatNode(StatNode):
4099 def analyse_expressions(self, env):
4100 env.use_utility_code(restore_exception_utility_code)
4102 nogil_check = Node.gil_error
4103 gil_message = "Raising exception"
4105 def generate_execution_code(self, code):
4106 vars = code.funcstate.exc_vars
4108 for varname in vars:
4109 code.put_giveref(varname)
4110 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4111 for varname in vars:
4112 code.put("%s = 0; " % varname)
4114 code.putln(code.error_goto(self.pos))
4116 error(self.pos, "Reraise not inside except clause")
4119 class AssertStatNode(StatNode):
4123 # value ExprNode or None
4125 child_attrs = ["cond", "value"]
4127 def analyse_expressions(self, env):
4128 self.cond = self.cond.analyse_boolean_expression(env)
4130 self.value.analyse_types(env)
4131 self.value = self.value.coerce_to_pyobject(env)
4133 nogil_check = Node.gil_error
4134 gil_message = "Raising exception"
4136 def generate_execution_code(self, code):
4137 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4138 self.cond.generate_evaluation_code(code)
4140 "if (unlikely(!%s)) {" %
4143 self.value.generate_evaluation_code(code)
4145 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4146 self.value.py_result())
4147 self.value.generate_disposal_code(code)
4148 self.value.free_temps(code)
4151 "PyErr_SetNone(PyExc_AssertionError);")
4153 code.error_goto(self.pos))
4156 self.cond.generate_disposal_code(code)
4157 self.cond.free_temps(code)
4158 code.putln("#endif")
4160 def generate_function_definitions(self, env, code):
4161 self.cond.generate_function_definitions(env, code)
4162 if self.value is not None:
4163 self.value.generate_function_definitions(env, code)
4165 def annotate(self, code):
4166 self.cond.annotate(code)
4168 self.value.annotate(code)
4171 class IfStatNode(StatNode):
4174 # if_clauses [IfClauseNode]
4175 # else_clause StatNode or None
4177 child_attrs = ["if_clauses", "else_clause"]
4179 def analyse_control_flow(self, env):
4180 env.start_branching(self.pos)
4181 for if_clause in self.if_clauses:
4182 if_clause.analyse_control_flow(env)
4183 env.next_branch(if_clause.end_pos())
4184 if self.else_clause:
4185 self.else_clause.analyse_control_flow(env)
4186 env.finish_branching(self.end_pos())
4188 def analyse_declarations(self, env):
4189 for if_clause in self.if_clauses:
4190 if_clause.analyse_declarations(env)
4191 if self.else_clause:
4192 self.else_clause.analyse_declarations(env)
4194 def analyse_expressions(self, env):
4195 for if_clause in self.if_clauses:
4196 if_clause.analyse_expressions(env)
4197 if self.else_clause:
4198 self.else_clause.analyse_expressions(env)
4200 def generate_execution_code(self, code):
4201 code.mark_pos(self.pos)
4202 end_label = code.new_label()
4203 for if_clause in self.if_clauses:
4204 if_clause.generate_execution_code(code, end_label)
4205 if self.else_clause:
4206 code.putln("/*else*/ {")
4207 self.else_clause.generate_execution_code(code)
4209 code.put_label(end_label)
4211 def generate_function_definitions(self, env, code):
4212 for clause in self.if_clauses:
4213 clause.generate_function_definitions(env, code)
4214 if self.else_clause is not None:
4215 self.else_clause.generate_function_definitions(env, code)
4217 def annotate(self, code):
4218 for if_clause in self.if_clauses:
4219 if_clause.annotate(code)
4220 if self.else_clause:
4221 self.else_clause.annotate(code)
4224 class IfClauseNode(Node):
4225 # if or elif clause in an if statement
4227 # condition ExprNode
4230 child_attrs = ["condition", "body"]
4232 def analyse_control_flow(self, env):
4233 self.body.analyse_control_flow(env)
4235 def analyse_declarations(self, env):
4236 self.body.analyse_declarations(env)
4238 def analyse_expressions(self, env):
4240 self.condition.analyse_temp_boolean_expression(env)
4241 self.body.analyse_expressions(env)
4243 def get_constant_condition_result(self):
4244 if self.condition.has_constant_result():
4245 return bool(self.condition.constant_result)
4249 def generate_execution_code(self, code, end_label):
4250 self.condition.generate_evaluation_code(code)
4253 self.condition.result())
4254 self.condition.generate_disposal_code(code)
4255 self.condition.free_temps(code)
4256 self.body.generate_execution_code(code)
4257 code.put_goto(end_label)
4260 def generate_function_definitions(self, env, code):
4261 self.condition.generate_function_definitions(env, code)
4262 self.body.generate_function_definitions(env, code)
4264 def annotate(self, code):
4265 self.condition.annotate(code)
4266 self.body.annotate(code)
4269 class SwitchCaseNode(StatNode):
4270 # Generated in the optimization of an if-elif-else node
4272 # conditions [ExprNode]
4275 child_attrs = ['conditions', 'body']
4277 def generate_execution_code(self, code):
4278 for cond in self.conditions:
4279 code.mark_pos(cond.pos)
4280 cond.generate_evaluation_code(code)
4281 code.putln("case %s:" % cond.result())
4282 self.body.generate_execution_code(code)
4283 code.putln("break;")
4285 def generate_function_definitions(self, env, code):
4286 for cond in self.conditions:
4287 cond.generate_function_definitions(env, code)
4288 self.body.generate_function_definitions(env, code)
4290 def annotate(self, code):
4291 for cond in self.conditions:
4293 self.body.annotate(code)
4295 class SwitchStatNode(StatNode):
4296 # Generated in the optimization of an if-elif-else node
4299 # cases [SwitchCaseNode]
4300 # else_clause StatNode or None
4302 child_attrs = ['test', 'cases', 'else_clause']
4304 def generate_execution_code(self, code):
4305 self.test.generate_evaluation_code(code)
4306 code.putln("switch (%s) {" % self.test.result())
4307 for case in self.cases:
4308 case.generate_execution_code(code)
4309 if self.else_clause is not None:
4310 code.putln("default:")
4311 self.else_clause.generate_execution_code(code)
4312 code.putln("break;")
4315 def generate_function_definitions(self, env, code):
4316 self.test.generate_function_definitions(env, code)
4317 for case in self.cases:
4318 case.generate_function_definitions(env, code)
4319 if self.else_clause is not None:
4320 self.else_clause.generate_function_definitions(env, code)
4322 def annotate(self, code):
4323 self.test.annotate(code)
4324 for case in self.cases:
4326 if self.else_clause is not None:
4327 self.else_clause.annotate(code)
4329 class LoopNode(object):
4331 def analyse_control_flow(self, env):
4332 env.start_branching(self.pos)
4333 self.body.analyse_control_flow(env)
4334 env.next_branch(self.body.end_pos())
4335 if self.else_clause:
4336 self.else_clause.analyse_control_flow(env)
4337 env.finish_branching(self.end_pos())
4340 class WhileStatNode(LoopNode, StatNode):
4343 # condition ExprNode
4345 # else_clause StatNode
4347 child_attrs = ["condition", "body", "else_clause"]
4349 def analyse_declarations(self, env):
4350 self.body.analyse_declarations(env)
4351 if self.else_clause:
4352 self.else_clause.analyse_declarations(env)
4354 def analyse_expressions(self, env):
4356 self.condition.analyse_temp_boolean_expression(env)
4357 self.body.analyse_expressions(env)
4358 if self.else_clause:
4359 self.else_clause.analyse_expressions(env)
4361 def generate_execution_code(self, code):
4362 old_loop_labels = code.new_loop_labels()
4365 self.condition.generate_evaluation_code(code)
4366 self.condition.generate_disposal_code(code)
4369 self.condition.result())
4370 self.condition.free_temps(code)
4371 self.body.generate_execution_code(code)
4372 code.put_label(code.continue_label)
4374 break_label = code.break_label
4375 code.set_loop_labels(old_loop_labels)
4376 if self.else_clause:
4377 code.putln("/*else*/ {")
4378 self.else_clause.generate_execution_code(code)
4380 code.put_label(break_label)
4382 def generate_function_definitions(self, env, code):
4383 self.condition.generate_function_definitions(env, code)
4384 self.body.generate_function_definitions(env, code)
4385 if self.else_clause is not None:
4386 self.else_clause.generate_function_definitions(env, code)
4388 def annotate(self, code):
4389 self.condition.annotate(code)
4390 self.body.annotate(code)
4391 if self.else_clause:
4392 self.else_clause.annotate(code)
4395 def ForStatNode(pos, **kw):
4396 if 'iterator' in kw:
4397 return ForInStatNode(pos, **kw)
4399 return ForFromStatNode(pos, **kw)
4401 class ForInStatNode(LoopNode, StatNode):
4405 # iterator IteratorNode
4407 # else_clause StatNode
4408 # item NextNode used internally
4410 child_attrs = ["target", "iterator", "body", "else_clause"]
4413 def analyse_declarations(self, env):
4414 self.target.analyse_target_declaration(env)
4415 self.body.analyse_declarations(env)
4416 if self.else_clause:
4417 self.else_clause.analyse_declarations(env)
4419 def analyse_expressions(self, env):
4421 self.target.analyse_target_types(env)
4422 self.iterator.analyse_expressions(env)
4423 self.item = ExprNodes.NextNode(self.iterator, env)
4424 self.item = self.item.coerce_to(self.target.type, env)
4425 self.body.analyse_expressions(env)
4426 if self.else_clause:
4427 self.else_clause.analyse_expressions(env)
4429 def generate_execution_code(self, code):
4430 old_loop_labels = code.new_loop_labels()
4431 self.iterator.allocate_counter_temp(code)
4432 self.iterator.generate_evaluation_code(code)
4435 self.item.generate_evaluation_code(code)
4436 self.target.generate_assignment_code(self.item, code)
4437 self.body.generate_execution_code(code)
4438 code.put_label(code.continue_label)
4441 break_label = code.break_label
4442 code.set_loop_labels(old_loop_labels)
4444 if self.else_clause:
4445 # in nested loops, the 'else' block can contain a
4446 # 'continue' statement for the outer loop, but we may need
4447 # to generate cleanup code before taking that path, so we
4449 orig_continue_label = code.continue_label
4450 code.continue_label = code.new_label('outer_continue')
4452 code.putln("/*else*/ {")
4453 self.else_clause.generate_execution_code(code)
4456 if code.label_used(code.continue_label):
4457 code.put_goto(break_label)
4458 code.put_label(code.continue_label)
4459 self.iterator.generate_disposal_code(code)
4460 code.put_goto(orig_continue_label)
4461 code.set_loop_labels(old_loop_labels)
4463 if code.label_used(break_label):
4464 code.put_label(break_label)
4465 self.iterator.release_counter_temp(code)
4466 self.iterator.generate_disposal_code(code)
4467 self.iterator.free_temps(code)
4469 def generate_function_definitions(self, env, code):
4470 self.target.generate_function_definitions(env, code)
4471 self.iterator.generate_function_definitions(env, code)
4472 self.body.generate_function_definitions(env, code)
4473 if self.else_clause is not None:
4474 self.else_clause.generate_function_definitions(env, code)
4476 def annotate(self, code):
4477 self.target.annotate(code)
4478 self.iterator.annotate(code)
4479 self.body.annotate(code)
4480 if self.else_clause:
4481 self.else_clause.annotate(code)
4482 self.item.annotate(code)
4485 class ForFromStatNode(LoopNode, StatNode):
4486 # for name from expr rel name rel expr
4493 # step ExprNode or None
4495 # else_clause StatNode or None
4501 # loopvar_node ExprNode (usually a NameNode or temp node)
4502 # py_loopvar_node PyTempNode or None
4503 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4505 is_py_target = False
4507 py_loopvar_node = None
4510 gil_message = "For-loop using object bounds or target"
4512 def nogil_check(self, env):
4513 for x in (self.target, self.bound1, self.bound2):
4514 if x.type.is_pyobject:
4517 def analyse_declarations(self, env):
4518 self.target.analyse_target_declaration(env)
4519 self.body.analyse_declarations(env)
4520 if self.else_clause:
4521 self.else_clause.analyse_declarations(env)
4523 def analyse_expressions(self, env):
4525 self.target.analyse_target_types(env)
4526 self.bound1.analyse_types(env)
4527 self.bound2.analyse_types(env)
4528 if self.step is not None:
4529 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4530 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4531 self.step.analyse_types(env)
4533 target_type = self.target.type
4534 if self.target.type.is_numeric:
4535 loop_type = self.target.type
4537 loop_type = PyrexTypes.c_int_type
4538 if not self.bound1.type.is_pyobject:
4539 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4540 if not self.bound2.type.is_pyobject:
4541 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4542 if self.step is not None and not self.step.type.is_pyobject:
4543 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4544 self.bound1 = self.bound1.coerce_to(loop_type, env)
4545 self.bound2 = self.bound2.coerce_to(loop_type, env)
4546 if not self.bound2.is_literal:
4547 self.bound2 = self.bound2.coerce_to_temp(env)
4548 if self.step is not None:
4549 self.step = self.step.coerce_to(loop_type, env)
4550 if not self.step.is_literal:
4551 self.step = self.step.coerce_to_temp(env)
4553 target_type = self.target.type
4554 if not (target_type.is_pyobject or target_type.is_numeric):
4555 error(self.target.pos,
4556 "for-from loop variable must be c numeric type or Python object")
4557 if target_type.is_numeric:
4558 self.is_py_target = False
4559 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4560 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4561 self.loopvar_node = self.target
4562 self.py_loopvar_node = None
4564 self.is_py_target = True
4565 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4566 self.loopvar_node = c_loopvar_node
4567 self.py_loopvar_node = \
4568 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4569 self.body.analyse_expressions(env)
4570 if self.else_clause:
4571 self.else_clause.analyse_expressions(env)
4573 def generate_execution_code(self, code):
4574 old_loop_labels = code.new_loop_labels()
4575 from_range = self.from_range
4576 self.bound1.generate_evaluation_code(code)
4577 self.bound2.generate_evaluation_code(code)
4578 offset, incop = self.relation_table[self.relation1]
4579 if self.step is not None:
4580 self.step.generate_evaluation_code(code)
4581 step = self.step.result()
4582 incop = "%s=%s" % (incop[0], step)
4584 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4585 self.loopvar_node.allocate(code)
4586 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4587 self.py_loopvar_node.allocate(code)
4589 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4591 loopvar_name = self.loopvar_node.result()
4593 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4595 self.bound1.result(), offset,
4596 loopvar_name, self.relation2, self.bound2.result(),
4597 loopvar_name, incop))
4598 if self.py_loopvar_node:
4599 self.py_loopvar_node.generate_evaluation_code(code)
4600 self.target.generate_assignment_code(self.py_loopvar_node, code)
4602 code.putln("%s = %s;" % (
4603 self.target.result(), loopvar_name))
4604 self.body.generate_execution_code(code)
4605 code.put_label(code.continue_label)
4606 if self.py_loopvar_node:
4607 # This mess is to make for..from loops with python targets behave
4608 # exactly like those with C targets with regards to re-assignment
4609 # of the loop variable.
4611 if self.target.entry.is_pyglobal:
4612 # We know target is a NameNode, this is the only ugly case.
4613 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4614 target_node.allocate(code)
4615 interned_cname = code.intern_identifier(self.target.entry.name)
4616 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4617 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4618 target_node.result(),
4619 Naming.module_cname,
4621 code.error_goto_if_null(target_node.result(), self.target.pos)))
4622 code.put_gotref(target_node.result())
4624 target_node = self.target
4625 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4626 from_py_node.temp_code = loopvar_name
4627 from_py_node.generate_result_code(code)
4628 if self.target.entry.is_pyglobal:
4629 code.put_decref(target_node.result(), target_node.type)
4630 target_node.release(code)
4632 if self.py_loopvar_node:
4633 # This is potentially wasteful, but we don't want the semantics to
4634 # depend on whether or not the loop is a python type.
4635 self.py_loopvar_node.generate_evaluation_code(code)
4636 self.target.generate_assignment_code(self.py_loopvar_node, code)
4638 code.funcstate.release_temp(loopvar_name)
4639 break_label = code.break_label
4640 code.set_loop_labels(old_loop_labels)
4641 if self.else_clause:
4642 code.putln("/*else*/ {")
4643 self.else_clause.generate_execution_code(code)
4645 code.put_label(break_label)
4646 self.bound1.generate_disposal_code(code)
4647 self.bound1.free_temps(code)
4648 self.bound2.generate_disposal_code(code)
4649 self.bound2.free_temps(code)
4650 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4651 self.loopvar_node.release(code)
4652 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4653 self.py_loopvar_node.release(code)
4654 if self.step is not None:
4655 self.step.generate_disposal_code(code)
4656 self.step.free_temps(code)
4659 # {relop : (initial offset, increment op)}
4666 def generate_function_definitions(self, env, code):
4667 self.target.generate_function_definitions(env, code)
4668 self.bound1.generate_function_definitions(env, code)
4669 self.bound2.generate_function_definitions(env, code)
4670 if self.step is not None:
4671 self.step.generate_function_definitions(env, code)
4672 self.body.generate_function_definitions(env, code)
4673 if self.else_clause is not None:
4674 self.else_clause.generate_function_definitions(env, code)
4676 def annotate(self, code):
4677 self.target.annotate(code)
4678 self.bound1.annotate(code)
4679 self.bound2.annotate(code)
4681 self.step.annotate(code)
4682 self.body.annotate(code)
4683 if self.else_clause:
4684 self.else_clause.annotate(code)
4687 class WithStatNode(StatNode):
4689 Represents a Python with statement.
4691 This is only used at parse tree level; and is not present in
4692 analysis or generation phases.
4694 # manager The with statement manager object
4695 # target Node (lhs expression)
4697 child_attrs = ["manager", "target", "body"]
4699 class TryExceptStatNode(StatNode):
4700 # try .. except statement
4703 # except_clauses [ExceptClauseNode]
4704 # else_clause StatNode or None
4706 child_attrs = ["body", "except_clauses", "else_clause"]
4708 def analyse_control_flow(self, env):
4709 env.start_branching(self.pos)
4710 self.body.analyse_control_flow(env)
4711 successful_try = env.control_flow # grab this for later
4712 env.next_branch(self.body.end_pos())
4713 env.finish_branching(self.body.end_pos())
4715 env.start_branching(self.except_clauses[0].pos)
4716 for except_clause in self.except_clauses:
4717 except_clause.analyse_control_flow(env)
4718 env.next_branch(except_clause.end_pos())
4720 # the else cause it executed only when the try clause finishes
4721 env.control_flow.incoming = successful_try
4722 if self.else_clause:
4723 self.else_clause.analyse_control_flow(env)
4724 env.finish_branching(self.end_pos())
4726 def analyse_declarations(self, env):
4727 self.body.analyse_declarations(env)
4728 for except_clause in self.except_clauses:
4729 except_clause.analyse_declarations(env)
4730 if self.else_clause:
4731 self.else_clause.analyse_declarations(env)
4732 env.use_utility_code(reset_exception_utility_code)
4734 def analyse_expressions(self, env):
4735 self.body.analyse_expressions(env)
4736 default_clause_seen = 0
4737 for except_clause in self.except_clauses:
4738 except_clause.analyse_expressions(env)
4739 if default_clause_seen:
4740 error(except_clause.pos, "default 'except:' must be last")
4741 if not except_clause.pattern:
4742 default_clause_seen = 1
4743 self.has_default_clause = default_clause_seen
4744 if self.else_clause:
4745 self.else_clause.analyse_expressions(env)
4747 nogil_check = Node.gil_error
4748 gil_message = "Try-except statement"
4750 def generate_execution_code(self, code):
4751 old_return_label = code.return_label
4752 old_break_label = code.break_label
4753 old_continue_label = code.continue_label
4754 old_error_label = code.new_error_label()
4755 our_error_label = code.error_label
4756 except_end_label = code.new_label('exception_handled')
4757 except_error_label = code.new_label('except_error')
4758 except_return_label = code.new_label('except_return')
4759 try_return_label = code.new_label('try_return')
4760 try_break_label = code.new_label('try_break')
4761 try_continue_label = code.new_label('try_continue')
4762 try_end_label = code.new_label('try_end')
4764 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4767 code.putln("__Pyx_ExceptionSave(%s);" %
4768 ', '.join(['&%s' % var for var in exc_save_vars]))
4769 for var in exc_save_vars:
4770 code.put_xgotref(var)
4773 code.return_label = try_return_label
4774 code.break_label = try_break_label
4775 code.continue_label = try_continue_label
4776 self.body.generate_execution_code(code)
4779 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4780 code.error_label = except_error_label
4781 code.return_label = except_return_label
4782 if self.else_clause:
4785 self.else_clause.generate_execution_code(code)
4788 for var in exc_save_vars:
4789 code.put_xdecref_clear(var, py_object_type)
4790 code.put_goto(try_end_label)
4791 if code.label_used(try_return_label):
4792 code.put_label(try_return_label)
4793 for var in exc_save_vars: code.put_xgiveref(var)
4794 code.putln("__Pyx_ExceptionReset(%s);" %
4795 ', '.join(exc_save_vars))
4796 code.put_goto(old_return_label)
4797 code.put_label(our_error_label)
4798 for temp_name, type in temps_to_clean_up:
4799 code.put_xdecref_clear(temp_name, type)
4800 for except_clause in self.except_clauses:
4801 except_clause.generate_handling_code(code, except_end_label)
4803 error_label_used = code.label_used(except_error_label)
4804 if error_label_used or not self.has_default_clause:
4805 if error_label_used:
4806 code.put_label(except_error_label)
4807 for var in exc_save_vars: code.put_xgiveref(var)
4808 code.putln("__Pyx_ExceptionReset(%s);" %
4809 ', '.join(exc_save_vars))
4810 code.put_goto(old_error_label)
4812 for exit_label, old_label in zip(
4813 [try_break_label, try_continue_label, except_return_label],
4814 [old_break_label, old_continue_label, old_return_label]):
4816 if code.label_used(exit_label):
4817 code.put_label(exit_label)
4818 for var in exc_save_vars: code.put_xgiveref(var)
4819 code.putln("__Pyx_ExceptionReset(%s);" %
4820 ', '.join(exc_save_vars))
4821 code.put_goto(old_label)
4823 if code.label_used(except_end_label):
4824 code.put_label(except_end_label)
4825 for var in exc_save_vars: code.put_xgiveref(var)
4826 code.putln("__Pyx_ExceptionReset(%s);" %
4827 ', '.join(exc_save_vars))
4828 code.put_label(try_end_label)
4831 for cname in exc_save_vars:
4832 code.funcstate.release_temp(cname)
4834 code.return_label = old_return_label
4835 code.break_label = old_break_label
4836 code.continue_label = old_continue_label
4837 code.error_label = old_error_label
4839 def generate_function_definitions(self, env, code):
4840 self.body.generate_function_definitions(env, code)
4841 for except_clause in self.except_clauses:
4842 except_clause.generate_function_definitions(env, code)
4843 if self.else_clause is not None:
4844 self.else_clause.generate_function_definitions(env, code)
4846 def annotate(self, code):
4847 self.body.annotate(code)
4848 for except_node in self.except_clauses:
4849 except_node.annotate(code)
4850 if self.else_clause:
4851 self.else_clause.annotate(code)
4854 class ExceptClauseNode(Node):
4855 # Part of try ... except statement.
4857 # pattern [ExprNode]
4858 # target ExprNode or None
4860 # excinfo_target NameNode or None optional target for exception info
4861 # match_flag string result of exception match
4862 # exc_value ExcValueNode used internally
4863 # function_name string qualified name of enclosing function
4864 # exc_vars (string * 3) local exception variables
4866 # excinfo_target is never set by the parser, but can be set by a transform
4867 # in order to extract more extensive information about the exception as a
4868 # sys.exc_info()-style tuple into a target variable
4870 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4873 excinfo_target = None
4875 def analyse_declarations(self, env):
4877 self.target.analyse_target_declaration(env)
4878 if self.excinfo_target is not None:
4879 self.excinfo_target.analyse_target_declaration(env)
4880 self.body.analyse_declarations(env)
4882 def analyse_expressions(self, env):
4884 genv = env.global_scope()
4885 self.function_name = env.qualified_name
4887 # normalise/unpack self.pattern into a list
4888 for i, pattern in enumerate(self.pattern):
4889 pattern.analyse_expressions(env)
4890 self.pattern[i] = pattern.coerce_to_pyobject(env)
4893 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4894 self.target.analyse_target_expression(env, self.exc_value)
4895 if self.excinfo_target is not None:
4897 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4898 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4899 self.excinfo_tuple.analyse_expressions(env)
4900 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4902 self.body.analyse_expressions(env)
4904 def generate_handling_code(self, code, end_label):
4905 code.mark_pos(self.pos)
4908 for pattern in self.pattern:
4909 pattern.generate_evaluation_code(code)
4910 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4912 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4914 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4915 for pattern in self.pattern:
4916 pattern.generate_disposal_code(code)
4917 pattern.free_temps(code)
4921 code.funcstate.release_temp(match_flag)
4923 code.putln("/*except:*/ {")
4925 if not getattr(self.body, 'stats', True) and \
4926 self.excinfo_target is None and self.target is None:
4927 # most simple case: no exception variable, empty body (pass)
4928 # => reset the exception state, done
4929 code.putln("PyErr_Restore(0,0,0);")
4930 code.put_goto(end_label)
4934 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4937 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4938 # We always have to fetch the exception value even if
4939 # there is no target, because this also normalises the
4940 # exception and stores it in the thread state.
4941 code.globalstate.use_utility_code(get_exception_utility_code)
4942 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4943 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4944 code.error_goto(self.pos)))
4948 self.exc_value.set_var(exc_vars[1])
4949 self.exc_value.generate_evaluation_code(code)
4950 self.target.generate_assignment_code(self.exc_value, code)
4951 if self.excinfo_target is not None:
4952 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4953 node.set_var(tempvar)
4954 self.excinfo_tuple.generate_evaluation_code(code)
4955 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4957 old_break_label, old_continue_label = code.break_label, code.continue_label
4958 code.break_label = code.new_label('except_break')
4959 code.continue_label = code.new_label('except_continue')
4961 old_exc_vars = code.funcstate.exc_vars
4962 code.funcstate.exc_vars = exc_vars
4963 self.body.generate_execution_code(code)
4964 code.funcstate.exc_vars = old_exc_vars
4965 for var in exc_vars:
4966 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4967 code.put_goto(end_label)
4969 if code.label_used(code.break_label):
4970 code.put_label(code.break_label)
4971 for var in exc_vars:
4972 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4973 code.put_goto(old_break_label)
4974 code.break_label = old_break_label
4976 if code.label_used(code.continue_label):
4977 code.put_label(code.continue_label)
4978 for var in exc_vars:
4979 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4980 code.put_goto(old_continue_label)
4981 code.continue_label = old_continue_label
4983 for temp in exc_vars:
4984 code.funcstate.release_temp(temp)
4989 def generate_function_definitions(self, env, code):
4990 if self.target is not None:
4991 self.target.generate_function_definitions(env, code)
4992 self.body.generate_function_definitions(env, code)
4994 def annotate(self, code):
4996 for pattern in self.pattern:
4997 pattern.annotate(code)
4999 self.target.annotate(code)
5000 self.body.annotate(code)
5003 class TryFinallyStatNode(StatNode):
5004 # try ... finally statement
5007 # finally_clause StatNode
5009 # The plan is that we funnel all continue, break
5010 # return and error gotos into the beginning of the
5011 # finally block, setting a variable to remember which
5012 # one we're doing. At the end of the finally block, we
5013 # switch on the variable to figure out where to go.
5014 # In addition, if we're doing an error, we save the
5015 # exception on entry to the finally block and restore
5018 child_attrs = ["body", "finally_clause"]
5020 preserve_exception = 1
5022 disallow_continue_in_try_finally = 0
5023 # There doesn't seem to be any point in disallowing
5024 # continue in the try block, since we have no problem
5027 def create_analysed(pos, env, body, finally_clause):
5028 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5030 create_analysed = staticmethod(create_analysed)
5032 def analyse_control_flow(self, env):
5033 env.start_branching(self.pos)
5034 self.body.analyse_control_flow(env)
5035 env.next_branch(self.body.end_pos())
5036 env.finish_branching(self.body.end_pos())
5037 self.finally_clause.analyse_control_flow(env)
5039 def analyse_declarations(self, env):
5040 self.body.analyse_declarations(env)
5041 self.finally_clause.analyse_declarations(env)
5043 def analyse_expressions(self, env):
5044 self.body.analyse_expressions(env)
5045 self.finally_clause.analyse_expressions(env)
5047 nogil_check = Node.gil_error
5048 gil_message = "Try-finally statement"
5050 def generate_execution_code(self, code):
5051 old_error_label = code.error_label
5052 old_labels = code.all_new_labels()
5053 new_labels = code.get_all_labels()
5054 new_error_label = code.error_label
5055 catch_label = code.new_label()
5058 if self.disallow_continue_in_try_finally:
5059 was_in_try_finally = code.funcstate.in_try_finally
5060 code.funcstate.in_try_finally = 1
5061 self.body.generate_execution_code(code)
5062 if self.disallow_continue_in_try_finally:
5063 code.funcstate.in_try_finally = was_in_try_finally
5066 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5067 code.mark_pos(self.finally_clause.pos)
5071 error_label_used = 0
5072 for i, new_label in enumerate(new_labels):
5073 if new_label in code.labels_used:
5074 cases_used.append(i)
5075 if new_label == new_error_label:
5076 error_label_used = 1
5077 error_label_case = i
5081 if error_label_used and self.preserve_exception:
5083 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5085 "int %s;" % Naming.exc_lineno_name)
5086 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5087 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5088 code.putln(exc_var_init_zero)
5090 exc_var_init_zero = None
5091 code.use_label(catch_label)
5093 "__pyx_why = 0; goto %s;" % catch_label)
5094 for i in cases_used:
5095 new_label = new_labels[i]
5096 #if new_label and new_label != "<try>":
5097 if new_label == new_error_label and self.preserve_exception:
5098 self.put_error_catcher(code,
5099 new_error_label, i+1, catch_label, temps_to_clean_up)
5101 code.put('%s: ' % new_label)
5102 if exc_var_init_zero:
5103 code.putln(exc_var_init_zero)
5104 code.putln("__pyx_why = %s; goto %s;" % (
5107 code.put_label(catch_label)
5108 code.set_all_labels(old_labels)
5109 if error_label_used:
5110 code.new_error_label()
5111 finally_error_label = code.error_label
5112 self.finally_clause.generate_execution_code(code)
5113 if error_label_used:
5114 if finally_error_label in code.labels_used and self.preserve_exception:
5115 over_label = code.new_label()
5116 code.put_goto(over_label);
5117 code.put_label(finally_error_label)
5118 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5119 for var in Naming.exc_vars:
5120 code.putln("Py_XDECREF(%s);" % var)
5122 code.put_goto(old_error_label)
5123 code.put_label(over_label)
5124 code.error_label = old_error_label
5127 "switch (__pyx_why) {")
5128 for i in cases_used:
5129 old_label = old_labels[i]
5130 if old_label == old_error_label and self.preserve_exception:
5131 self.put_error_uncatcher(code, i+1, old_error_label)
5133 code.use_label(old_label)
5135 "case %s: goto %s;" % (
5143 def generate_function_definitions(self, env, code):
5144 self.body.generate_function_definitions(env, code)
5145 self.finally_clause.generate_function_definitions(env, code)
5147 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5148 code.globalstate.use_utility_code(restore_exception_utility_code)
5155 for temp_name, type in temps_to_clean_up:
5156 code.put_xdecref_clear(temp_name, type)
5158 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5162 Naming.exc_lineno_name, Naming.lineno_cname))
5163 code.put_goto(catch_label)
5166 def put_error_uncatcher(self, code, i, error_label):
5167 code.globalstate.use_utility_code(restore_exception_utility_code)
5172 "__Pyx_ErrRestore(%s, %s, %s);" %
5176 Naming.lineno_cname, Naming.exc_lineno_name))
5177 for var in Naming.exc_vars:
5181 code.put_goto(error_label)
5185 def annotate(self, code):
5186 self.body.annotate(code)
5187 self.finally_clause.annotate(code)
5190 class GILStatNode(TryFinallyStatNode):
5191 # 'with gil' or 'with nogil' statement
5193 # state string 'gil' or 'nogil'
5197 preserve_exception = 0
5199 def __init__(self, pos, state, body):
5201 TryFinallyStatNode.__init__(self, pos,
5203 finally_clause = GILExitNode(pos, state = state))
5205 def analyse_expressions(self, env):
5206 env.use_utility_code(force_init_threads_utility_code)
5207 was_nogil = env.nogil
5209 TryFinallyStatNode.analyse_expressions(self, env)
5210 env.nogil = was_nogil
5214 def generate_execution_code(self, code):
5215 code.mark_pos(self.pos)
5217 if self.state == 'gil':
5218 code.putln("#ifdef WITH_THREAD")
5219 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5220 code.putln("#endif")
5222 code.putln("#ifdef WITH_THREAD")
5223 code.putln("PyThreadState *_save;")
5224 code.putln("#endif")
5225 code.putln("Py_UNBLOCK_THREADS")
5226 TryFinallyStatNode.generate_execution_code(self, code)
5230 class GILExitNode(StatNode):
5231 # Used as the 'finally' block in a GILStatNode
5233 # state string 'gil' or 'nogil'
5237 def analyse_expressions(self, env):
5240 def generate_execution_code(self, code):
5241 if self.state == 'gil':
5242 code.putln("#ifdef WITH_THREAD")
5243 code.putln("PyGILState_Release(_save);")
5244 code.putln("#endif")
5246 code.putln("Py_BLOCK_THREADS")
5249 class CImportStatNode(StatNode):
5252 # module_name string Qualified name of module being imported
5253 # as_name string or None Name specified in "as" clause, if any
5257 def analyse_declarations(self, env):
5258 if not env.is_module_scope:
5259 error(self.pos, "cimport only allowed at module level")
5261 module_scope = env.find_module(self.module_name, self.pos)
5262 if "." in self.module_name:
5263 names = [EncodedString(name) for name in self.module_name.split(".")]
5265 top_module_scope = env.context.find_submodule(top_name)
5266 module_scope = top_module_scope
5267 for name in names[1:]:
5268 submodule_scope = module_scope.find_submodule(name)
5269 module_scope.declare_module(name, submodule_scope, self.pos)
5270 module_scope = submodule_scope
5272 env.declare_module(self.as_name, module_scope, self.pos)
5274 env.declare_module(top_name, top_module_scope, self.pos)
5276 name = self.as_name or self.module_name
5277 env.declare_module(name, module_scope, self.pos)
5279 def analyse_expressions(self, env):
5282 def generate_execution_code(self, code):
5286 class FromCImportStatNode(StatNode):
5287 # from ... cimport statement
5289 # module_name string Qualified name of module
5290 # imported_names [(pos, name, as_name, kind)] Names to be imported
5294 def analyse_declarations(self, env):
5295 if not env.is_module_scope:
5296 error(self.pos, "cimport only allowed at module level")
5298 module_scope = env.find_module(self.module_name, self.pos)
5299 env.add_imported_module(module_scope)
5300 for pos, name, as_name, kind in self.imported_names:
5302 for local_name, entry in module_scope.entries.items():
5303 env.add_imported_entry(local_name, entry, pos)
5305 entry = module_scope.lookup(name)
5307 if kind and not self.declaration_matches(entry, kind):
5308 entry.redeclared(pos)
5310 if kind == 'struct' or kind == 'union':
5311 entry = module_scope.declare_struct_or_union(name,
5312 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5313 elif kind == 'class':
5314 entry = module_scope.declare_c_class(name, pos = pos,
5315 module_name = self.module_name)
5317 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5318 if submodule_scope.parent_module is module_scope:
5319 env.declare_module(as_name or name, submodule_scope, self.pos)
5321 error(pos, "Name '%s' not declared in module '%s'"
5322 % (name, self.module_name))
5325 local_name = as_name or name
5326 env.add_imported_entry(local_name, entry, pos)
5328 def declaration_matches(self, entry, kind):
5329 if not entry.is_type:
5333 if not type.is_extension_type:
5336 if not type.is_struct_or_union:
5338 if kind != type.kind:
5342 def analyse_expressions(self, env):
5345 def generate_execution_code(self, code):
5349 class FromImportStatNode(StatNode):
5350 # from ... import statement
5353 # items [(string, NameNode)]
5354 # interned_items [(string, NameNode, ExprNode)]
5355 # item PyTempNode used internally
5356 # import_star boolean used internally
5358 child_attrs = ["module"]
5361 def analyse_declarations(self, env):
5362 for name, target in self.items:
5364 if not env.is_module_scope:
5365 error(self.pos, "import * only allowed at module level")
5367 env.has_import_star = 1
5368 self.import_star = 1
5370 target.analyse_target_declaration(env)
5372 def analyse_expressions(self, env):
5374 self.module.analyse_expressions(env)
5375 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5376 self.interned_items = []
5377 for name, target in self.items:
5379 for _, entry in env.entries.items():
5380 if not entry.is_type and entry.type.is_extension_type:
5381 env.use_utility_code(ExprNodes.type_test_utility_code)
5384 entry = env.lookup(target.name)
5385 # check whether or not entry is already cimported
5386 if (entry.is_type and entry.type.name == name
5387 and hasattr(entry.type, 'module_name')):
5388 if entry.type.module_name == self.module.module_name.value:
5389 # cimported with absolute name
5392 # cimported with relative name
5393 module = env.find_module(self.module.module_name.value,
5395 if entry.type.module_name == module.qualified_name:
5397 except AttributeError:
5399 target.analyse_target_expression(env, None)
5400 if target.type is py_object_type:
5403 coerced_item = self.item.coerce_to(target.type, env)
5404 self.interned_items.append((name, target, coerced_item))
5406 def generate_execution_code(self, code):
5407 self.module.generate_evaluation_code(code)
5408 if self.import_star:
5410 'if (%s(%s) < 0) %s;' % (
5412 self.module.py_result(),
5413 code.error_goto(self.pos)))
5414 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5415 self.item.set_cname(item_temp)
5416 for name, target, coerced_item in self.interned_items:
5417 cname = code.intern_identifier(name)
5419 '%s = PyObject_GetAttr(%s, %s); %s' % (
5421 self.module.py_result(),
5423 code.error_goto_if_null(item_temp, self.pos)))
5424 code.put_gotref(item_temp)
5425 if coerced_item is None:
5426 target.generate_assignment_code(self.item, code)
5428 coerced_item.allocate_temp_result(code)
5429 coerced_item.generate_result_code(code)
5430 target.generate_assignment_code(coerced_item, code)
5431 code.put_decref_clear(item_temp, py_object_type)
5432 code.funcstate.release_temp(item_temp)
5433 self.module.generate_disposal_code(code)
5434 self.module.free_temps(code)
5438 #------------------------------------------------------------------------------------
5440 # Runtime support code
5442 #------------------------------------------------------------------------------------
5444 utility_function_predeclarations = \
5446 /* inline attribute */
5447 #ifndef CYTHON_INLINE
5448 #if defined(__GNUC__)
5449 #define CYTHON_INLINE __inline__
5450 #elif defined(_MSC_VER)
5451 #define CYTHON_INLINE __inline
5452 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5453 #define CYTHON_INLINE inline
5455 #define CYTHON_INLINE
5459 /* unused attribute */
5460 #ifndef CYTHON_UNUSED
5461 # if defined(__GNUC__)
5462 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5463 # define CYTHON_UNUSED __attribute__ ((__unused__))
5465 # define CYTHON_UNUSED
5467 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5468 # define CYTHON_UNUSED __attribute__ ((__unused__))
5470 # define CYTHON_UNUSED
5474 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*/
5478 if Options.gcc_branch_hints:
5479 branch_prediction_macros = \
5482 /* Test for GCC > 2.95 */
5483 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5484 #define likely(x) __builtin_expect(!!(x), 1)
5485 #define unlikely(x) __builtin_expect(!!(x), 0)
5486 #else /* __GNUC__ > 2 ... */
5487 #define likely(x) (x)
5488 #define unlikely(x) (x)
5489 #endif /* __GNUC__ > 2 ... */
5490 #else /* __GNUC__ */
5491 #define likely(x) (x)
5492 #define unlikely(x) (x)
5493 #endif /* __GNUC__ */
5496 branch_prediction_macros = \
5498 #define likely(x) (x)
5499 #define unlikely(x) (x)
5502 #get_name_predeclaration = \
5503 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5505 #get_name_interned_predeclaration = \
5506 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5508 #------------------------------------------------------------------------------------
5510 printing_utility_code = UtilityCode(
5512 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5513 #if PY_MAJOR_VERSION >= 3
5514 static PyObject* %s = 0;
5515 static PyObject* %s = 0;
5517 """ % (Naming.print_function, Naming.print_function_kwargs),
5519 #if PY_MAJOR_VERSION >= 3
5523 """ % (Naming.print_function, Naming.print_function_kwargs),
5525 #if PY_MAJOR_VERSION < 3
5526 static PyObject *__Pyx_GetStdout(void) {
5527 PyObject *f = PySys_GetObject((char *)"stdout");
5529 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5534 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5539 if (!(f = __Pyx_GetStdout()))
5542 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5543 if (PyFile_SoftSpace(f, 1)) {
5544 if (PyFile_WriteString(" ", f) < 0)
5547 v = PyTuple_GET_ITEM(arg_tuple, i);
5548 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5550 if (PyString_Check(v)) {
5551 char *s = PyString_AsString(v);
5552 Py_ssize_t len = PyString_Size(v);
5554 isspace(Py_CHARMASK(s[len-1])) &&
5556 PyFile_SoftSpace(f, 0);
5560 if (PyFile_WriteString("\n", f) < 0)
5562 PyFile_SoftSpace(f, 0);
5567 #else /* Python 3 has a print function */
5569 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5570 PyObject* kwargs = 0;
5571 PyObject* result = 0;
5572 PyObject* end_string;
5573 if (unlikely(!%(PRINT_FUNCTION)s)) {
5574 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5575 if (!%(PRINT_FUNCTION)s)
5579 kwargs = PyDict_New();
5580 if (unlikely(!kwargs))
5582 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5585 end_string = PyUnicode_FromStringAndSize(" ", 1);
5586 if (unlikely(!end_string))
5588 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5589 Py_DECREF(end_string);
5592 Py_DECREF(end_string);
5594 } else if (!newline) {
5595 if (unlikely(!%(PRINT_KWARGS)s)) {
5596 %(PRINT_KWARGS)s = PyDict_New();
5597 if (unlikely(!%(PRINT_KWARGS)s))
5599 end_string = PyUnicode_FromStringAndSize(" ", 1);
5600 if (unlikely(!end_string))
5602 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5603 Py_DECREF(end_string);
5606 Py_DECREF(end_string);
5608 kwargs = %(PRINT_KWARGS)s;
5610 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5611 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5618 if (kwargs != %(PRINT_KWARGS)s)
5624 """ % {'BUILTINS' : Naming.builtins_cname,
5625 'PRINT_FUNCTION' : Naming.print_function,
5626 'PRINT_KWARGS' : Naming.print_function_kwargs}
5630 printing_one_utility_code = UtilityCode(
5632 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5635 #if PY_MAJOR_VERSION < 3
5637 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5639 if (!(f = __Pyx_GetStdout()))
5642 if (PyFile_SoftSpace(f, 0)) {
5643 if (PyFile_WriteString(" ", f) < 0)
5646 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5648 if (PyFile_WriteString("\n", f) < 0)
5651 /* the line below is just to avoid compiler
5652 * compiler warnings about unused functions */
5653 return __Pyx_Print(f, NULL, 0);
5656 #else /* Python 3 has a print function */
5658 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5660 PyObject* arg_tuple = PyTuple_New(1);
5661 if (unlikely(!arg_tuple))
5664 PyTuple_SET_ITEM(arg_tuple, 0, o);
5665 res = __Pyx_Print(stream, arg_tuple, 1);
5666 Py_DECREF(arg_tuple);
5672 requires=[printing_utility_code])
5676 #------------------------------------------------------------------------------------
5678 # Exception raising code
5680 # Exceptions are raised by __Pyx_Raise() and stored as plain
5681 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5682 # 'except' statement, curexc_* is moved over to exc_* by
5683 # __Pyx_GetException()
5685 restore_exception_utility_code = UtilityCode(
5687 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5688 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5691 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5692 PyObject *tmp_type, *tmp_value, *tmp_tb;
5693 PyThreadState *tstate = PyThreadState_GET();
5695 tmp_type = tstate->curexc_type;
5696 tmp_value = tstate->curexc_value;
5697 tmp_tb = tstate->curexc_traceback;
5698 tstate->curexc_type = type;
5699 tstate->curexc_value = value;
5700 tstate->curexc_traceback = tb;
5701 Py_XDECREF(tmp_type);
5702 Py_XDECREF(tmp_value);
5706 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5707 PyThreadState *tstate = PyThreadState_GET();
5708 *type = tstate->curexc_type;
5709 *value = tstate->curexc_value;
5710 *tb = tstate->curexc_traceback;
5712 tstate->curexc_type = 0;
5713 tstate->curexc_value = 0;
5714 tstate->curexc_traceback = 0;
5719 # The following function is based on do_raise() from ceval.c. There
5720 # are separate versions for Python2 and Python3 as exception handling
5721 # has changed quite a lot between the two versions.
5723 raise_utility_code = UtilityCode(
5725 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5728 #if PY_MAJOR_VERSION < 3
5729 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5733 /* First, check the traceback argument, replacing None with NULL. */
5734 if (tb == Py_None) {
5738 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5739 PyErr_SetString(PyExc_TypeError,
5740 "raise: arg 3 must be a traceback or None");
5743 /* Next, replace a missing value with None */
5744 if (value == NULL) {
5748 #if PY_VERSION_HEX < 0x02050000
5749 if (!PyClass_Check(type))
5751 if (!PyType_Check(type))
5754 /* Raising an instance. The value should be a dummy. */
5755 if (value != Py_None) {
5756 PyErr_SetString(PyExc_TypeError,
5757 "instance exception may not have a separate value");
5760 /* Normalize to raise <class>, <instance> */
5763 #if PY_VERSION_HEX < 0x02050000
5764 if (PyInstance_Check(type)) {
5765 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5770 PyErr_SetString(PyExc_TypeError,
5771 "raise: exception must be an old-style class or instance");
5775 type = (PyObject*) Py_TYPE(type);
5777 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5778 PyErr_SetString(PyExc_TypeError,
5779 "raise: exception class must be a subclass of BaseException");
5785 __Pyx_ErrRestore(type, value, tb);
5794 #else /* Python 3+ */
5796 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5797 if (tb == Py_None) {
5799 } else if (tb && !PyTraceBack_Check(tb)) {
5800 PyErr_SetString(PyExc_TypeError,
5801 "raise: arg 3 must be a traceback or None");
5804 if (value == Py_None)
5807 if (PyExceptionInstance_Check(type)) {
5809 PyErr_SetString(PyExc_TypeError,
5810 "instance exception may not have a separate value");
5814 type = (PyObject*) Py_TYPE(value);
5815 } else if (!PyExceptionClass_Check(type)) {
5816 PyErr_SetString(PyExc_TypeError,
5817 "raise: exception class must be a subclass of BaseException");
5821 PyErr_SetObject(type, value);
5824 PyThreadState *tstate = PyThreadState_GET();
5825 PyObject* tmp_tb = tstate->curexc_traceback;
5828 tstate->curexc_traceback = tb;
5838 requires=[restore_exception_utility_code])
5840 #------------------------------------------------------------------------------------
5842 get_exception_utility_code = UtilityCode(
5844 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5847 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5848 PyObject *local_type, *local_value, *local_tb;
5849 PyObject *tmp_type, *tmp_value, *tmp_tb;
5850 PyThreadState *tstate = PyThreadState_GET();
5851 local_type = tstate->curexc_type;
5852 local_value = tstate->curexc_value;
5853 local_tb = tstate->curexc_traceback;
5854 tstate->curexc_type = 0;
5855 tstate->curexc_value = 0;
5856 tstate->curexc_traceback = 0;
5857 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5858 if (unlikely(tstate->curexc_type))
5860 #if PY_MAJOR_VERSION >= 3
5861 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5865 *value = local_value;
5867 Py_INCREF(local_type);
5868 Py_INCREF(local_value);
5869 Py_INCREF(local_tb);
5870 tmp_type = tstate->exc_type;
5871 tmp_value = tstate->exc_value;
5872 tmp_tb = tstate->exc_traceback;
5873 tstate->exc_type = local_type;
5874 tstate->exc_value = local_value;
5875 tstate->exc_traceback = local_tb;
5876 /* Make sure tstate is in a consistent state when we XDECREF
5877 these objects (XDECREF may run arbitrary code). */
5878 Py_XDECREF(tmp_type);
5879 Py_XDECREF(tmp_value);
5886 Py_XDECREF(local_type);
5887 Py_XDECREF(local_value);
5888 Py_XDECREF(local_tb);
5894 #------------------------------------------------------------------------------------
5896 get_exception_tuple_utility_code = UtilityCode(proto="""
5897 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5899 # I doubt that calling __Pyx_GetException() here is correct as it moves
5900 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5901 # exception handlers later on from receiving it.
5903 static PyObject *__Pyx_GetExceptionTuple(void) {
5904 PyObject *type = NULL, *value = NULL, *tb = NULL;
5905 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5906 PyObject* exc_info = PyTuple_New(3);
5911 PyTuple_SET_ITEM(exc_info, 0, type);
5912 PyTuple_SET_ITEM(exc_info, 1, value);
5913 PyTuple_SET_ITEM(exc_info, 2, tb);
5920 requires=[get_exception_utility_code])
5922 #------------------------------------------------------------------------------------
5924 reset_exception_utility_code = UtilityCode(
5926 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5927 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5930 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5931 PyThreadState *tstate = PyThreadState_GET();
5932 *type = tstate->exc_type;
5933 *value = tstate->exc_value;
5934 *tb = tstate->exc_traceback;
5940 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5941 PyObject *tmp_type, *tmp_value, *tmp_tb;
5942 PyThreadState *tstate = PyThreadState_GET();
5943 tmp_type = tstate->exc_type;
5944 tmp_value = tstate->exc_value;
5945 tmp_tb = tstate->exc_traceback;
5946 tstate->exc_type = type;
5947 tstate->exc_value = value;
5948 tstate->exc_traceback = tb;
5949 Py_XDECREF(tmp_type);
5950 Py_XDECREF(tmp_value);
5955 #------------------------------------------------------------------------------------
5957 arg_type_test_utility_code = UtilityCode(
5959 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5960 const char *name, int exact); /*proto*/
5963 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5964 const char *name, int exact)
5967 PyErr_Format(PyExc_SystemError, "Missing type object");
5970 if (none_allowed && obj == Py_None) return 1;
5972 if (Py_TYPE(obj) == type) return 1;
5975 if (PyObject_TypeCheck(obj, type)) return 1;
5977 PyErr_Format(PyExc_TypeError,
5978 "Argument '%s' has incorrect type (expected %s, got %s)",
5979 name, type->tp_name, Py_TYPE(obj)->tp_name);
5984 #------------------------------------------------------------------------------------
5986 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5987 # many or too few positional arguments were found. This handles
5988 # Py_ssize_t formatting correctly.
5990 raise_argtuple_invalid_utility_code = UtilityCode(
5992 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5993 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5996 static void __Pyx_RaiseArgtupleInvalid(
5997 const char* func_name,
6001 Py_ssize_t num_found)
6003 Py_ssize_t num_expected;
6004 const char *number, *more_or_less;
6006 if (num_found < num_min) {
6007 num_expected = num_min;
6008 more_or_less = "at least";
6010 num_expected = num_max;
6011 more_or_less = "at most";
6014 more_or_less = "exactly";
6016 number = (num_expected == 1) ? "" : "s";
6017 PyErr_Format(PyExc_TypeError,
6018 #if PY_VERSION_HEX < 0x02050000
6019 "%s() takes %s %d positional argument%s (%d given)",
6021 "%s() takes %s %zd positional argument%s (%zd given)",
6023 func_name, more_or_less, num_expected, number, num_found);
6027 raise_keyword_required_utility_code = UtilityCode(
6029 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6032 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6033 const char* func_name,
6036 PyErr_Format(PyExc_TypeError,
6037 #if PY_MAJOR_VERSION >= 3
6038 "%s() needs keyword-only argument %U", func_name, kw_name);
6040 "%s() needs keyword-only argument %s", func_name,
6041 PyString_AS_STRING(kw_name));
6046 raise_double_keywords_utility_code = UtilityCode(
6048 static void __Pyx_RaiseDoubleKeywordsError(
6049 const char* func_name, PyObject* kw_name); /*proto*/
6052 static void __Pyx_RaiseDoubleKeywordsError(
6053 const char* func_name,
6056 PyErr_Format(PyExc_TypeError,
6057 #if PY_MAJOR_VERSION >= 3
6058 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6060 "%s() got multiple values for keyword argument '%s'", func_name,
6061 PyString_AS_STRING(kw_name));
6066 #------------------------------------------------------------------------------------
6068 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6069 # were passed to a function, or if any keywords were passed to a
6070 # function that does not accept them.
6072 keyword_string_check_utility_code = UtilityCode(
6074 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6075 const char* function_name, int kw_allowed); /*proto*/
6078 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6080 const char* function_name,
6085 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6086 #if PY_MAJOR_VERSION < 3
6087 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6089 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6091 goto invalid_keyword_type;
6093 if ((!kw_allowed) && unlikely(key))
6094 goto invalid_keyword;
6096 invalid_keyword_type:
6097 PyErr_Format(PyExc_TypeError,
6098 "%s() keywords must be strings", function_name);
6101 PyErr_Format(PyExc_TypeError,
6102 #if PY_MAJOR_VERSION < 3
6103 "%s() got an unexpected keyword argument '%s'",
6104 function_name, PyString_AsString(key));
6106 "%s() got an unexpected keyword argument '%U'",
6107 function_name, key);
6113 #------------------------------------------------------------------------------------
6115 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6116 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6117 # keywords will raise an invalid keyword error.
6119 # Three kinds of errors are checked: 1) non-string keywords, 2)
6120 # unexpected keywords and 3) overlap with positional arguments.
6122 # If num_posargs is greater 0, it denotes the number of positional
6123 # arguments that were passed and that must therefore not appear
6124 # amongst the keywords as well.
6126 # This method does not check for required keyword arguments.
6129 parse_keywords_utility_code = UtilityCode(
6131 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6132 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6133 const char* function_name); /*proto*/
6136 static int __Pyx_ParseOptionalKeywords(
6138 PyObject **argnames[],
6141 Py_ssize_t num_pos_args,
6142 const char* function_name)
6144 PyObject *key = 0, *value = 0;
6147 PyObject*** first_kw_arg = argnames + num_pos_args;
6149 while (PyDict_Next(kwds, &pos, &key, &value)) {
6150 name = first_kw_arg;
6151 while (*name && (**name != key)) name++;
6153 values[name-argnames] = value;
6155 #if PY_MAJOR_VERSION < 3
6156 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6158 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6160 goto invalid_keyword_type;
6162 for (name = first_kw_arg; *name; name++) {
6163 #if PY_MAJOR_VERSION >= 3
6164 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6165 PyUnicode_Compare(**name, key) == 0) break;
6167 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6168 _PyString_Eq(**name, key)) break;
6172 values[name-argnames] = value;
6174 /* unexpected keyword found */
6175 for (name=argnames; name != first_kw_arg; name++) {
6176 if (**name == key) goto arg_passed_twice;
6177 #if PY_MAJOR_VERSION >= 3
6178 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6179 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6181 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6182 _PyString_Eq(**name, key)) goto arg_passed_twice;
6186 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6188 goto invalid_keyword;
6196 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6198 invalid_keyword_type:
6199 PyErr_Format(PyExc_TypeError,
6200 "%s() keywords must be strings", function_name);
6203 PyErr_Format(PyExc_TypeError,
6204 #if PY_MAJOR_VERSION < 3
6205 "%s() got an unexpected keyword argument '%s'",
6206 function_name, PyString_AsString(key));
6208 "%s() got an unexpected keyword argument '%U'",
6209 function_name, key);
6216 #------------------------------------------------------------------------------------
6218 traceback_utility_code = UtilityCode(
6220 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6223 #include "compile.h"
6224 #include "frameobject.h"
6225 #include "traceback.h"
6227 static void __Pyx_AddTraceback(const char *funcname) {
6228 PyObject *py_srcfile = 0;
6229 PyObject *py_funcname = 0;
6230 PyObject *py_globals = 0;
6231 PyCodeObject *py_code = 0;
6232 PyFrameObject *py_frame = 0;
6234 #if PY_MAJOR_VERSION < 3
6235 py_srcfile = PyString_FromString(%(FILENAME)s);
6237 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6239 if (!py_srcfile) goto bad;
6241 #if PY_MAJOR_VERSION < 3
6242 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6244 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6248 #if PY_MAJOR_VERSION < 3
6249 py_funcname = PyString_FromString(funcname);
6251 py_funcname = PyUnicode_FromString(funcname);
6254 if (!py_funcname) goto bad;
6255 py_globals = PyModule_GetDict(%(GLOBALS)s);
6256 if (!py_globals) goto bad;
6257 py_code = PyCode_New(
6258 0, /*int argcount,*/
6259 #if PY_MAJOR_VERSION >= 3
6260 0, /*int kwonlyargcount,*/
6263 0, /*int stacksize,*/
6265 %(EMPTY_BYTES)s, /*PyObject *code,*/
6266 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6267 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6268 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6269 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6270 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6271 py_srcfile, /*PyObject *filename,*/
6272 py_funcname, /*PyObject *name,*/
6273 %(LINENO)s, /*int firstlineno,*/
6274 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6276 if (!py_code) goto bad;
6277 py_frame = PyFrame_New(
6278 PyThreadState_GET(), /*PyThreadState *tstate,*/
6279 py_code, /*PyCodeObject *code,*/
6280 py_globals, /*PyObject *globals,*/
6281 0 /*PyObject *locals*/
6283 if (!py_frame) goto bad;
6284 py_frame->f_lineno = %(LINENO)s;
6285 PyTraceBack_Here(py_frame);
6287 Py_XDECREF(py_srcfile);
6288 Py_XDECREF(py_funcname);
6289 Py_XDECREF(py_code);
6290 Py_XDECREF(py_frame);
6293 'FILENAME': Naming.filename_cname,
6294 'LINENO': Naming.lineno_cname,
6295 'CFILENAME': Naming.cfilenm_cname,
6296 'CLINENO': Naming.clineno_cname,
6297 'GLOBALS': Naming.module_cname,
6298 'EMPTY_TUPLE' : Naming.empty_tuple,
6299 'EMPTY_BYTES' : Naming.empty_bytes,
6302 #------------------------------------------------------------------------------------
6304 unraisable_exception_utility_code = UtilityCode(
6306 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6309 static void __Pyx_WriteUnraisable(const char *name) {
6310 PyObject *old_exc, *old_val, *old_tb;
6312 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6313 #if PY_MAJOR_VERSION < 3
6314 ctx = PyString_FromString(name);
6316 ctx = PyUnicode_FromString(name);
6318 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6320 PyErr_WriteUnraisable(Py_None);
6322 PyErr_WriteUnraisable(ctx);
6327 requires=[restore_exception_utility_code])
6329 #------------------------------------------------------------------------------------
6331 set_vtable_utility_code = UtilityCode(
6333 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6336 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6337 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6338 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6340 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6344 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6354 #------------------------------------------------------------------------------------
6356 get_vtable_utility_code = UtilityCode(
6358 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6361 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6362 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6365 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6366 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6368 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6370 if (!*(void **)vtabptr)
6380 #------------------------------------------------------------------------------------
6382 init_string_tab_utility_code = UtilityCode(
6384 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6387 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6389 #if PY_MAJOR_VERSION < 3
6390 if (t->is_unicode) {
6391 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6392 } else if (t->intern) {
6393 *t->p = PyString_InternFromString(t->s);
6395 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6397 #else /* Python 3+ has unicode identifiers */
6398 if (t->is_unicode | t->is_str) {
6400 *t->p = PyUnicode_InternFromString(t->s);
6401 } else if (t->encoding) {
6402 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6404 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6407 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6418 #------------------------------------------------------------------------------------
6420 force_init_threads_utility_code = UtilityCode(
6422 #ifndef __PYX_FORCE_INIT_THREADS
6423 #if PY_VERSION_HEX < 0x02040200
6424 #define __PYX_FORCE_INIT_THREADS 1
6426 #define __PYX_FORCE_INIT_THREADS 0
6431 #------------------------------------------------------------------------------------
6433 # Note that cPython ignores PyTrace_EXCEPTION,
6434 # but maybe some other profilers don't.
6436 profile_utility_code = UtilityCode(proto="""
6437 #ifndef CYTHON_PROFILE
6438 #define CYTHON_PROFILE 1
6441 #ifndef CYTHON_PROFILE_REUSE_FRAME
6442 #define CYTHON_PROFILE_REUSE_FRAME 0
6447 #include "compile.h"
6448 #include "frameobject.h"
6449 #include "traceback.h"
6451 #if CYTHON_PROFILE_REUSE_FRAME
6452 #define CYTHON_FRAME_MODIFIER static
6453 #define CYTHON_FRAME_DEL
6455 #define CYTHON_FRAME_MODIFIER
6456 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6459 #define __Pyx_TraceDeclarations \\
6460 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6461 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6462 int __Pyx_use_tracing = 0;
6464 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6465 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6466 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6469 #define __Pyx_TraceException() \\
6470 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6471 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6473 PyThreadState_GET()->c_profilefunc( \\
6474 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6475 Py_DECREF(exc_info); \\
6479 #define __Pyx_TraceReturn(result) \\
6480 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6481 PyThreadState_GET()->c_profilefunc( \\
6482 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6483 CYTHON_FRAME_DEL; \\
6486 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6487 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6491 #define __Pyx_TraceDeclarations
6492 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6493 #define __Pyx_TraceException()
6494 #define __Pyx_TraceReturn(result)
6496 #endif /* CYTHON_PROFILE */
6499 "FRAME": Naming.frame_cname,
6500 "FRAME_CODE": Naming.frame_code_cname,
6506 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6507 PyFrameObject** frame,
6508 const char *funcname,
6509 const char *srcfile,
6511 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6512 if (*code == NULL) {
6513 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6514 if (*code == NULL) return 0;
6516 *frame = PyFrame_New(
6517 PyThreadState_GET(), /*PyThreadState *tstate*/
6518 *code, /*PyCodeObject *code*/
6519 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6520 0 /*PyObject *locals*/
6522 if (*frame == NULL) return 0;
6525 (*frame)->f_tstate = PyThreadState_GET();
6527 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6530 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6531 PyObject *py_srcfile = 0;
6532 PyObject *py_funcname = 0;
6533 PyCodeObject *py_code = 0;
6535 #if PY_MAJOR_VERSION < 3
6536 py_funcname = PyString_FromString(funcname);
6537 py_srcfile = PyString_FromString(srcfile);
6539 py_funcname = PyUnicode_FromString(funcname);
6540 py_srcfile = PyUnicode_FromString(srcfile);
6542 if (!py_funcname | !py_srcfile) goto bad;
6544 py_code = PyCode_New(
6545 0, /*int argcount,*/
6546 #if PY_MAJOR_VERSION >= 3
6547 0, /*int kwonlyargcount,*/
6550 0, /*int stacksize,*/
6552 %(EMPTY_BYTES)s, /*PyObject *code,*/
6553 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6554 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6555 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6556 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6557 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6558 py_srcfile, /*PyObject *filename,*/
6559 py_funcname, /*PyObject *name,*/
6560 firstlineno, /*int firstlineno,*/
6561 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6565 Py_XDECREF(py_srcfile);
6566 Py_XDECREF(py_funcname);
6571 #endif /* CYTHON_PROFILE */
6573 'EMPTY_TUPLE' : Naming.empty_tuple,
6574 'EMPTY_BYTES' : Naming.empty_bytes,
6575 "MODULE": Naming.module_cname,