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 elif entry.in_closure and self.needs_closure:
1460 code.put_giveref(entry.cname)
1461 # Decref any increfed args
1462 for entry in lenv.arg_entries:
1463 if entry.type.is_pyobject:
1464 if entry.in_closure:
1465 code.put_var_giveref(entry)
1466 elif entry.assignments:
1467 code.put_var_decref(entry)
1468 if self.needs_closure and not self.is_generator:
1469 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1470 if self.is_generator:
1471 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
1474 # This code is duplicated in ModuleNode.generate_module_init_func
1476 default_retval = self.return_type.default_value
1477 err_val = self.error_value()
1478 if err_val is None and default_retval:
1479 err_val = default_retval
1480 if self.return_type.is_pyobject:
1481 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1483 if self.entry.is_special and self.entry.name == "__hash__":
1484 # Returning -1 for __hash__ is supposed to signal an error
1485 # We do as Python instances and coerce -1 into -2.
1486 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1487 Naming.retval_cname, Naming.retval_cname))
1490 if self.return_type.is_pyobject:
1491 code.put_trace_return(Naming.retval_cname)
1493 code.put_trace_return("Py_None")
1495 code.put_finish_refcount_context()
1498 code.putln("#ifdef WITH_THREAD")
1499 code.putln("PyGILState_Release(_save);")
1500 code.putln("#endif")
1502 if not self.return_type.is_void:
1503 code.putln("return %s;" % Naming.retval_cname)
1507 if preprocessor_guard:
1508 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1509 # ----- Go back and insert temp variable declarations
1510 tempvardecl_code.put_temp_declarations(code.funcstate)
1511 # ----- Generator resume code
1512 if self.is_generator:
1513 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
1514 resume_code.putln("case 0: goto %s;" % first_run_label)
1515 for yield_expr in self.yields:
1516 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
1517 resume_code.putln("default: /* raise error here */");
1518 resume_code.putln("return NULL;");
1519 resume_code.putln("}");
1520 # ----- Python version
1521 code.exit_cfunc_scope()
1523 self.py_func.generate_function_definitions(env, code)
1524 self.generate_wrapper_functions(code)
1526 if self.is_generator:
1527 gotref_code.putln('/* Make refnanny happy */')
1528 code.temp_allocator.put_gotref(gotref_code)
1529 self.generator.generate_function_body(self.local_scope, code)
1531 def generate_preamble(self, env, code):
1532 """Parse arguments and prepare scope"""
1535 lenv = self.local_scope
1537 self.generate_argument_parsing_code(env, code)
1538 # If an argument is assigned to in the body, we must
1539 # incref it to properly keep track of refcounts.
1540 for entry in lenv.arg_entries:
1541 if entry.type.is_pyobject:
1542 if entry.assignments and not entry.in_closure:
1543 code.put_var_incref(entry)
1544 # ----- Initialise local variables
1545 for entry in lenv.var_entries:
1546 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1547 code.put_init_var_to_py_none(entry)
1548 # ----- Initialise local buffer auxiliary variables
1549 for entry in lenv.var_entries + lenv.arg_entries:
1550 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1551 code.putln("%s.buf = NULL;" %
1552 entry.buffer_aux.buffer_info_var.cname)
1553 # ----- Check and convert arguments
1554 self.generate_argument_type_tests(code)
1555 # ----- Acquire buffer arguments
1556 for entry in lenv.arg_entries:
1557 if entry.type.is_buffer:
1558 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1560 def declare_argument(self, env, arg):
1561 if arg.type.is_void:
1562 error(arg.pos, "Invalid use of 'void'")
1563 elif not arg.type.is_complete() and not arg.type.is_array:
1565 "Argument type '%s' is incomplete" % arg.type)
1566 return env.declare_arg(arg.name, arg.type, arg.pos)
1568 def generate_arg_type_test(self, arg, code):
1569 # Generate type test for one argument.
1570 if arg.type.typeobj_is_available():
1571 code.globalstate.use_utility_code(arg_type_test_utility_code)
1572 typeptr_cname = arg.type.typeptr_cname
1573 arg_code = "((PyObject *)%s)" % arg.entry.cname
1575 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1580 arg.type.is_builtin_type,
1581 code.error_goto(arg.pos)))
1583 error(arg.pos, "Cannot test type of extern C class "
1584 "without type object name specification")
1586 def generate_arg_none_check(self, arg, code):
1587 # Generate None check for one argument.
1588 code.globalstate.use_utility_code(arg_type_test_utility_code)
1589 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1590 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1592 code.error_goto(arg.pos)))
1595 def generate_wrapper_functions(self, code):
1598 def generate_execution_code(self, code):
1599 # Evaluate and store argument default values
1600 for arg in self.args:
1601 default = arg.default
1603 if not default.is_literal:
1604 default.generate_evaluation_code(code)
1605 default.make_owned_reference(code)
1606 result = default.result_as(arg.type)
1609 arg.calculate_default_value_code(code),
1611 if arg.type.is_pyobject:
1612 code.put_giveref(default.result())
1613 default.generate_post_assignment_code(code)
1614 default.free_temps(code)
1615 # For Python class methods, create and store function object
1617 self.assmt.generate_execution_code(code)
1620 # Special code for the __getbuffer__ function
1622 def getbuffer_init(self, code):
1623 info = self.local_scope.arg_entries[1].cname
1624 # Python 3.0 betas have a bug in memoryview which makes it call
1625 # getbuffer with a NULL parameter. For now we work around this;
1626 # the following line should be removed when this bug is fixed.
1627 code.putln("if (%s == NULL) return 0;" % info)
1628 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1629 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1631 def getbuffer_error_cleanup(self, code):
1632 info = self.local_scope.arg_entries[1].cname
1633 code.put_gotref("%s->obj" % info)
1634 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1637 def getbuffer_normal_cleanup(self, code):
1638 info = self.local_scope.arg_entries[1].cname
1639 code.putln("if (%s->obj == Py_None) {" % info)
1640 code.put_gotref("Py_None")
1641 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1644 class CFuncDefNode(FuncDefNode):
1645 # C function definition.
1647 # modifiers ['inline']
1648 # visibility 'private' or 'public' or 'extern'
1649 # base_type CBaseTypeNode
1650 # declarator CDeclaratorNode
1653 # decorators [DecoratorNode] list of decorators
1655 # with_gil boolean Acquire GIL around body
1657 # py_func wrapper for calling from Python
1658 # overridable whether or not this is a cpdef function
1659 # inline_in_pxd whether this is an inline function in a pxd file
1661 child_attrs = ["base_type", "declarator", "body", "py_func"]
1663 inline_in_pxd = False
1665 directive_locals = {}
1667 def unqualified_name(self):
1668 return self.entry.name
1670 def analyse_declarations(self, env):
1671 self.directive_locals.update(env.directives['locals'])
1672 base_type = self.base_type.analyse(env)
1673 # The 2 here is because we need both function and argument names.
1674 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1675 if not type.is_cfunction:
1677 "Suite attached to non-function declaration")
1678 # Remember the actual type according to the function header
1679 # written here, because the type in the symbol table entry
1680 # may be different if we're overriding a C method inherited
1681 # from the base type of an extension type.
1683 type.is_overridable = self.overridable
1684 declarator = self.declarator
1685 while not hasattr(declarator, 'args'):
1686 declarator = declarator.base
1687 self.args = declarator.args
1688 for formal_arg, type_arg in zip(self.args, type.args):
1689 formal_arg.type = type_arg.type
1690 formal_arg.name = type_arg.name
1691 formal_arg.cname = type_arg.cname
1692 name = name_declarator.name
1693 cname = name_declarator.cname
1694 self.entry = env.declare_cfunction(
1695 name, type, self.pos,
1696 cname = cname, visibility = self.visibility,
1697 defining = self.body is not None,
1698 api = self.api, modifiers = self.modifiers)
1699 self.entry.inline_func_in_pxd = self.inline_in_pxd
1700 self.return_type = type.return_type
1702 if self.overridable and not env.is_module_scope:
1703 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1704 # An error will be produced in the cdef function
1705 self.overridable = False
1707 if self.overridable:
1709 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1710 self.py_func = DefNode(pos = self.pos,
1711 name = self.entry.name,
1714 starstar_arg = None,
1716 body = py_func_body,
1718 self.py_func.is_module_scope = env.is_module_scope
1719 self.py_func.analyse_declarations(env)
1720 self.entry.as_variable = self.py_func.entry
1721 # Reset scope entry the above cfunction
1722 env.entries[name] = self.entry
1723 if not env.is_module_scope or Options.lookup_module_cpdef:
1724 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1725 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1726 self.create_local_scope(env)
1728 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1730 args = self.type.args
1731 if omit_optional_args:
1732 args = args[:len(args) - self.type.optional_arg_count]
1733 arg_names = [arg.name for arg in args]
1735 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1737 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1738 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1739 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1740 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)
1741 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1743 def declare_arguments(self, env):
1744 for arg in self.type.args:
1746 error(arg.pos, "Missing argument name")
1747 self.declare_argument(env, arg)
1749 def need_gil_acquisition(self, lenv):
1750 return self.type.with_gil
1752 def nogil_check(self, env):
1754 with_gil = type.with_gil
1755 if type.nogil and not with_gil:
1756 if type.return_type.is_pyobject:
1758 "Function with Python return type cannot be declared nogil")
1759 for entry in self.local_scope.var_entries:
1760 if entry.type.is_pyobject:
1761 error(self.pos, "Function declared nogil has Python locals or temporaries")
1763 def analyse_expressions(self, env):
1764 self.local_scope.directives = env.directives
1765 if self.py_func is not None:
1766 # this will also analyse the default values
1767 self.py_func.analyse_expressions(env)
1769 self.analyse_default_values(env)
1770 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1772 def needs_assignment_synthesis(self, env, code=None):
1775 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1778 visibility = self.entry.visibility
1779 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1780 arg_decls.append(arg.declaration_code())
1781 if with_dispatch and self.overridable:
1782 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1783 if type.optional_arg_count and with_opt_args:
1784 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1785 if type.has_varargs:
1786 arg_decls.append("...")
1788 arg_decls = ["void"]
1790 cname = self.entry.func_cname
1791 entity = type.function_header_code(cname, ', '.join(arg_decls))
1792 if visibility == 'public':
1793 dll_linkage = "DL_EXPORT"
1796 header = self.return_type.declaration_code(entity,
1797 dll_linkage = dll_linkage)
1798 if visibility == 'extern':
1799 storage_class = "%s " % Naming.extern_c_macro
1800 elif visibility == 'public':
1803 storage_class = "static "
1804 if 'inline' in self.modifiers:
1805 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1806 code.putln("%s%s %s {" % (
1808 ' '.join(self.modifiers).upper(), # macro forms
1811 def generate_argument_declarations(self, env, code):
1812 for arg in self.args:
1814 result = arg.calculate_default_value_code(code)
1815 code.putln('%s = %s;' % (
1816 arg.type.declaration_code(arg.cname), result))
1818 def generate_keyword_list(self, code):
1821 def generate_argument_parsing_code(self, env, code):
1823 if self.type.optional_arg_count:
1824 code.putln('if (%s) {' % Naming.optional_args_cname)
1825 for arg in self.args:
1827 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1828 declarator = arg.declarator
1829 while not hasattr(declarator, 'name'):
1830 declarator = declarator.base
1831 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1833 for _ in range(self.type.optional_arg_count):
1837 def generate_argument_conversion_code(self, code):
1840 def generate_argument_type_tests(self, code):
1841 # Generate type tests for args whose type in a parent
1842 # class is a supertype of the declared type.
1843 for arg in self.type.args:
1844 if arg.needs_type_test:
1845 self.generate_arg_type_test(arg, code)
1846 elif arg.type.is_pyobject and not arg.accept_none:
1847 self.generate_arg_none_check(arg, code)
1849 def error_value(self):
1850 if self.return_type.is_pyobject:
1854 return self.entry.type.exception_value
1856 def caller_will_check_exceptions(self):
1857 return self.entry.type.exception_check
1859 def generate_wrapper_functions(self, code):
1860 # If the C signature of a function has changed, we need to generate
1861 # wrappers to put in the slots here.
1864 func_type = entry.type
1865 while entry.prev_entry is not None:
1867 entry = entry.prev_entry
1868 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1870 self.generate_function_header(code,
1872 with_dispatch = entry.type.is_overridable,
1873 with_opt_args = entry.type.optional_arg_count,
1874 cname = entry.func_cname)
1875 if not self.return_type.is_void:
1877 args = self.type.args
1878 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1879 if entry.type.is_overridable:
1880 arglist.append(Naming.skip_dispatch_cname)
1881 elif func_type.is_overridable:
1883 if entry.type.optional_arg_count:
1884 arglist.append(Naming.optional_args_cname)
1885 elif func_type.optional_arg_count:
1886 arglist.append('NULL')
1887 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1891 class PyArgDeclNode(Node):
1892 # Argument which must be a Python object (used
1893 # for * and ** arguments).
1896 # entry Symtab.Entry
1897 # annotation ExprNode or None Py3 argument annotation
1900 def generate_function_definitions(self, env, code):
1901 self.entry.generate_function_definitions(env, code)
1903 class DecoratorNode(Node):
1906 # decorator NameNode or CallNode or AttributeNode
1907 child_attrs = ['decorator']
1910 class GeneratorWrapperNode(object):
1912 def __init__(self, def_node, func_cname=None, body_cname=None, header=None):
1913 self.def_node = def_node
1914 self.func_cname = func_cname
1915 self.body_cname = body_cname
1916 self.header = header
1918 def generate_function_body(self, env, code):
1919 cenv = env.outer_scope # XXX: correct?
1920 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1921 cenv = cenv.outer_scope
1922 lenv = self.def_node.local_scope
1923 code.enter_cfunc_scope()
1925 code.putln('%s {' % self.header)
1926 code.put_declare_refcount_context()
1927 self.def_node.generate_keyword_list(code)
1928 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1930 code.put_setup_refcount_context(self.def_node.entry.name)
1931 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1932 Naming.cur_scope_cname,
1933 lenv.scope_class.type.declaration_code(''),
1934 lenv.scope_class.type.typeptr_cname,
1935 lenv.scope_class.type.typeptr_cname,
1936 Naming.empty_tuple))
1937 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1938 code.put_finish_refcount_context()
1939 code.putln("return NULL;");
1941 code.put_gotref(Naming.cur_scope_cname)
1943 if self.def_node.needs_outer_scope:
1944 outer_scope_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.outer_scope_cname)
1945 code.putln("%s = (%s)%s;" % (
1947 cenv.scope_class.type.declaration_code(''),
1949 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1951 self.def_node.generate_preamble(env, code)
1953 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
1955 code.putln('%s.resume_label = 0;' % generator_cname)
1956 code.putln('%s.body = %s;' % (generator_cname, self.body_cname))
1957 for entry in lenv.scope_class.type.scope.entries.values():
1958 if entry.type.is_pyobject:
1959 code.put_xgiveref('%s->%s' % (Naming.cur_scope_cname, entry.cname))
1960 code.put_giveref(Naming.cur_scope_cname)
1961 code.put_finish_refcount_context()
1962 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
1964 code.exit_cfunc_scope()
1966 class DefNode(FuncDefNode):
1967 # A Python function definition.
1969 # name string the Python name of the function
1970 # lambda_name string the internal name of a lambda 'function'
1971 # decorators [DecoratorNode] list of decorators
1972 # args [CArgDeclNode] formal arguments
1973 # star_arg PyArgDeclNode or None * argument
1974 # starstar_arg PyArgDeclNode or None ** argument
1975 # doc EncodedString or None
1977 # return_type_annotation
1978 # ExprNode or None the Py3 return type annotation
1980 # The following subnode is constructed internally
1981 # when the def statement is inside a Python class definition.
1983 # assmt AssignmentNode Function construction/assignment
1985 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1990 num_required_kw_args = 0
1991 reqd_kw_flags_cname = "0"
1994 return_type_annotation = None
1999 def __init__(self, pos, **kwds):
2000 FuncDefNode.__init__(self, pos, **kwds)
2002 for arg in self.args:
2009 self.num_kwonly_args = k
2010 self.num_required_kw_args = rk
2011 self.num_required_args = r
2013 def as_cfunction(self, cfunc=None, scope=None):
2015 error(self.star_arg.pos, "cdef function cannot have star argument")
2016 if self.starstar_arg:
2017 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
2020 for formal_arg in self.args:
2021 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
2022 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
2024 type = py_object_type,
2025 pos = formal_arg.pos))
2026 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
2028 has_varargs = False,
2029 exception_value = None,
2030 exception_check = False,
2033 is_overridable = True)
2034 cfunc = CVarDefNode(self.pos, type=cfunc_type)
2038 cfunc_type = cfunc.type
2039 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2040 error(self.pos, "wrong number of arguments")
2041 error(cfunc.pos, "previous declaration here")
2042 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2043 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2044 is_self_arg = (i == 0 and scope.is_c_class_scope))
2045 if type is None or type is PyrexTypes.py_object_type:
2046 formal_arg.type = type_arg.type
2047 formal_arg.name_declarator = name_declarator
2049 if cfunc_type.exception_value is None:
2050 exception_value = None
2052 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2053 declarator = CFuncDeclaratorNode(self.pos,
2054 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2056 has_varargs = False,
2057 exception_check = cfunc_type.exception_check,
2058 exception_value = exception_value,
2059 with_gil = cfunc_type.with_gil,
2060 nogil = cfunc_type.nogil)
2061 return CFuncDefNode(self.pos,
2063 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2064 declarator = declarator,
2067 overridable = cfunc_type.is_overridable,
2069 with_gil = cfunc_type.with_gil,
2070 nogil = cfunc_type.nogil,
2071 visibility = 'private',
2073 directive_locals = getattr(cfunc, 'directive_locals', {}))
2075 def analyse_declarations(self, env):
2076 self.is_classmethod = self.is_staticmethod = False
2078 for decorator in self.decorators:
2079 func = decorator.decorator
2081 self.is_classmethod |= func.name == 'classmethod'
2082 self.is_staticmethod |= func.name == 'staticmethod'
2084 if self.is_classmethod and env.lookup_here('classmethod'):
2085 # classmethod() was overridden - not much we can do here ...
2086 self.is_classmethod = False
2087 if self.is_staticmethod and env.lookup_here('staticmethod'):
2088 # staticmethod() was overridden - not much we can do here ...
2089 self.is_staticmethod = False
2091 if self.name == '__new__':
2092 self.is_staticmethod = 1
2094 self.analyse_argument_types(env)
2095 if self.name == '<lambda>':
2096 self.declare_lambda_function(env)
2098 self.declare_pyfunction(env)
2099 self.analyse_signature(env)
2100 self.return_type = self.entry.signature.return_type()
2101 self.create_local_scope(env)
2103 def analyse_argument_types(self, env):
2104 directive_locals = self.directive_locals = env.directives['locals']
2105 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2106 for arg in self.args:
2107 if hasattr(arg, 'name'):
2109 name_declarator = None
2111 base_type = arg.base_type.analyse(env)
2112 name_declarator, type = \
2113 arg.declarator.analyse(base_type, env)
2114 arg.name = name_declarator.name
2115 if arg.name in directive_locals:
2116 type_node = directive_locals[arg.name]
2117 other_type = type_node.analyse_as_type(env)
2118 if other_type is None:
2119 error(type_node.pos, "Not a type")
2120 elif (type is not PyrexTypes.py_object_type
2121 and not type.same_as(other_type)):
2122 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2123 error(type_node.pos, "Previous declaration here")
2126 if name_declarator and name_declarator.cname:
2128 "Python function argument cannot have C name specification")
2129 arg.type = type.as_argument_type()
2131 arg.needs_conversion = 0
2132 arg.needs_type_test = 0
2134 if arg.type.is_pyobject:
2136 arg.accept_none = True
2138 arg.accept_none = False
2139 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2140 if arg.default and arg.default.constant_result is None:
2141 # special case: def func(MyType obj = None)
2142 arg.accept_none = True
2144 # default depends on compiler directive
2145 arg.accept_none = allow_none_for_extension_args
2147 # probably just a plain 'object'
2148 arg.accept_none = True
2150 arg.accept_none = True # won't be used, but must be there
2152 error(arg.pos, "Only Python type arguments can have 'not None'")
2154 error(arg.pos, "Only Python type arguments can have 'or None'")
2156 def analyse_signature(self, env):
2157 if self.entry.is_special:
2158 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2159 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2160 # Use the simpler calling signature for zero- and one-argument functions.
2161 if self.entry.signature is TypeSlots.pyfunction_signature:
2162 if len(self.args) == 0:
2163 self.entry.signature = TypeSlots.pyfunction_noargs
2164 elif len(self.args) == 1:
2165 if self.args[0].default is None and not self.args[0].kw_only:
2166 self.entry.signature = TypeSlots.pyfunction_onearg
2167 elif self.entry.signature is TypeSlots.pymethod_signature:
2168 if len(self.args) == 1:
2169 self.entry.signature = TypeSlots.unaryfunc
2170 elif len(self.args) == 2:
2171 if self.args[1].default is None and not self.args[1].kw_only:
2172 self.entry.signature = TypeSlots.ibinaryfunc
2174 sig = self.entry.signature
2175 nfixed = sig.num_fixed_args()
2176 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2177 and len(self.args) == 0 and self.star_arg:
2178 # this is the only case where a diverging number of
2179 # arguments is not an error - when we have no explicit
2180 # 'self' parameter as in method(*args)
2181 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2182 self.self_in_stararg = 1
2185 for i in range(min(nfixed, len(self.args))):
2188 if sig.is_self_arg(i) and not self.is_staticmethod:
2189 if self.is_classmethod:
2191 arg.hdr_type = arg.type = Builtin.type_type
2194 arg.hdr_type = arg.type = env.parent_type
2195 arg.needs_conversion = 0
2197 arg.hdr_type = sig.fixed_arg_type(i)
2198 if not arg.type.same_as(arg.hdr_type):
2199 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2200 arg.needs_type_test = 1
2202 arg.needs_conversion = 1
2203 if arg.needs_conversion:
2204 arg.hdr_cname = Naming.arg_prefix + arg.name
2206 arg.hdr_cname = Naming.var_prefix + arg.name
2208 if nfixed > len(self.args):
2209 self.bad_signature()
2211 elif nfixed < len(self.args):
2212 if not sig.has_generic_args:
2213 self.bad_signature()
2214 for arg in self.args:
2215 if arg.is_generic and \
2216 (arg.type.is_extension_type or arg.type.is_builtin_type):
2217 arg.needs_type_test = 1
2219 def bad_signature(self):
2220 sig = self.entry.signature
2221 expected_str = "%d" % sig.num_fixed_args()
2222 if sig.has_generic_args:
2223 expected_str = expected_str + " or more"
2225 if name.startswith("__") and name.endswith("__"):
2226 desc = "Special method"
2230 "%s %s has wrong number of arguments "
2231 "(%d declared, %s expected)" % (
2232 desc, self.name, len(self.args), expected_str))
2234 def signature_has_nongeneric_args(self):
2235 argcount = len(self.args)
2236 if argcount == 0 or (
2237 argcount == 1 and (self.args[0].is_self_arg or
2238 self.args[0].is_type_arg)):
2242 def signature_has_generic_args(self):
2243 return self.entry.signature.has_generic_args
2245 def declare_pyfunction(self, env):
2246 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2248 entry = env.lookup_here(name)
2249 if entry and entry.type.is_cfunction and not self.is_wrapper:
2250 warning(self.pos, "Overriding cdef method with def method.", 5)
2251 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2253 prefix = env.next_id(env.scope_prefix)
2255 entry.func_cname = \
2256 Naming.pyfunc_prefix + prefix + name
2257 entry.pymethdef_cname = \
2258 Naming.pymethdef_prefix + prefix + name
2260 if self.is_generator:
2261 self.generator_body_cname = Naming.genbody_prefix + env.next_id(env.scope_prefix) + name
2263 if Options.docstrings:
2264 entry.doc = embed_position(self.pos, self.doc)
2266 Naming.funcdoc_prefix + prefix + name
2267 if entry.is_special:
2268 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2269 entry.wrapperbase_cname = None
2271 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2275 def declare_lambda_function(self, env):
2277 prefix = env.scope_prefix
2279 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2280 entry = env.declare_lambda_function(func_cname, self.pos)
2281 entry.pymethdef_cname = \
2282 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2283 entry.qualified_name = env.qualify_name(self.lambda_name)
2287 def declare_arguments(self, env):
2288 for arg in self.args:
2290 error(arg.pos, "Missing argument name")
2292 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2293 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2294 if arg.needs_conversion:
2295 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2296 if arg.type.is_pyobject:
2297 arg.entry.init = "0"
2298 arg.entry.init_to_none = 0
2300 arg.entry = self.declare_argument(env, arg)
2302 arg.entry.is_self_arg = arg.is_self_arg
2304 if arg.is_self_arg or arg.is_type_arg or \
2305 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2306 arg.entry.is_declared_generic = 1
2307 self.declare_python_arg(env, self.star_arg)
2308 self.declare_python_arg(env, self.starstar_arg)
2310 def declare_python_arg(self, env, arg):
2312 if env.directives['infer_types'] != False:
2313 type = PyrexTypes.unspecified_type
2315 type = py_object_type
2316 entry = env.declare_var(arg.name, type, arg.pos)
2319 entry.init_to_none = 0
2320 entry.xdecref_cleanup = 1
2322 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2324 def analyse_expressions(self, env):
2325 self.local_scope.directives = env.directives
2326 self.analyse_default_values(env)
2327 if self.needs_assignment_synthesis(env):
2328 # Shouldn't we be doing this at the module level too?
2329 self.synthesize_assignment_node(env)
2331 def needs_assignment_synthesis(self, env, code=None):
2332 # Should enable for module level as well, that will require more testing...
2333 if self.entry.is_anonymous:
2335 if env.is_module_scope:
2337 return env.directives['binding']
2339 return code.globalstate.directives['binding']
2340 return env.is_py_class_scope or env.is_closure_scope
2342 def synthesize_assignment_node(self, env):
2345 while genv.is_py_class_scope or genv.is_c_class_scope:
2346 genv = genv.outer_scope
2348 if genv.is_closure_scope:
2349 rhs = ExprNodes.InnerFunctionNode(
2350 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2352 rhs = ExprNodes.PyCFunctionNode(
2353 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2355 if env.is_py_class_scope:
2356 if not self.is_staticmethod and not self.is_classmethod:
2359 self.assmt = SingleAssignmentNode(self.pos,
2360 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2362 self.assmt.analyse_declarations(env)
2363 self.assmt.analyse_expressions(env)
2365 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2367 sig = self.entry.signature
2368 if sig.has_dummy_arg or self.self_in_stararg:
2369 arg_code_list.append(
2370 "PyObject *%s" % Naming.self_cname)
2371 for arg in self.args:
2372 if not arg.is_generic:
2373 if arg.is_self_arg or arg.is_type_arg:
2374 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2376 arg_code_list.append(
2377 arg.hdr_type.declaration_code(arg.hdr_cname))
2378 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2379 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2380 if sig.has_generic_args:
2381 arg_code_list.append(
2382 "PyObject *%s, PyObject *%s"
2383 % (Naming.args_cname, Naming.kwds_cname))
2384 arg_code = ", ".join(arg_code_list)
2385 dc = self.return_type.declaration_code(self.entry.func_cname)
2386 mf = " ".join(self.modifiers).upper()
2388 header = "static %s%s(%s)" % (mf, dc, arg_code)
2389 code.putln("%s; /*proto*/" % header)
2392 if (Options.docstrings and self.entry.doc and
2393 not self.entry.scope.is_property_scope and
2394 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2395 docstr = self.entry.doc
2396 if docstr.is_unicode:
2397 docstr = docstr.utf8encode()
2399 'static char %s[] = "%s";' % (
2400 self.entry.doc_cname,
2401 split_string_literal(escape_byte_string(docstr))))
2402 if self.entry.is_special:
2404 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2407 "static PyMethodDef %s = " %
2408 self.entry.pymethdef_cname)
2409 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2410 if self.is_generator:
2411 code.putln("static PyObject *%s(PyObject *%s, PyObject *%s) /* generator body */\n{" %
2412 (self.generator_body_cname, Naming.self_cname, Naming.sent_value_cname))
2413 self.generator = GeneratorWrapperNode(self,
2414 func_cname=self.entry.func_cname,
2415 body_cname=self.generator_body_cname,
2418 code.putln("%s {" % header)
2420 def generate_argument_declarations(self, env, code):
2421 for arg in self.args:
2422 if arg.is_generic: # or arg.needs_conversion:
2423 if arg.needs_conversion:
2424 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2425 elif not arg.entry.in_closure:
2426 code.put_var_declaration(arg.entry)
2428 def generate_keyword_list(self, code):
2429 if self.signature_has_generic_args() and \
2430 self.signature_has_nongeneric_args():
2432 "static PyObject **%s[] = {" %
2433 Naming.pykwdlist_cname)
2434 for arg in self.args:
2436 pystring_cname = code.intern_identifier(arg.name)
2437 code.put('&%s,' % pystring_cname)
2440 def generate_argument_parsing_code(self, env, code):
2441 # Generate PyArg_ParseTuple call for generic
2442 # arguments, if any.
2443 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2444 # get rid of unused argument warning
2445 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2447 old_error_label = code.new_error_label()
2448 our_error_label = code.error_label
2449 end_label = code.new_label("argument_unpacking_done")
2451 has_kwonly_args = self.num_kwonly_args > 0
2452 has_star_or_kw_args = self.star_arg is not None \
2453 or self.starstar_arg is not None or has_kwonly_args
2455 for arg in self.args:
2456 if not arg.type.is_pyobject:
2457 done = arg.type.create_from_py_utility_code(env)
2458 if not done: pass # will fail later
2460 if not self.signature_has_generic_args():
2461 if has_star_or_kw_args:
2462 error(self.pos, "This method cannot have * or keyword arguments")
2463 self.generate_argument_conversion_code(code)
2465 elif not self.signature_has_nongeneric_args():
2466 # func(*args) or func(**kw) or func(*args, **kw)
2467 self.generate_stararg_copy_code(code)
2470 positional_args = []
2472 for arg in self.args:
2473 arg_entry = arg.entry
2476 if not arg.is_self_arg and not arg.is_type_arg:
2478 kw_only_args.append(arg)
2480 positional_args.append(arg)
2482 kw_only_args.append(arg)
2483 elif not arg.is_self_arg and not arg.is_type_arg:
2484 positional_args.append(arg)
2486 self.generate_tuple_and_keyword_parsing_code(
2487 positional_args, kw_only_args, end_label, code)
2489 code.error_label = old_error_label
2490 if code.label_used(our_error_label):
2491 if not code.label_used(end_label):
2492 code.put_goto(end_label)
2493 code.put_label(our_error_label)
2494 if has_star_or_kw_args:
2495 self.generate_arg_decref(self.star_arg, code)
2496 if self.starstar_arg:
2497 if self.starstar_arg.entry.xdecref_cleanup:
2498 code.put_var_xdecref(self.starstar_arg.entry)
2500 code.put_var_decref(self.starstar_arg.entry)
2501 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2502 # The arguments are put into the closure one after the
2503 # other, so when type errors are found, all references in
2504 # the closure instance must be properly ref-counted to
2505 # facilitate generic closure instance deallocation. In
2506 # the case of an argument type error, it's best to just
2507 # DECREF+clear the already handled references, as this
2508 # frees their references as early as possible.
2509 for arg in self.args:
2510 if arg.type.is_pyobject and arg.entry.in_closure:
2511 code.put_var_xdecref_clear(arg.entry)
2512 if self.needs_closure:
2513 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2514 code.put_finish_refcount_context()
2515 code.putln("return %s;" % self.error_value())
2516 if code.label_used(end_label):
2517 code.put_label(end_label)
2519 def generate_arg_assignment(self, arg, item, code):
2520 if arg.type.is_pyobject:
2522 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2524 code.putln("%s = %s;" % (entry.cname, item))
2525 if entry.in_closure:
2526 code.put_var_incref(entry)
2528 func = arg.type.from_py_function
2530 code.putln("%s = %s(%s); %s" % (
2534 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2536 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2538 def generate_arg_xdecref(self, arg, code):
2540 code.put_var_xdecref(arg.entry)
2542 def generate_arg_decref(self, arg, code):
2544 code.put_var_decref(arg.entry)
2546 def generate_stararg_copy_code(self, code):
2547 if not self.star_arg:
2548 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2549 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2551 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2552 self.name, Naming.args_cname, self.error_value()))
2555 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2557 if self.starstar_arg:
2559 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2561 kwarg_check = "%s" % Naming.kwds_cname
2563 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2564 Naming.kwds_cname, Naming.kwds_cname)
2566 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2567 kwarg_check, Naming.kwds_cname, self.name,
2568 bool(self.starstar_arg), self.error_value()))
2570 if self.starstar_arg:
2571 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2572 self.starstar_arg.entry.cname,
2575 code.putln("if (unlikely(!%s)) return %s;" % (
2576 self.starstar_arg.entry.cname, self.error_value()))
2577 self.starstar_arg.entry.xdecref_cleanup = 0
2578 code.put_gotref(self.starstar_arg.entry.cname)
2580 if self.self_in_stararg:
2581 # need to create a new tuple with 'self' inserted as first item
2582 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2583 self.star_arg.entry.cname,
2585 self.star_arg.entry.cname))
2586 if self.starstar_arg:
2588 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2589 code.putln("return %s;" % self.error_value())
2592 code.putln("return %s;" % self.error_value())
2593 code.put_gotref(self.star_arg.entry.cname)
2594 code.put_incref(Naming.self_cname, py_object_type)
2595 code.put_giveref(Naming.self_cname)
2596 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2597 self.star_arg.entry.cname, Naming.self_cname))
2598 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2599 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2600 temp, temp, Naming.args_cname, temp))
2601 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2602 Naming.args_cname, temp))
2603 code.put_incref("item", py_object_type)
2604 code.put_giveref("item")
2605 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2606 self.star_arg.entry.cname, temp))
2608 code.funcstate.release_temp(temp)
2609 self.star_arg.entry.xdecref_cleanup = 0
2611 code.put_incref(Naming.args_cname, py_object_type)
2612 code.putln("%s = %s;" % (
2613 self.star_arg.entry.cname,
2615 self.star_arg.entry.xdecref_cleanup = 0
2617 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2618 kw_only_args, success_label, code):
2619 argtuple_error_label = code.new_label("argtuple_error")
2621 min_positional_args = self.num_required_args - self.num_required_kw_args
2622 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2623 min_positional_args -= 1
2624 max_positional_args = len(positional_args)
2625 has_fixed_positional_count = not self.star_arg and \
2626 min_positional_args == max_positional_args
2628 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2629 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2630 if self.num_required_kw_args:
2631 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2633 if self.starstar_arg or self.star_arg:
2634 self.generate_stararg_init_code(max_positional_args, code)
2636 # --- optimised code when we receive keyword arguments
2637 if self.num_required_kw_args:
2638 likely_hint = "likely"
2640 likely_hint = "unlikely"
2641 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2642 self.generate_keyword_unpacking_code(
2643 min_positional_args, max_positional_args,
2644 has_fixed_positional_count,
2645 positional_args, kw_only_args, argtuple_error_label, code)
2647 # --- optimised code when we do not receive any keyword arguments
2648 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2649 # Python raises arg tuple related errors first, so we must
2650 # check the length here
2651 if min_positional_args == max_positional_args and not self.star_arg:
2655 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2656 Naming.args_cname, compare, min_positional_args))
2657 code.put_goto(argtuple_error_label)
2659 if self.num_required_kw_args:
2660 # pure error case: keywords required but not passed
2661 if max_positional_args > min_positional_args and not self.star_arg:
2662 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2663 Naming.args_cname, max_positional_args))
2664 code.put_goto(argtuple_error_label)
2665 code.putln('} else {')
2666 for i, arg in enumerate(kw_only_args):
2668 pystring_cname = code.intern_identifier(arg.name)
2669 # required keyword-only argument missing
2670 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2673 code.putln(code.error_goto(self.pos))
2676 elif min_positional_args == max_positional_args:
2677 # parse the exact number of positional arguments from the
2679 code.putln('} else {')
2680 for i, arg in enumerate(positional_args):
2681 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2682 self.generate_arg_assignment(arg, item, code)
2683 self.generate_arg_default_assignments(code)
2686 # parse the positional arguments from the variable length
2688 code.putln('} else {')
2689 self.generate_arg_default_assignments(code)
2690 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2692 code.putln('default:')
2693 reversed_args = list(enumerate(positional_args))[::-1]
2694 for i, arg in reversed_args:
2695 if i >= min_positional_args-1:
2696 if min_positional_args > 1:
2697 code.putln('case %2d:' % (i+1)) # pure code beautification
2699 code.put('case %2d: ' % (i+1))
2700 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2701 self.generate_arg_assignment(arg, item, code)
2702 if min_positional_args == 0:
2703 code.put('case 0: ')
2704 code.putln('break;')
2706 if min_positional_args:
2707 for i in range(min_positional_args-1, -1, -1):
2708 code.putln('case %2d:' % i)
2709 code.put_goto(argtuple_error_label)
2711 code.put('default: ')
2712 code.put_goto(argtuple_error_label)
2717 if code.label_used(argtuple_error_label):
2718 code.put_goto(success_label)
2719 code.put_label(argtuple_error_label)
2720 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2721 self.name, has_fixed_positional_count,
2722 min_positional_args, max_positional_args,
2724 code.putln(code.error_goto(self.pos))
2726 def generate_arg_default_assignments(self, code):
2727 for arg in self.args:
2728 if arg.is_generic and arg.default:
2732 arg.calculate_default_value_code(code)))
2734 def generate_stararg_init_code(self, max_positional_args, code):
2735 if self.starstar_arg:
2736 self.starstar_arg.entry.xdecref_cleanup = 0
2737 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2738 self.starstar_arg.entry.cname,
2739 self.starstar_arg.entry.cname,
2740 self.error_value()))
2741 code.put_gotref(self.starstar_arg.entry.cname)
2743 self.star_arg.entry.xdecref_cleanup = 0
2744 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2746 max_positional_args))
2747 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2748 self.star_arg.entry.cname, Naming.args_cname,
2749 max_positional_args, Naming.args_cname))
2750 code.put_gotref(self.star_arg.entry.cname)
2751 if self.starstar_arg:
2753 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2754 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2755 code.putln('return %s;' % self.error_value())
2758 code.putln("if (unlikely(!%s)) return %s;" % (
2759 self.star_arg.entry.cname, self.error_value()))
2760 code.putln('} else {')
2761 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2762 code.put_incref(Naming.empty_tuple, py_object_type)
2765 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2766 has_fixed_positional_count, positional_args,
2767 kw_only_args, argtuple_error_label, code):
2768 all_args = tuple(positional_args) + tuple(kw_only_args)
2769 max_args = len(all_args)
2771 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2773 # the 'values' array collects borrowed references to arguments
2774 # before doing any type coercion etc.
2775 code.putln("PyObject* values[%d] = {%s};" % (
2776 max_args, ','.join('0'*max_args)))
2778 # assign borrowed Python default values to the values array,
2779 # so that they can be overwritten by received arguments below
2780 for i, arg in enumerate(all_args):
2781 if arg.default and arg.type.is_pyobject:
2782 default_value = arg.calculate_default_value_code(code)
2783 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2785 # parse the args tuple and check that it's not too long
2786 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2788 code.putln('default:')
2789 for i in range(max_positional_args-1, -1, -1):
2790 code.put('case %2d: ' % (i+1))
2791 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2792 i, Naming.args_cname, i))
2793 code.putln('case 0: break;')
2794 if not self.star_arg:
2795 code.put('default: ') # more arguments than allowed
2796 code.put_goto(argtuple_error_label)
2799 # now fill up the positional/required arguments with values
2801 if self.num_required_args or max_positional_args > 0:
2802 last_required_arg = -1
2803 for i, arg in enumerate(all_args):
2805 last_required_arg = i
2806 if last_required_arg < max_positional_args:
2807 last_required_arg = max_positional_args-1
2808 num_required_args = self.num_required_args
2809 if max_positional_args > 0:
2810 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2811 for i, arg in enumerate(all_args[:last_required_arg+1]):
2812 if max_positional_args > 0 and i <= max_positional_args:
2813 if self.star_arg and i == max_positional_args:
2814 code.putln('default:')
2816 code.putln('case %2d:' % i)
2817 pystring_cname = code.intern_identifier(arg.name)
2820 # handled separately below
2822 code.putln('if (kw_args > 0) {')
2823 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2824 Naming.kwds_cname, pystring_cname))
2825 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2828 num_required_args -= 1
2829 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2830 i, Naming.kwds_cname, pystring_cname))
2831 code.putln('if (likely(values[%d])) kw_args--;' % i);
2832 if i < min_positional_args:
2834 # special case: we know arg 0 is missing
2836 code.put_goto(argtuple_error_label)
2838 # print the correct number of values (args or
2839 # kwargs) that were passed into positional
2840 # arguments up to this point
2841 code.putln('else {')
2842 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2843 self.name, has_fixed_positional_count,
2844 min_positional_args, max_positional_args, i))
2845 code.putln(code.error_goto(self.pos))
2848 code.putln('else {')
2849 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2850 self.name, pystring_cname))
2851 code.putln(code.error_goto(self.pos))
2853 if max_positional_args > 0:
2856 if kw_only_args and not self.starstar_arg:
2857 # unpack optional keyword-only arguments
2858 # checking for interned strings in a dict is faster than iterating
2859 # but it's too likely that we must iterate if we expect **kwargs
2861 for i, arg in enumerate(all_args[max_positional_args:]):
2862 if not arg.kw_only or not arg.default:
2864 optional_args.append((i+max_positional_args, arg))
2866 # this mimics an unrolled loop so that we can "break" out of it
2867 code.putln('while (kw_args > 0) {')
2868 code.putln('PyObject* value;')
2869 for i, arg in optional_args:
2870 pystring_cname = code.intern_identifier(arg.name)
2872 'value = PyDict_GetItem(%s, %s);' % (
2873 Naming.kwds_cname, pystring_cname))
2875 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2876 code.putln('break;')
2879 code.putln('if (unlikely(kw_args > 0)) {')
2880 # non-positional/-required kw args left in dict: default args,
2881 # kw-only args, **kwargs or error
2883 # This is sort of a catch-all: except for checking required
2884 # arguments, this will always do the right thing for unpacking
2885 # keyword arguments, so that we can concentrate on optimising
2886 # common cases above.
2887 if max_positional_args == 0:
2890 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2891 Naming.args_cname, max_positional_args,
2892 Naming.args_cname, max_positional_args))
2893 pos_arg_count = "used_pos_args"
2895 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2896 code.globalstate.use_utility_code(parse_keywords_utility_code)
2898 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2900 Naming.pykwdlist_cname,
2901 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2904 code.putln(code.error_goto(self.pos))
2907 # convert arg values to their final type and assign them
2908 for i, arg in enumerate(all_args):
2909 if arg.default and not arg.type.is_pyobject:
2910 code.putln("if (values[%d]) {" % i)
2911 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2912 if arg.default and not arg.type.is_pyobject:
2913 code.putln('} else {')
2917 arg.calculate_default_value_code(code)))
2920 def generate_argument_conversion_code(self, code):
2921 # Generate code to convert arguments from signature type to
2922 # declared type, if needed. Also copies signature arguments
2923 # into closure fields.
2924 for arg in self.args:
2925 if arg.needs_conversion:
2926 self.generate_arg_conversion(arg, code)
2927 elif arg.entry.in_closure:
2928 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2929 if arg.type.is_pyobject:
2930 code.put_var_incref(arg.entry)
2932 def generate_arg_conversion(self, arg, code):
2933 # Generate conversion code for one argument.
2934 old_type = arg.hdr_type
2936 if old_type.is_pyobject:
2938 code.putln("if (%s) {" % arg.hdr_cname)
2940 code.putln("assert(%s); {" % arg.hdr_cname)
2941 self.generate_arg_conversion_from_pyobject(arg, code)
2943 elif new_type.is_pyobject:
2944 self.generate_arg_conversion_to_pyobject(arg, code)
2946 if new_type.assignable_from(old_type):
2948 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2951 "Cannot convert 1 argument from '%s' to '%s'" %
2952 (old_type, new_type))
2954 def generate_arg_conversion_from_pyobject(self, arg, code):
2956 func = new_type.from_py_function
2957 # copied from CoerceFromPyTypeNode
2959 lhs = arg.entry.cname
2960 rhs = "%s(%s)" % (func, arg.hdr_cname)
2961 if new_type.is_enum:
2962 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2963 code.putln("%s = %s; %s" % (
2966 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2969 "Cannot convert Python object argument to type '%s'"
2972 def generate_arg_conversion_to_pyobject(self, arg, code):
2973 old_type = arg.hdr_type
2974 func = old_type.to_py_function
2976 code.putln("%s = %s(%s); %s" % (
2980 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2981 code.put_var_gotref(arg.entry)
2984 "Cannot convert argument of type '%s' to Python object"
2987 def generate_argument_type_tests(self, code):
2988 # Generate type tests for args whose signature
2989 # type is PyObject * and whose declared type is
2990 # a subtype thereof.
2991 for arg in self.args:
2992 if arg.needs_type_test:
2993 self.generate_arg_type_test(arg, code)
2994 elif not arg.accept_none and arg.type.is_pyobject:
2995 self.generate_arg_none_check(arg, code)
2997 def error_value(self):
2998 return self.entry.signature.error_value
3000 def caller_will_check_exceptions(self):
3003 class OverrideCheckNode(StatNode):
3004 # A Node for dispatching to the def method if it
3013 child_attrs = ['body']
3017 def analyse_expressions(self, env):
3018 self.args = env.arg_entries
3019 if self.py_func.is_module_scope:
3024 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3025 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3026 call_node = ExprNodes.SimpleCallNode(self.pos,
3027 function=self.func_node,
3028 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3029 self.body = ReturnStatNode(self.pos, value=call_node)
3030 self.body.analyse_expressions(env)
3032 def generate_execution_code(self, code):
3033 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3034 # Check to see if we are an extension type
3035 if self.py_func.is_module_scope:
3036 self_arg = "((PyObject *)%s)" % Naming.module_cname
3038 self_arg = "((PyObject *)%s)" % self.args[0].cname
3039 code.putln("/* Check if called by wrapper */")
3040 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3041 code.putln("/* Check if overriden in Python */")
3042 if self.py_func.is_module_scope:
3043 code.putln("else {")
3045 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3046 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3047 self.func_node.set_cname(func_node_temp)
3048 # need to get attribute manually--scope would return cdef method
3049 err = code.error_goto_if_null(func_node_temp, self.pos)
3050 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3051 func_node_temp, self_arg, interned_attr_cname, err))
3052 code.put_gotref(func_node_temp)
3053 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3054 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3055 func_node_temp, self.py_func.entry.func_cname)
3056 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3057 self.body.generate_execution_code(code)
3059 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3060 code.funcstate.release_temp(func_node_temp)
3063 class ClassDefNode(StatNode, BlockNode):
3066 class PyClassDefNode(ClassDefNode):
3067 # A Python class definition.
3069 # name EncodedString Name of the class
3070 # doc string or None
3071 # body StatNode Attribute definition code
3072 # entry Symtab.Entry
3073 # scope PyClassScope
3074 # decorators [DecoratorNode] list of decorators or None
3076 # The following subnodes are constructed internally:
3078 # dict DictNode Class dictionary or Py3 namespace
3079 # classobj ClassNode Class object
3080 # target NameNode Variable to assign class object to
3082 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3084 py3_style_class = False # Python3 style class (bases+kwargs)
3086 def __init__(self, pos, name, bases, doc, body, decorators = None,
3087 keyword_args = None, starstar_arg = None):
3088 StatNode.__init__(self, pos)
3092 self.decorators = decorators
3094 if self.doc and Options.docstrings:
3095 doc = embed_position(self.pos, self.doc)
3096 doc_node = ExprNodes.StringNode(pos, value = doc)
3099 if keyword_args or starstar_arg:
3100 self.py3_style_class = True
3102 self.metaclass = None
3103 if keyword_args and not starstar_arg:
3104 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3105 if item.key.value == 'metaclass':
3106 if self.metaclass is not None:
3107 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3108 # special case: we already know the metaclass,
3109 # so we don't need to do the "build kwargs,
3110 # find metaclass" dance at runtime
3111 self.metaclass = item.value
3112 del keyword_args.key_value_pairs[i]
3113 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3114 self.mkw = ExprNodes.KeywordArgsNode(
3115 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3117 self.mkw = ExprNodes.NullNode(pos)
3118 if self.metaclass is None:
3119 self.metaclass = ExprNodes.PyClassMetaclassNode(
3120 pos, mkw = self.mkw, bases = self.bases)
3121 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3122 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3124 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3125 bases = self.bases, dict = self.dict, doc = doc_node,
3126 metaclass = self.metaclass, mkw = self.mkw)
3128 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3129 self.metaclass = None
3132 self.classobj = ExprNodes.ClassNode(pos, name = name,
3133 bases = bases, dict = self.dict, doc = doc_node)
3134 self.target = ExprNodes.NameNode(pos, name = name)
3136 def as_cclass(self):
3138 Return this node as if it were declared as an extension class
3140 if self.py3_style_class:
3141 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3143 bases = self.classobj.bases.args
3145 base_class_name = None
3146 base_class_module = None
3147 elif len(bases) == 1:
3150 from ExprNodes import AttributeNode, NameNode
3151 while isinstance(base, AttributeNode):
3152 path.insert(0, base.attribute)
3154 if isinstance(base, NameNode):
3155 path.insert(0, base.name)
3156 base_class_name = path[-1]
3158 base_class_module = u'.'.join(path[:-1])
3160 base_class_module = None
3162 error(self.classobj.bases.args.pos, "Invalid base class")
3164 error(self.classobj.bases.args.pos, "C class may only have one base class")
3167 return CClassDefNode(self.pos,
3168 visibility = 'private',
3170 class_name = self.name,
3171 base_class_module = base_class_module,
3172 base_class_name = base_class_name,
3173 decorators = self.decorators,
3178 def create_scope(self, env):
3180 while genv.is_py_class_scope or genv.is_c_class_scope:
3181 genv = genv.outer_scope
3182 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3185 def analyse_declarations(self, env):
3186 self.target.analyse_target_declaration(env)
3187 cenv = self.create_scope(env)
3188 cenv.directives = env.directives
3189 cenv.class_obj_cname = self.target.entry.cname
3190 self.body.analyse_declarations(cenv)
3192 def analyse_expressions(self, env):
3193 if self.py3_style_class:
3194 self.bases.analyse_expressions(env)
3195 self.metaclass.analyse_expressions(env)
3196 self.mkw.analyse_expressions(env)
3197 self.dict.analyse_expressions(env)
3198 self.classobj.analyse_expressions(env)
3199 genv = env.global_scope()
3201 self.body.analyse_expressions(cenv)
3202 self.target.analyse_target_expression(env, self.classobj)
3204 def generate_function_definitions(self, env, code):
3205 self.generate_lambda_definitions(self.scope, code)
3206 self.body.generate_function_definitions(self.scope, code)
3208 def generate_execution_code(self, code):
3209 code.pyclass_stack.append(self)
3211 if self.py3_style_class:
3212 self.bases.generate_evaluation_code(code)
3213 self.mkw.generate_evaluation_code(code)
3214 self.metaclass.generate_evaluation_code(code)
3215 self.dict.generate_evaluation_code(code)
3216 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3217 self.body.generate_execution_code(code)
3218 self.classobj.generate_evaluation_code(code)
3219 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3220 self.target.generate_assignment_code(self.classobj, code)
3221 self.dict.generate_disposal_code(code)
3222 self.dict.free_temps(code)
3223 if self.py3_style_class:
3224 self.mkw.generate_disposal_code(code)
3225 self.mkw.free_temps(code)
3226 self.metaclass.generate_disposal_code(code)
3227 self.metaclass.free_temps(code)
3228 self.bases.generate_disposal_code(code)
3229 self.bases.free_temps(code)
3230 code.pyclass_stack.pop()
3232 class CClassDefNode(ClassDefNode):
3233 # An extension type definition.
3235 # visibility 'private' or 'public' or 'extern'
3236 # typedef_flag boolean
3238 # module_name string or None For import of extern type objects
3239 # class_name string Unqualified name of class
3240 # as_name string or None Name to declare as in this scope
3241 # base_class_module string or None Module containing the base class
3242 # base_class_name string or None Name of the base class
3243 # objstruct_name string or None Specified C name of object struct
3244 # typeobj_name string or None Specified C name of type object
3245 # in_pxd boolean Is in a .pxd file
3246 # decorators [DecoratorNode] list of decorators or None
3247 # doc string or None
3248 # body StatNode or None
3249 # entry Symtab.Entry
3250 # base_type PyExtensionType or None
3251 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3252 # buffer_defaults_pos
3254 child_attrs = ["body"]
3255 buffer_defaults_node = None
3256 buffer_defaults_pos = None
3257 typedef_flag = False
3259 objstruct_name = None
3263 def analyse_declarations(self, env):
3264 #print "CClassDefNode.analyse_declarations:", self.class_name
3265 #print "...visibility =", self.visibility
3266 #print "...module_name =", self.module_name
3269 if self.buffer_defaults_node:
3270 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3271 env, [], self.buffer_defaults_node,
3272 need_complete=False)
3274 buffer_defaults = None
3276 if env.in_cinclude and not self.objstruct_name:
3277 error(self.pos, "Object struct name specification required for "
3278 "C class defined in 'extern from' block")
3279 self.base_type = None
3280 # Now that module imports are cached, we need to
3281 # import the modules for extern classes.
3282 if self.module_name:
3284 for module in env.cimported_modules:
3285 if module.name == self.module_name:
3286 self.module = module
3287 if self.module is None:
3288 self.module = ModuleScope(self.module_name, None, env.context)
3289 self.module.has_extern_class = 1
3290 env.add_imported_module(self.module)
3292 if self.base_class_name:
3293 if self.base_class_module:
3294 base_class_scope = env.find_module(self.base_class_module, self.pos)
3296 base_class_scope = env
3297 if self.base_class_name == 'object':
3298 # extension classes are special and don't need to inherit from object
3299 if base_class_scope is None or base_class_scope.lookup('object') is None:
3300 self.base_class_name = None
3301 self.base_class_module = None
3302 base_class_scope = None
3303 if base_class_scope:
3304 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3305 if base_class_entry:
3306 if not base_class_entry.is_type:
3307 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3308 elif not base_class_entry.type.is_extension_type and \
3309 not (base_class_entry.type.is_builtin_type and \
3310 base_class_entry.type.objstruct_cname):
3311 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3312 elif not base_class_entry.type.is_complete():
3313 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3314 self.base_class_name, self.class_name))
3315 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3316 base_class_entry.type.scope.directives['final']:
3317 error(self.pos, "Base class '%s' of type '%s' is final" % (
3318 self.base_class_name, self.class_name))
3319 elif base_class_entry.type.is_builtin_type and \
3320 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3321 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3322 % base_class_entry.type.name)
3324 self.base_type = base_class_entry.type
3325 has_body = self.body is not None
3326 if self.module_name and self.visibility != 'extern':
3327 module_path = self.module_name.split(".")
3328 home_scope = env.find_imported_module(module_path, self.pos)
3334 if self.visibility == 'extern':
3335 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3336 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3338 self.entry = home_scope.declare_c_class(
3339 name = self.class_name,
3341 defining = has_body and self.in_pxd,
3342 implementing = has_body and not self.in_pxd,
3343 module_name = self.module_name,
3344 base_type = self.base_type,
3345 objstruct_cname = self.objstruct_name,
3346 typeobj_cname = self.typeobj_name,
3347 visibility = self.visibility,
3348 typedef_flag = self.typedef_flag,
3350 buffer_defaults = buffer_defaults)
3351 if home_scope is not env and self.visibility == 'extern':
3352 env.add_imported_entry(self.class_name, self.entry, self.pos)
3353 self.scope = scope = self.entry.type.scope
3354 if scope is not None:
3355 scope.directives = env.directives
3357 if self.doc and Options.docstrings:
3358 scope.doc = embed_position(self.pos, self.doc)
3361 self.body.analyse_declarations(scope)
3365 scope.implemented = 1
3366 env.allocate_vtable_names(self.entry)
3368 def analyse_expressions(self, env):
3370 scope = self.entry.type.scope
3371 self.body.analyse_expressions(scope)
3373 def generate_function_definitions(self, env, code):
3375 self.generate_lambda_definitions(self.scope, code)
3376 self.body.generate_function_definitions(self.scope, code)
3378 def generate_execution_code(self, code):
3379 # This is needed to generate evaluation code for
3380 # default values of method arguments.
3382 self.body.generate_execution_code(code)
3384 def annotate(self, code):
3386 self.body.annotate(code)
3389 class PropertyNode(StatNode):
3390 # Definition of a property in an extension type.
3393 # doc EncodedString or None Doc string
3396 child_attrs = ["body"]
3398 def analyse_declarations(self, env):
3399 entry = env.declare_property(self.name, self.doc, self.pos)
3401 entry.scope.directives = env.directives
3402 self.body.analyse_declarations(entry.scope)
3404 def analyse_expressions(self, env):
3405 self.body.analyse_expressions(env)
3407 def generate_function_definitions(self, env, code):
3408 self.body.generate_function_definitions(env, code)
3410 def generate_execution_code(self, code):
3413 def annotate(self, code):
3414 self.body.annotate(code)
3417 class GlobalNode(StatNode):
3418 # Global variable declaration.
3424 def analyse_declarations(self, env):
3425 for name in self.names:
3426 env.declare_global(name, self.pos)
3428 def analyse_expressions(self, env):
3431 def generate_execution_code(self, code):
3435 class ExprStatNode(StatNode):
3436 # Expression used as a statement.
3440 child_attrs = ["expr"]
3442 def analyse_declarations(self, env):
3444 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3445 func = self.expr.function.as_cython_attribute()
3446 if func == u'declare':
3447 args, kwds = self.expr.explicit_args_kwds()
3449 error(self.expr.pos, "Variable names must be specified.")
3450 for var, type_node in kwds.key_value_pairs:
3451 type = type_node.analyse_as_type(env)
3453 error(type_node.pos, "Unknown type")
3455 env.declare_var(var.value, type, var.pos, is_cdef = True)
3456 self.__class__ = PassStatNode
3458 def analyse_expressions(self, env):
3459 self.expr.result_is_used = False # hint that .result() may safely be left empty
3460 self.expr.analyse_expressions(env)
3462 def generate_execution_code(self, code):
3463 self.expr.generate_evaluation_code(code)
3464 if not self.expr.is_temp and self.expr.result():
3465 code.putln("%s;" % self.expr.result())
3466 self.expr.generate_disposal_code(code)
3467 self.expr.free_temps(code)
3469 def generate_function_definitions(self, env, code):
3470 self.expr.generate_function_definitions(env, code)
3472 def annotate(self, code):
3473 self.expr.annotate(code)
3476 class AssignmentNode(StatNode):
3477 # Abstract base class for assignment nodes.
3479 # The analyse_expressions and generate_execution_code
3480 # phases of assignments are split into two sub-phases
3481 # each, to enable all the right hand sides of a
3482 # parallel assignment to be evaluated before assigning
3483 # to any of the left hand sides.
3485 def analyse_expressions(self, env):
3486 self.analyse_types(env)
3488 # def analyse_expressions(self, env):
3489 # self.analyse_expressions_1(env)
3490 # self.analyse_expressions_2(env)
3492 def generate_execution_code(self, code):
3493 self.generate_rhs_evaluation_code(code)
3494 self.generate_assignment_code(code)
3497 class SingleAssignmentNode(AssignmentNode):
3498 # The simplest case:
3502 # lhs ExprNode Left hand side
3503 # rhs ExprNode Right hand side
3504 # first bool Is this guaranteed the first assignment to lhs?
3506 child_attrs = ["lhs", "rhs"]
3508 declaration_only = False
3510 def analyse_declarations(self, env):
3513 # handle declarations of the form x = cython.foo()
3514 if isinstance(self.rhs, ExprNodes.CallNode):
3515 func_name = self.rhs.function.as_cython_attribute()
3517 args, kwds = self.rhs.explicit_args_kwds()
3519 if func_name in ['declare', 'typedef']:
3520 if len(args) > 2 or kwds is not None:
3521 error(self.rhs.pos, "Can only declare one type at a time.")
3523 type = args[0].analyse_as_type(env)
3525 error(args[0].pos, "Unknown type")
3528 if func_name == 'declare':
3529 if isinstance(lhs, ExprNodes.NameNode):
3530 vars = [(lhs.name, lhs.pos)]
3531 elif isinstance(lhs, ExprNodes.TupleNode):
3532 vars = [(var.name, var.pos) for var in lhs.args]
3534 error(lhs.pos, "Invalid declaration")
3536 for var, pos in vars:
3537 env.declare_var(var, type, pos, is_cdef = True)
3542 self.declaration_only = True
3544 self.declaration_only = True
3545 if not isinstance(lhs, ExprNodes.NameNode):
3546 error(lhs.pos, "Invalid declaration.")
3547 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3549 elif func_name in ['struct', 'union']:
3550 self.declaration_only = True
3551 if len(args) > 0 or kwds is None:
3552 error(self.rhs.pos, "Struct or union members must be given by name.")
3555 for member, type_node in kwds.key_value_pairs:
3556 type = type_node.analyse_as_type(env)
3558 error(type_node.pos, "Unknown type")
3560 members.append((member.value, type, member.pos))
3561 if len(members) < len(kwds.key_value_pairs):
3563 if not isinstance(self.lhs, ExprNodes.NameNode):
3564 error(self.lhs.pos, "Invalid declaration.")
3565 name = self.lhs.name
3566 scope = StructOrUnionScope(name)
3567 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3568 for member, type, pos in members:
3569 scope.declare_var(member, type, pos)
3571 if self.declaration_only:
3574 self.lhs.analyse_target_declaration(env)
3576 def analyse_types(self, env, use_temp = 0):
3577 self.rhs.analyse_types(env)
3578 self.lhs.analyse_target_types(env)
3579 self.lhs.gil_assignment_check(env)
3580 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3582 self.rhs = self.rhs.coerce_to_temp(env)
3584 def generate_rhs_evaluation_code(self, code):
3585 self.rhs.generate_evaluation_code(code)
3587 def generate_assignment_code(self, code):
3588 self.lhs.generate_assignment_code(self.rhs, code)
3590 def generate_function_definitions(self, env, code):
3591 self.rhs.generate_function_definitions(env, code)
3593 def annotate(self, code):
3594 self.lhs.annotate(code)
3595 self.rhs.annotate(code)
3598 class CascadedAssignmentNode(AssignmentNode):
3599 # An assignment with multiple left hand sides:
3603 # lhs_list [ExprNode] Left hand sides
3604 # rhs ExprNode Right hand sides
3608 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3610 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3611 coerced_rhs_list = None
3613 def analyse_declarations(self, env):
3614 for lhs in self.lhs_list:
3615 lhs.analyse_target_declaration(env)
3617 def analyse_types(self, env, use_temp = 0):
3618 self.rhs.analyse_types(env)
3619 if not self.rhs.is_simple():
3621 self.rhs = self.rhs.coerce_to_temp(env)
3623 self.rhs = self.rhs.coerce_to_simple(env)
3624 from ExprNodes import CloneNode
3625 self.coerced_rhs_list = []
3626 for lhs in self.lhs_list:
3627 lhs.analyse_target_types(env)
3628 lhs.gil_assignment_check(env)
3629 rhs = CloneNode(self.rhs)
3630 rhs = rhs.coerce_to(lhs.type, env)
3631 self.coerced_rhs_list.append(rhs)
3633 def generate_rhs_evaluation_code(self, code):
3634 self.rhs.generate_evaluation_code(code)
3636 def generate_assignment_code(self, code):
3637 for i in range(len(self.lhs_list)):
3638 lhs = self.lhs_list[i]
3639 rhs = self.coerced_rhs_list[i]
3640 rhs.generate_evaluation_code(code)
3641 lhs.generate_assignment_code(rhs, code)
3642 # Assignment has disposed of the cloned RHS
3643 self.rhs.generate_disposal_code(code)
3644 self.rhs.free_temps(code)
3646 def generate_function_definitions(self, env, code):
3647 self.rhs.generate_function_definitions(env, code)
3649 def annotate(self, code):
3650 for i in range(len(self.lhs_list)):
3651 lhs = self.lhs_list[i].annotate(code)
3652 rhs = self.coerced_rhs_list[i].annotate(code)
3653 self.rhs.annotate(code)
3656 class ParallelAssignmentNode(AssignmentNode):
3657 # A combined packing/unpacking assignment:
3661 # This has been rearranged by the parser into
3663 # a = d ; b = e ; c = f
3665 # but we must evaluate all the right hand sides
3666 # before assigning to any of the left hand sides.
3668 # stats [AssignmentNode] The constituent assignments
3670 child_attrs = ["stats"]
3672 def analyse_declarations(self, env):
3673 for stat in self.stats:
3674 stat.analyse_declarations(env)
3676 def analyse_expressions(self, env):
3677 for stat in self.stats:
3678 stat.analyse_types(env, use_temp = 1)
3680 # def analyse_expressions(self, env):
3681 # for stat in self.stats:
3682 # stat.analyse_expressions_1(env, use_temp = 1)
3683 # for stat in self.stats:
3684 # stat.analyse_expressions_2(env)
3686 def generate_execution_code(self, code):
3687 for stat in self.stats:
3688 stat.generate_rhs_evaluation_code(code)
3689 for stat in self.stats:
3690 stat.generate_assignment_code(code)
3692 def generate_function_definitions(self, env, code):
3693 for stat in self.stats:
3694 stat.generate_function_definitions(env, code)
3696 def annotate(self, code):
3697 for stat in self.stats:
3701 class InPlaceAssignmentNode(AssignmentNode):
3702 # An in place arithmetic operand:
3708 # lhs ExprNode Left hand side
3709 # rhs ExprNode Right hand side
3710 # op char one of "+-*/%^&|"
3711 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3713 # This code is a bit tricky because in order to obey Python
3714 # semantics the sub-expressions (e.g. indices) of the lhs must
3715 # not be evaluated twice. So we must re-use the values calculated
3716 # in evaluation phase for the assignment phase as well.
3717 # Fortunately, the type of the lhs node is fairly constrained
3718 # (it must be a NameNode, AttributeNode, or IndexNode).
3720 child_attrs = ["lhs", "rhs"]
3722 def analyse_declarations(self, env):
3723 self.lhs.analyse_target_declaration(env)
3725 def analyse_types(self, env):
3726 self.rhs.analyse_types(env)
3727 self.lhs.analyse_target_types(env)
3729 def generate_execution_code(self, code):
3731 self.rhs.generate_evaluation_code(code)
3732 self.lhs.generate_subexpr_evaluation_code(code)
3733 c_op = self.operator
3737 error(self.pos, "No C inplace power operator")
3738 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3739 if self.lhs.type.is_pyobject:
3740 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3741 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3742 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3743 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3746 # TODO: make sure overload is declared
3747 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3748 self.lhs.generate_subexpr_disposal_code(code)
3749 self.lhs.free_subexpr_temps(code)
3750 self.rhs.generate_disposal_code(code)
3751 self.rhs.free_temps(code)
3753 def annotate(self, code):
3754 self.lhs.annotate(code)
3755 self.rhs.annotate(code)
3757 def create_binop_node(self):
3759 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3762 class PrintStatNode(StatNode):
3765 # arg_tuple TupleNode
3766 # stream ExprNode or None (stdout)
3767 # append_newline boolean
3769 child_attrs = ["arg_tuple", "stream"]
3771 def analyse_expressions(self, env):
3773 self.stream.analyse_expressions(env)
3774 self.stream = self.stream.coerce_to_pyobject(env)
3775 self.arg_tuple.analyse_expressions(env)
3776 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3777 env.use_utility_code(printing_utility_code)
3778 if len(self.arg_tuple.args) == 1 and self.append_newline:
3779 env.use_utility_code(printing_one_utility_code)
3781 nogil_check = Node.gil_error
3782 gil_message = "Python print statement"
3784 def generate_execution_code(self, code):
3786 self.stream.generate_evaluation_code(code)
3787 stream_result = self.stream.py_result()
3790 if len(self.arg_tuple.args) == 1 and self.append_newline:
3791 arg = self.arg_tuple.args[0]
3792 arg.generate_evaluation_code(code)
3795 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3798 code.error_goto(self.pos)))
3799 arg.generate_disposal_code(code)
3800 arg.free_temps(code)
3802 self.arg_tuple.generate_evaluation_code(code)
3804 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3806 self.arg_tuple.py_result(),
3807 self.append_newline,
3808 code.error_goto(self.pos)))
3809 self.arg_tuple.generate_disposal_code(code)
3810 self.arg_tuple.free_temps(code)
3813 self.stream.generate_disposal_code(code)
3814 self.stream.free_temps(code)
3816 def generate_function_definitions(self, env, code):
3818 self.stream.generate_function_definitions(env, code)
3819 self.arg_tuple.generate_function_definitions(env, code)
3821 def annotate(self, code):
3823 self.stream.annotate(code)
3824 self.arg_tuple.annotate(code)
3827 class ExecStatNode(StatNode):
3832 child_attrs = ["args"]
3834 def analyse_expressions(self, env):
3835 for i, arg in enumerate(self.args):
3836 arg.analyse_expressions(env)
3837 arg = arg.coerce_to_pyobject(env)
3839 env.use_utility_code(Builtin.pyexec_utility_code)
3841 nogil_check = Node.gil_error
3842 gil_message = "Python exec statement"
3844 def generate_execution_code(self, code):
3846 for arg in self.args:
3847 arg.generate_evaluation_code(code)
3848 args.append( arg.py_result() )
3849 args = tuple(args + ['0', '0'][:3-len(args)])
3850 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3851 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3852 (temp_result,) + args))
3853 for arg in self.args:
3854 arg.generate_disposal_code(code)
3855 arg.free_temps(code)
3857 code.error_goto_if_null(temp_result, self.pos))
3858 code.put_gotref(temp_result)
3859 code.put_decref_clear(temp_result, py_object_type)
3860 code.funcstate.release_temp(temp_result)
3862 def annotate(self, code):
3863 for arg in self.args:
3867 class DelStatNode(StatNode):
3872 child_attrs = ["args"]
3874 def analyse_declarations(self, env):
3875 for arg in self.args:
3876 arg.analyse_target_declaration(env)
3878 def analyse_expressions(self, env):
3879 for arg in self.args:
3880 arg.analyse_target_expression(env, None)
3881 if arg.type.is_pyobject:
3883 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3885 elif arg.type.is_cpp_class:
3886 error(arg.pos, "Deletion of non-heap C++ object")
3888 error(arg.pos, "Deletion of non-Python, non-C++ object")
3889 #arg.release_target_temp(env)
3891 def nogil_check(self, env):
3892 for arg in self.args:
3893 if arg.type.is_pyobject:
3896 gil_message = "Deleting Python object"
3898 def generate_execution_code(self, code):
3899 for arg in self.args:
3900 if arg.type.is_pyobject:
3901 arg.generate_deletion_code(code)
3902 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3903 arg.generate_result_code(code)
3904 code.putln("delete %s;" % arg.result())
3905 # else error reported earlier
3907 def annotate(self, code):
3908 for arg in self.args:
3912 class PassStatNode(StatNode):
3917 def analyse_expressions(self, env):
3920 def generate_execution_code(self, code):
3924 class BreakStatNode(StatNode):
3928 def analyse_expressions(self, env):
3931 def generate_execution_code(self, code):
3932 if not code.break_label:
3933 error(self.pos, "break statement not inside loop")
3935 code.put_goto(code.break_label)
3938 class ContinueStatNode(StatNode):
3942 def analyse_expressions(self, env):
3945 def generate_execution_code(self, code):
3946 if code.funcstate.in_try_finally:
3947 error(self.pos, "continue statement inside try of try...finally")
3948 elif not code.continue_label:
3949 error(self.pos, "continue statement not inside loop")
3951 code.put_goto(code.continue_label)
3954 class ReturnStatNode(StatNode):
3957 # value ExprNode or None
3958 # return_type PyrexType
3960 child_attrs = ["value"]
3962 def analyse_expressions(self, env):
3963 return_type = env.return_type
3964 self.return_type = return_type
3966 error(self.pos, "Return not inside a function body")
3969 self.value.analyse_types(env)
3970 if return_type.is_void or return_type.is_returncode:
3971 error(self.value.pos,
3972 "Return with value in void function")
3974 self.value = self.value.coerce_to(env.return_type, env)
3976 if (not return_type.is_void
3977 and not return_type.is_pyobject
3978 and not return_type.is_returncode):
3979 error(self.pos, "Return value required")
3981 def nogil_check(self, env):
3982 if self.return_type.is_pyobject:
3985 gil_message = "Returning Python object"
3987 def generate_execution_code(self, code):
3988 code.mark_pos(self.pos)
3989 if not self.return_type:
3990 # error reported earlier
3992 if self.return_type.is_pyobject:
3993 code.put_xdecref(Naming.retval_cname,
3996 self.value.generate_evaluation_code(code)
3997 self.value.make_owned_reference(code)
4000 Naming.retval_cname,
4001 self.value.result_as(self.return_type)))
4002 self.value.generate_post_assignment_code(code)
4003 self.value.free_temps(code)
4005 if self.return_type.is_pyobject:
4006 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4007 elif self.return_type.is_returncode:
4010 Naming.retval_cname,
4011 self.return_type.default_value))
4012 for cname, type in code.funcstate.temps_holding_reference():
4013 code.put_decref_clear(cname, type)
4014 code.put_goto(code.return_label)
4016 def generate_function_definitions(self, env, code):
4017 if self.value is not None:
4018 self.value.generate_function_definitions(env, code)
4020 def annotate(self, code):
4022 self.value.annotate(code)
4025 class RaiseStatNode(StatNode):
4028 # exc_type ExprNode or None
4029 # exc_value ExprNode or None
4030 # exc_tb ExprNode or None
4032 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4034 def analyse_expressions(self, env):
4036 self.exc_type.analyse_types(env)
4037 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4039 self.exc_value.analyse_types(env)
4040 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4042 self.exc_tb.analyse_types(env)
4043 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4044 env.use_utility_code(raise_utility_code)
4046 nogil_check = Node.gil_error
4047 gil_message = "Raising exception"
4049 def generate_execution_code(self, code):
4051 self.exc_type.generate_evaluation_code(code)
4052 type_code = self.exc_type.py_result()
4056 self.exc_value.generate_evaluation_code(code)
4057 value_code = self.exc_value.py_result()
4061 self.exc_tb.generate_evaluation_code(code)
4062 tb_code = self.exc_tb.py_result()
4066 "__Pyx_Raise(%s, %s, %s);" % (
4070 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4072 obj.generate_disposal_code(code)
4073 obj.free_temps(code)
4075 code.error_goto(self.pos))
4077 def generate_function_definitions(self, env, code):
4078 if self.exc_type is not None:
4079 self.exc_type.generate_function_definitions(env, code)
4080 if self.exc_value is not None:
4081 self.exc_value.generate_function_definitions(env, code)
4082 if self.exc_tb is not None:
4083 self.exc_tb.generate_function_definitions(env, code)
4085 def annotate(self, code):
4087 self.exc_type.annotate(code)
4089 self.exc_value.annotate(code)
4091 self.exc_tb.annotate(code)
4094 class ReraiseStatNode(StatNode):
4098 def analyse_expressions(self, env):
4099 env.use_utility_code(restore_exception_utility_code)
4101 nogil_check = Node.gil_error
4102 gil_message = "Raising exception"
4104 def generate_execution_code(self, code):
4105 vars = code.funcstate.exc_vars
4107 for varname in vars:
4108 code.put_giveref(varname)
4109 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4110 for varname in vars:
4111 code.put("%s = 0; " % varname)
4113 code.putln(code.error_goto(self.pos))
4115 error(self.pos, "Reraise not inside except clause")
4118 class AssertStatNode(StatNode):
4122 # value ExprNode or None
4124 child_attrs = ["cond", "value"]
4126 def analyse_expressions(self, env):
4127 self.cond = self.cond.analyse_boolean_expression(env)
4129 self.value.analyse_types(env)
4130 self.value = self.value.coerce_to_pyobject(env)
4132 nogil_check = Node.gil_error
4133 gil_message = "Raising exception"
4135 def generate_execution_code(self, code):
4136 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4137 self.cond.generate_evaluation_code(code)
4139 "if (unlikely(!%s)) {" %
4142 self.value.generate_evaluation_code(code)
4144 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4145 self.value.py_result())
4146 self.value.generate_disposal_code(code)
4147 self.value.free_temps(code)
4150 "PyErr_SetNone(PyExc_AssertionError);")
4152 code.error_goto(self.pos))
4155 self.cond.generate_disposal_code(code)
4156 self.cond.free_temps(code)
4157 code.putln("#endif")
4159 def generate_function_definitions(self, env, code):
4160 self.cond.generate_function_definitions(env, code)
4161 if self.value is not None:
4162 self.value.generate_function_definitions(env, code)
4164 def annotate(self, code):
4165 self.cond.annotate(code)
4167 self.value.annotate(code)
4170 class IfStatNode(StatNode):
4173 # if_clauses [IfClauseNode]
4174 # else_clause StatNode or None
4176 child_attrs = ["if_clauses", "else_clause"]
4178 def analyse_control_flow(self, env):
4179 env.start_branching(self.pos)
4180 for if_clause in self.if_clauses:
4181 if_clause.analyse_control_flow(env)
4182 env.next_branch(if_clause.end_pos())
4183 if self.else_clause:
4184 self.else_clause.analyse_control_flow(env)
4185 env.finish_branching(self.end_pos())
4187 def analyse_declarations(self, env):
4188 for if_clause in self.if_clauses:
4189 if_clause.analyse_declarations(env)
4190 if self.else_clause:
4191 self.else_clause.analyse_declarations(env)
4193 def analyse_expressions(self, env):
4194 for if_clause in self.if_clauses:
4195 if_clause.analyse_expressions(env)
4196 if self.else_clause:
4197 self.else_clause.analyse_expressions(env)
4199 def generate_execution_code(self, code):
4200 code.mark_pos(self.pos)
4201 end_label = code.new_label()
4202 for if_clause in self.if_clauses:
4203 if_clause.generate_execution_code(code, end_label)
4204 if self.else_clause:
4205 code.putln("/*else*/ {")
4206 self.else_clause.generate_execution_code(code)
4208 code.put_label(end_label)
4210 def generate_function_definitions(self, env, code):
4211 for clause in self.if_clauses:
4212 clause.generate_function_definitions(env, code)
4213 if self.else_clause is not None:
4214 self.else_clause.generate_function_definitions(env, code)
4216 def annotate(self, code):
4217 for if_clause in self.if_clauses:
4218 if_clause.annotate(code)
4219 if self.else_clause:
4220 self.else_clause.annotate(code)
4223 class IfClauseNode(Node):
4224 # if or elif clause in an if statement
4226 # condition ExprNode
4229 child_attrs = ["condition", "body"]
4231 def analyse_control_flow(self, env):
4232 self.body.analyse_control_flow(env)
4234 def analyse_declarations(self, env):
4235 self.body.analyse_declarations(env)
4237 def analyse_expressions(self, env):
4239 self.condition.analyse_temp_boolean_expression(env)
4240 self.body.analyse_expressions(env)
4242 def get_constant_condition_result(self):
4243 if self.condition.has_constant_result():
4244 return bool(self.condition.constant_result)
4248 def generate_execution_code(self, code, end_label):
4249 self.condition.generate_evaluation_code(code)
4252 self.condition.result())
4253 self.condition.generate_disposal_code(code)
4254 self.condition.free_temps(code)
4255 self.body.generate_execution_code(code)
4256 code.put_goto(end_label)
4259 def generate_function_definitions(self, env, code):
4260 self.condition.generate_function_definitions(env, code)
4261 self.body.generate_function_definitions(env, code)
4263 def annotate(self, code):
4264 self.condition.annotate(code)
4265 self.body.annotate(code)
4268 class SwitchCaseNode(StatNode):
4269 # Generated in the optimization of an if-elif-else node
4271 # conditions [ExprNode]
4274 child_attrs = ['conditions', 'body']
4276 def generate_execution_code(self, code):
4277 for cond in self.conditions:
4278 code.mark_pos(cond.pos)
4279 cond.generate_evaluation_code(code)
4280 code.putln("case %s:" % cond.result())
4281 self.body.generate_execution_code(code)
4282 code.putln("break;")
4284 def generate_function_definitions(self, env, code):
4285 for cond in self.conditions:
4286 cond.generate_function_definitions(env, code)
4287 self.body.generate_function_definitions(env, code)
4289 def annotate(self, code):
4290 for cond in self.conditions:
4292 self.body.annotate(code)
4294 class SwitchStatNode(StatNode):
4295 # Generated in the optimization of an if-elif-else node
4298 # cases [SwitchCaseNode]
4299 # else_clause StatNode or None
4301 child_attrs = ['test', 'cases', 'else_clause']
4303 def generate_execution_code(self, code):
4304 self.test.generate_evaluation_code(code)
4305 code.putln("switch (%s) {" % self.test.result())
4306 for case in self.cases:
4307 case.generate_execution_code(code)
4308 if self.else_clause is not None:
4309 code.putln("default:")
4310 self.else_clause.generate_execution_code(code)
4311 code.putln("break;")
4314 def generate_function_definitions(self, env, code):
4315 self.test.generate_function_definitions(env, code)
4316 for case in self.cases:
4317 case.generate_function_definitions(env, code)
4318 if self.else_clause is not None:
4319 self.else_clause.generate_function_definitions(env, code)
4321 def annotate(self, code):
4322 self.test.annotate(code)
4323 for case in self.cases:
4325 if self.else_clause is not None:
4326 self.else_clause.annotate(code)
4328 class LoopNode(object):
4330 def analyse_control_flow(self, env):
4331 env.start_branching(self.pos)
4332 self.body.analyse_control_flow(env)
4333 env.next_branch(self.body.end_pos())
4334 if self.else_clause:
4335 self.else_clause.analyse_control_flow(env)
4336 env.finish_branching(self.end_pos())
4339 class WhileStatNode(LoopNode, StatNode):
4342 # condition ExprNode
4344 # else_clause StatNode
4346 child_attrs = ["condition", "body", "else_clause"]
4348 def analyse_declarations(self, env):
4349 self.body.analyse_declarations(env)
4350 if self.else_clause:
4351 self.else_clause.analyse_declarations(env)
4353 def analyse_expressions(self, env):
4355 self.condition.analyse_temp_boolean_expression(env)
4356 self.body.analyse_expressions(env)
4357 if self.else_clause:
4358 self.else_clause.analyse_expressions(env)
4360 def generate_execution_code(self, code):
4361 old_loop_labels = code.new_loop_labels()
4364 self.condition.generate_evaluation_code(code)
4365 self.condition.generate_disposal_code(code)
4368 self.condition.result())
4369 self.condition.free_temps(code)
4370 self.body.generate_execution_code(code)
4371 code.put_label(code.continue_label)
4373 break_label = code.break_label
4374 code.set_loop_labels(old_loop_labels)
4375 if self.else_clause:
4376 code.putln("/*else*/ {")
4377 self.else_clause.generate_execution_code(code)
4379 code.put_label(break_label)
4381 def generate_function_definitions(self, env, code):
4382 self.condition.generate_function_definitions(env, code)
4383 self.body.generate_function_definitions(env, code)
4384 if self.else_clause is not None:
4385 self.else_clause.generate_function_definitions(env, code)
4387 def annotate(self, code):
4388 self.condition.annotate(code)
4389 self.body.annotate(code)
4390 if self.else_clause:
4391 self.else_clause.annotate(code)
4394 def ForStatNode(pos, **kw):
4395 if 'iterator' in kw:
4396 return ForInStatNode(pos, **kw)
4398 return ForFromStatNode(pos, **kw)
4400 class ForInStatNode(LoopNode, StatNode):
4404 # iterator IteratorNode
4406 # else_clause StatNode
4407 # item NextNode used internally
4409 child_attrs = ["target", "iterator", "body", "else_clause"]
4412 def analyse_declarations(self, env):
4413 self.target.analyse_target_declaration(env)
4414 self.body.analyse_declarations(env)
4415 if self.else_clause:
4416 self.else_clause.analyse_declarations(env)
4418 def analyse_expressions(self, env):
4420 self.target.analyse_target_types(env)
4421 self.iterator.analyse_expressions(env)
4422 self.item = ExprNodes.NextNode(self.iterator, env)
4423 self.item = self.item.coerce_to(self.target.type, env)
4424 self.body.analyse_expressions(env)
4425 if self.else_clause:
4426 self.else_clause.analyse_expressions(env)
4428 def generate_execution_code(self, code):
4429 old_loop_labels = code.new_loop_labels()
4430 self.iterator.allocate_counter_temp(code)
4431 self.iterator.generate_evaluation_code(code)
4434 self.item.generate_evaluation_code(code)
4435 self.target.generate_assignment_code(self.item, code)
4436 self.body.generate_execution_code(code)
4437 code.put_label(code.continue_label)
4440 break_label = code.break_label
4441 code.set_loop_labels(old_loop_labels)
4443 if self.else_clause:
4444 # in nested loops, the 'else' block can contain a
4445 # 'continue' statement for the outer loop, but we may need
4446 # to generate cleanup code before taking that path, so we
4448 orig_continue_label = code.continue_label
4449 code.continue_label = code.new_label('outer_continue')
4451 code.putln("/*else*/ {")
4452 self.else_clause.generate_execution_code(code)
4455 if code.label_used(code.continue_label):
4456 code.put_goto(break_label)
4457 code.put_label(code.continue_label)
4458 self.iterator.generate_disposal_code(code)
4459 code.put_goto(orig_continue_label)
4460 code.set_loop_labels(old_loop_labels)
4462 if code.label_used(break_label):
4463 code.put_label(break_label)
4464 self.iterator.release_counter_temp(code)
4465 self.iterator.generate_disposal_code(code)
4466 self.iterator.free_temps(code)
4468 def generate_function_definitions(self, env, code):
4469 self.target.generate_function_definitions(env, code)
4470 self.iterator.generate_function_definitions(env, code)
4471 self.body.generate_function_definitions(env, code)
4472 if self.else_clause is not None:
4473 self.else_clause.generate_function_definitions(env, code)
4475 def annotate(self, code):
4476 self.target.annotate(code)
4477 self.iterator.annotate(code)
4478 self.body.annotate(code)
4479 if self.else_clause:
4480 self.else_clause.annotate(code)
4481 self.item.annotate(code)
4484 class ForFromStatNode(LoopNode, StatNode):
4485 # for name from expr rel name rel expr
4492 # step ExprNode or None
4494 # else_clause StatNode or None
4500 # loopvar_node ExprNode (usually a NameNode or temp node)
4501 # py_loopvar_node PyTempNode or None
4502 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4504 is_py_target = False
4506 py_loopvar_node = None
4509 gil_message = "For-loop using object bounds or target"
4511 def nogil_check(self, env):
4512 for x in (self.target, self.bound1, self.bound2):
4513 if x.type.is_pyobject:
4516 def analyse_declarations(self, env):
4517 self.target.analyse_target_declaration(env)
4518 self.body.analyse_declarations(env)
4519 if self.else_clause:
4520 self.else_clause.analyse_declarations(env)
4522 def analyse_expressions(self, env):
4524 self.target.analyse_target_types(env)
4525 self.bound1.analyse_types(env)
4526 self.bound2.analyse_types(env)
4527 if self.step is not None:
4528 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4529 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4530 self.step.analyse_types(env)
4532 target_type = self.target.type
4533 if self.target.type.is_numeric:
4534 loop_type = self.target.type
4536 loop_type = PyrexTypes.c_int_type
4537 if not self.bound1.type.is_pyobject:
4538 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4539 if not self.bound2.type.is_pyobject:
4540 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4541 if self.step is not None and not self.step.type.is_pyobject:
4542 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4543 self.bound1 = self.bound1.coerce_to(loop_type, env)
4544 self.bound2 = self.bound2.coerce_to(loop_type, env)
4545 if not self.bound2.is_literal:
4546 self.bound2 = self.bound2.coerce_to_temp(env)
4547 if self.step is not None:
4548 self.step = self.step.coerce_to(loop_type, env)
4549 if not self.step.is_literal:
4550 self.step = self.step.coerce_to_temp(env)
4552 target_type = self.target.type
4553 if not (target_type.is_pyobject or target_type.is_numeric):
4554 error(self.target.pos,
4555 "for-from loop variable must be c numeric type or Python object")
4556 if target_type.is_numeric:
4557 self.is_py_target = False
4558 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4559 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4560 self.loopvar_node = self.target
4561 self.py_loopvar_node = None
4563 self.is_py_target = True
4564 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4565 self.loopvar_node = c_loopvar_node
4566 self.py_loopvar_node = \
4567 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4568 self.body.analyse_expressions(env)
4569 if self.else_clause:
4570 self.else_clause.analyse_expressions(env)
4572 def generate_execution_code(self, code):
4573 old_loop_labels = code.new_loop_labels()
4574 from_range = self.from_range
4575 self.bound1.generate_evaluation_code(code)
4576 self.bound2.generate_evaluation_code(code)
4577 offset, incop = self.relation_table[self.relation1]
4578 if self.step is not None:
4579 self.step.generate_evaluation_code(code)
4580 step = self.step.result()
4581 incop = "%s=%s" % (incop[0], step)
4583 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4584 self.loopvar_node.allocate(code)
4585 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4586 self.py_loopvar_node.allocate(code)
4588 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4590 loopvar_name = self.loopvar_node.result()
4592 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4594 self.bound1.result(), offset,
4595 loopvar_name, self.relation2, self.bound2.result(),
4596 loopvar_name, incop))
4597 if self.py_loopvar_node:
4598 self.py_loopvar_node.generate_evaluation_code(code)
4599 self.target.generate_assignment_code(self.py_loopvar_node, code)
4601 code.putln("%s = %s;" % (
4602 self.target.result(), loopvar_name))
4603 self.body.generate_execution_code(code)
4604 code.put_label(code.continue_label)
4605 if self.py_loopvar_node:
4606 # This mess is to make for..from loops with python targets behave
4607 # exactly like those with C targets with regards to re-assignment
4608 # of the loop variable.
4610 if self.target.entry.is_pyglobal:
4611 # We know target is a NameNode, this is the only ugly case.
4612 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4613 target_node.allocate(code)
4614 interned_cname = code.intern_identifier(self.target.entry.name)
4615 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4616 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4617 target_node.result(),
4618 Naming.module_cname,
4620 code.error_goto_if_null(target_node.result(), self.target.pos)))
4621 code.put_gotref(target_node.result())
4623 target_node = self.target
4624 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4625 from_py_node.temp_code = loopvar_name
4626 from_py_node.generate_result_code(code)
4627 if self.target.entry.is_pyglobal:
4628 code.put_decref(target_node.result(), target_node.type)
4629 target_node.release(code)
4631 if self.py_loopvar_node:
4632 # This is potentially wasteful, but we don't want the semantics to
4633 # depend on whether or not the loop is a python type.
4634 self.py_loopvar_node.generate_evaluation_code(code)
4635 self.target.generate_assignment_code(self.py_loopvar_node, code)
4637 code.funcstate.release_temp(loopvar_name)
4638 break_label = code.break_label
4639 code.set_loop_labels(old_loop_labels)
4640 if self.else_clause:
4641 code.putln("/*else*/ {")
4642 self.else_clause.generate_execution_code(code)
4644 code.put_label(break_label)
4645 self.bound1.generate_disposal_code(code)
4646 self.bound1.free_temps(code)
4647 self.bound2.generate_disposal_code(code)
4648 self.bound2.free_temps(code)
4649 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4650 self.loopvar_node.release(code)
4651 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4652 self.py_loopvar_node.release(code)
4653 if self.step is not None:
4654 self.step.generate_disposal_code(code)
4655 self.step.free_temps(code)
4658 # {relop : (initial offset, increment op)}
4665 def generate_function_definitions(self, env, code):
4666 self.target.generate_function_definitions(env, code)
4667 self.bound1.generate_function_definitions(env, code)
4668 self.bound2.generate_function_definitions(env, code)
4669 if self.step is not None:
4670 self.step.generate_function_definitions(env, code)
4671 self.body.generate_function_definitions(env, code)
4672 if self.else_clause is not None:
4673 self.else_clause.generate_function_definitions(env, code)
4675 def annotate(self, code):
4676 self.target.annotate(code)
4677 self.bound1.annotate(code)
4678 self.bound2.annotate(code)
4680 self.step.annotate(code)
4681 self.body.annotate(code)
4682 if self.else_clause:
4683 self.else_clause.annotate(code)
4686 class WithStatNode(StatNode):
4688 Represents a Python with statement.
4690 This is only used at parse tree level; and is not present in
4691 analysis or generation phases.
4693 # manager The with statement manager object
4694 # target Node (lhs expression)
4696 child_attrs = ["manager", "target", "body"]
4698 class TryExceptStatNode(StatNode):
4699 # try .. except statement
4702 # except_clauses [ExceptClauseNode]
4703 # else_clause StatNode or None
4705 child_attrs = ["body", "except_clauses", "else_clause"]
4707 def analyse_control_flow(self, env):
4708 env.start_branching(self.pos)
4709 self.body.analyse_control_flow(env)
4710 successful_try = env.control_flow # grab this for later
4711 env.next_branch(self.body.end_pos())
4712 env.finish_branching(self.body.end_pos())
4714 env.start_branching(self.except_clauses[0].pos)
4715 for except_clause in self.except_clauses:
4716 except_clause.analyse_control_flow(env)
4717 env.next_branch(except_clause.end_pos())
4719 # the else cause it executed only when the try clause finishes
4720 env.control_flow.incoming = successful_try
4721 if self.else_clause:
4722 self.else_clause.analyse_control_flow(env)
4723 env.finish_branching(self.end_pos())
4725 def analyse_declarations(self, env):
4726 self.body.analyse_declarations(env)
4727 for except_clause in self.except_clauses:
4728 except_clause.analyse_declarations(env)
4729 if self.else_clause:
4730 self.else_clause.analyse_declarations(env)
4731 env.use_utility_code(reset_exception_utility_code)
4733 def analyse_expressions(self, env):
4734 self.body.analyse_expressions(env)
4735 default_clause_seen = 0
4736 for except_clause in self.except_clauses:
4737 except_clause.analyse_expressions(env)
4738 if default_clause_seen:
4739 error(except_clause.pos, "default 'except:' must be last")
4740 if not except_clause.pattern:
4741 default_clause_seen = 1
4742 self.has_default_clause = default_clause_seen
4743 if self.else_clause:
4744 self.else_clause.analyse_expressions(env)
4746 nogil_check = Node.gil_error
4747 gil_message = "Try-except statement"
4749 def generate_execution_code(self, code):
4750 old_return_label = code.return_label
4751 old_break_label = code.break_label
4752 old_continue_label = code.continue_label
4753 old_error_label = code.new_error_label()
4754 our_error_label = code.error_label
4755 except_end_label = code.new_label('exception_handled')
4756 except_error_label = code.new_label('except_error')
4757 except_return_label = code.new_label('except_return')
4758 try_return_label = code.new_label('try_return')
4759 try_break_label = code.new_label('try_break')
4760 try_continue_label = code.new_label('try_continue')
4761 try_end_label = code.new_label('try_end')
4763 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4766 code.putln("__Pyx_ExceptionSave(%s);" %
4767 ', '.join(['&%s' % var for var in exc_save_vars]))
4768 for var in exc_save_vars:
4769 code.put_xgotref(var)
4772 code.return_label = try_return_label
4773 code.break_label = try_break_label
4774 code.continue_label = try_continue_label
4775 self.body.generate_execution_code(code)
4778 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4779 code.error_label = except_error_label
4780 code.return_label = except_return_label
4781 if self.else_clause:
4784 self.else_clause.generate_execution_code(code)
4787 for var in exc_save_vars:
4788 code.put_xdecref_clear(var, py_object_type)
4789 code.put_goto(try_end_label)
4790 if code.label_used(try_return_label):
4791 code.put_label(try_return_label)
4792 for var in exc_save_vars: code.put_xgiveref(var)
4793 code.putln("__Pyx_ExceptionReset(%s);" %
4794 ', '.join(exc_save_vars))
4795 code.put_goto(old_return_label)
4796 code.put_label(our_error_label)
4797 for temp_name, type in temps_to_clean_up:
4798 code.put_xdecref_clear(temp_name, type)
4799 for except_clause in self.except_clauses:
4800 except_clause.generate_handling_code(code, except_end_label)
4802 error_label_used = code.label_used(except_error_label)
4803 if error_label_used or not self.has_default_clause:
4804 if error_label_used:
4805 code.put_label(except_error_label)
4806 for var in exc_save_vars: code.put_xgiveref(var)
4807 code.putln("__Pyx_ExceptionReset(%s);" %
4808 ', '.join(exc_save_vars))
4809 code.put_goto(old_error_label)
4811 for exit_label, old_label in zip(
4812 [try_break_label, try_continue_label, except_return_label],
4813 [old_break_label, old_continue_label, old_return_label]):
4815 if code.label_used(exit_label):
4816 code.put_label(exit_label)
4817 for var in exc_save_vars: code.put_xgiveref(var)
4818 code.putln("__Pyx_ExceptionReset(%s);" %
4819 ', '.join(exc_save_vars))
4820 code.put_goto(old_label)
4822 if code.label_used(except_end_label):
4823 code.put_label(except_end_label)
4824 for var in exc_save_vars: code.put_xgiveref(var)
4825 code.putln("__Pyx_ExceptionReset(%s);" %
4826 ', '.join(exc_save_vars))
4827 code.put_label(try_end_label)
4830 for cname in exc_save_vars:
4831 code.funcstate.release_temp(cname)
4833 code.return_label = old_return_label
4834 code.break_label = old_break_label
4835 code.continue_label = old_continue_label
4836 code.error_label = old_error_label
4838 def generate_function_definitions(self, env, code):
4839 self.body.generate_function_definitions(env, code)
4840 for except_clause in self.except_clauses:
4841 except_clause.generate_function_definitions(env, code)
4842 if self.else_clause is not None:
4843 self.else_clause.generate_function_definitions(env, code)
4845 def annotate(self, code):
4846 self.body.annotate(code)
4847 for except_node in self.except_clauses:
4848 except_node.annotate(code)
4849 if self.else_clause:
4850 self.else_clause.annotate(code)
4853 class ExceptClauseNode(Node):
4854 # Part of try ... except statement.
4856 # pattern [ExprNode]
4857 # target ExprNode or None
4859 # excinfo_target NameNode or None optional target for exception info
4860 # match_flag string result of exception match
4861 # exc_value ExcValueNode used internally
4862 # function_name string qualified name of enclosing function
4863 # exc_vars (string * 3) local exception variables
4865 # excinfo_target is never set by the parser, but can be set by a transform
4866 # in order to extract more extensive information about the exception as a
4867 # sys.exc_info()-style tuple into a target variable
4869 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4872 excinfo_target = None
4874 def analyse_declarations(self, env):
4876 self.target.analyse_target_declaration(env)
4877 if self.excinfo_target is not None:
4878 self.excinfo_target.analyse_target_declaration(env)
4879 self.body.analyse_declarations(env)
4881 def analyse_expressions(self, env):
4883 genv = env.global_scope()
4884 self.function_name = env.qualified_name
4886 # normalise/unpack self.pattern into a list
4887 for i, pattern in enumerate(self.pattern):
4888 pattern.analyse_expressions(env)
4889 self.pattern[i] = pattern.coerce_to_pyobject(env)
4892 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4893 self.target.analyse_target_expression(env, self.exc_value)
4894 if self.excinfo_target is not None:
4896 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4897 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4898 self.excinfo_tuple.analyse_expressions(env)
4899 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4901 self.body.analyse_expressions(env)
4903 def generate_handling_code(self, code, end_label):
4904 code.mark_pos(self.pos)
4907 for pattern in self.pattern:
4908 pattern.generate_evaluation_code(code)
4909 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4911 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4913 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4914 for pattern in self.pattern:
4915 pattern.generate_disposal_code(code)
4916 pattern.free_temps(code)
4920 code.funcstate.release_temp(match_flag)
4922 code.putln("/*except:*/ {")
4924 if not getattr(self.body, 'stats', True) and \
4925 self.excinfo_target is None and self.target is None:
4926 # most simple case: no exception variable, empty body (pass)
4927 # => reset the exception state, done
4928 code.putln("PyErr_Restore(0,0,0);")
4929 code.put_goto(end_label)
4933 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4936 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4937 # We always have to fetch the exception value even if
4938 # there is no target, because this also normalises the
4939 # exception and stores it in the thread state.
4940 code.globalstate.use_utility_code(get_exception_utility_code)
4941 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4942 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4943 code.error_goto(self.pos)))
4947 self.exc_value.set_var(exc_vars[1])
4948 self.exc_value.generate_evaluation_code(code)
4949 self.target.generate_assignment_code(self.exc_value, code)
4950 if self.excinfo_target is not None:
4951 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4952 node.set_var(tempvar)
4953 self.excinfo_tuple.generate_evaluation_code(code)
4954 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4956 old_break_label, old_continue_label = code.break_label, code.continue_label
4957 code.break_label = code.new_label('except_break')
4958 code.continue_label = code.new_label('except_continue')
4960 old_exc_vars = code.funcstate.exc_vars
4961 code.funcstate.exc_vars = exc_vars
4962 self.body.generate_execution_code(code)
4963 code.funcstate.exc_vars = old_exc_vars
4964 for var in exc_vars:
4965 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4966 code.put_goto(end_label)
4968 if code.label_used(code.break_label):
4969 code.put_label(code.break_label)
4970 for var in exc_vars:
4971 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4972 code.put_goto(old_break_label)
4973 code.break_label = old_break_label
4975 if code.label_used(code.continue_label):
4976 code.put_label(code.continue_label)
4977 for var in exc_vars:
4978 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4979 code.put_goto(old_continue_label)
4980 code.continue_label = old_continue_label
4982 for temp in exc_vars:
4983 code.funcstate.release_temp(temp)
4988 def generate_function_definitions(self, env, code):
4989 if self.target is not None:
4990 self.target.generate_function_definitions(env, code)
4991 self.body.generate_function_definitions(env, code)
4993 def annotate(self, code):
4995 for pattern in self.pattern:
4996 pattern.annotate(code)
4998 self.target.annotate(code)
4999 self.body.annotate(code)
5002 class TryFinallyStatNode(StatNode):
5003 # try ... finally statement
5006 # finally_clause StatNode
5008 # The plan is that we funnel all continue, break
5009 # return and error gotos into the beginning of the
5010 # finally block, setting a variable to remember which
5011 # one we're doing. At the end of the finally block, we
5012 # switch on the variable to figure out where to go.
5013 # In addition, if we're doing an error, we save the
5014 # exception on entry to the finally block and restore
5017 child_attrs = ["body", "finally_clause"]
5019 preserve_exception = 1
5021 disallow_continue_in_try_finally = 0
5022 # There doesn't seem to be any point in disallowing
5023 # continue in the try block, since we have no problem
5026 def create_analysed(pos, env, body, finally_clause):
5027 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5029 create_analysed = staticmethod(create_analysed)
5031 def analyse_control_flow(self, env):
5032 env.start_branching(self.pos)
5033 self.body.analyse_control_flow(env)
5034 env.next_branch(self.body.end_pos())
5035 env.finish_branching(self.body.end_pos())
5036 self.finally_clause.analyse_control_flow(env)
5038 def analyse_declarations(self, env):
5039 self.body.analyse_declarations(env)
5040 self.finally_clause.analyse_declarations(env)
5042 def analyse_expressions(self, env):
5043 self.body.analyse_expressions(env)
5044 self.finally_clause.analyse_expressions(env)
5046 nogil_check = Node.gil_error
5047 gil_message = "Try-finally statement"
5049 def generate_execution_code(self, code):
5050 old_error_label = code.error_label
5051 old_labels = code.all_new_labels()
5052 new_labels = code.get_all_labels()
5053 new_error_label = code.error_label
5054 catch_label = code.new_label()
5057 if self.disallow_continue_in_try_finally:
5058 was_in_try_finally = code.funcstate.in_try_finally
5059 code.funcstate.in_try_finally = 1
5060 self.body.generate_execution_code(code)
5061 if self.disallow_continue_in_try_finally:
5062 code.funcstate.in_try_finally = was_in_try_finally
5065 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5066 code.mark_pos(self.finally_clause.pos)
5070 error_label_used = 0
5071 for i, new_label in enumerate(new_labels):
5072 if new_label in code.labels_used:
5073 cases_used.append(i)
5074 if new_label == new_error_label:
5075 error_label_used = 1
5076 error_label_case = i
5080 if error_label_used and self.preserve_exception:
5082 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5084 "int %s;" % Naming.exc_lineno_name)
5085 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5086 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5087 code.putln(exc_var_init_zero)
5089 exc_var_init_zero = None
5090 code.use_label(catch_label)
5092 "__pyx_why = 0; goto %s;" % catch_label)
5093 for i in cases_used:
5094 new_label = new_labels[i]
5095 #if new_label and new_label != "<try>":
5096 if new_label == new_error_label and self.preserve_exception:
5097 self.put_error_catcher(code,
5098 new_error_label, i+1, catch_label, temps_to_clean_up)
5100 code.put('%s: ' % new_label)
5101 if exc_var_init_zero:
5102 code.putln(exc_var_init_zero)
5103 code.putln("__pyx_why = %s; goto %s;" % (
5106 code.put_label(catch_label)
5107 code.set_all_labels(old_labels)
5108 if error_label_used:
5109 code.new_error_label()
5110 finally_error_label = code.error_label
5111 self.finally_clause.generate_execution_code(code)
5112 if error_label_used:
5113 if finally_error_label in code.labels_used and self.preserve_exception:
5114 over_label = code.new_label()
5115 code.put_goto(over_label);
5116 code.put_label(finally_error_label)
5117 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5118 for var in Naming.exc_vars:
5119 code.putln("Py_XDECREF(%s);" % var)
5121 code.put_goto(old_error_label)
5122 code.put_label(over_label)
5123 code.error_label = old_error_label
5126 "switch (__pyx_why) {")
5127 for i in cases_used:
5128 old_label = old_labels[i]
5129 if old_label == old_error_label and self.preserve_exception:
5130 self.put_error_uncatcher(code, i+1, old_error_label)
5132 code.use_label(old_label)
5134 "case %s: goto %s;" % (
5142 def generate_function_definitions(self, env, code):
5143 self.body.generate_function_definitions(env, code)
5144 self.finally_clause.generate_function_definitions(env, code)
5146 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5147 code.globalstate.use_utility_code(restore_exception_utility_code)
5154 for temp_name, type in temps_to_clean_up:
5155 code.put_xdecref_clear(temp_name, type)
5157 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5161 Naming.exc_lineno_name, Naming.lineno_cname))
5162 code.put_goto(catch_label)
5165 def put_error_uncatcher(self, code, i, error_label):
5166 code.globalstate.use_utility_code(restore_exception_utility_code)
5171 "__Pyx_ErrRestore(%s, %s, %s);" %
5175 Naming.lineno_cname, Naming.exc_lineno_name))
5176 for var in Naming.exc_vars:
5180 code.put_goto(error_label)
5184 def annotate(self, code):
5185 self.body.annotate(code)
5186 self.finally_clause.annotate(code)
5189 class GILStatNode(TryFinallyStatNode):
5190 # 'with gil' or 'with nogil' statement
5192 # state string 'gil' or 'nogil'
5196 preserve_exception = 0
5198 def __init__(self, pos, state, body):
5200 TryFinallyStatNode.__init__(self, pos,
5202 finally_clause = GILExitNode(pos, state = state))
5204 def analyse_expressions(self, env):
5205 env.use_utility_code(force_init_threads_utility_code)
5206 was_nogil = env.nogil
5208 TryFinallyStatNode.analyse_expressions(self, env)
5209 env.nogil = was_nogil
5213 def generate_execution_code(self, code):
5214 code.mark_pos(self.pos)
5216 if self.state == 'gil':
5217 code.putln("#ifdef WITH_THREAD")
5218 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5219 code.putln("#endif")
5221 code.putln("#ifdef WITH_THREAD")
5222 code.putln("PyThreadState *_save;")
5223 code.putln("#endif")
5224 code.putln("Py_UNBLOCK_THREADS")
5225 TryFinallyStatNode.generate_execution_code(self, code)
5229 class GILExitNode(StatNode):
5230 # Used as the 'finally' block in a GILStatNode
5232 # state string 'gil' or 'nogil'
5236 def analyse_expressions(self, env):
5239 def generate_execution_code(self, code):
5240 if self.state == 'gil':
5241 code.putln("#ifdef WITH_THREAD")
5242 code.putln("PyGILState_Release(_save);")
5243 code.putln("#endif")
5245 code.putln("Py_BLOCK_THREADS")
5248 class CImportStatNode(StatNode):
5251 # module_name string Qualified name of module being imported
5252 # as_name string or None Name specified in "as" clause, if any
5256 def analyse_declarations(self, env):
5257 if not env.is_module_scope:
5258 error(self.pos, "cimport only allowed at module level")
5260 module_scope = env.find_module(self.module_name, self.pos)
5261 if "." in self.module_name:
5262 names = [EncodedString(name) for name in self.module_name.split(".")]
5264 top_module_scope = env.context.find_submodule(top_name)
5265 module_scope = top_module_scope
5266 for name in names[1:]:
5267 submodule_scope = module_scope.find_submodule(name)
5268 module_scope.declare_module(name, submodule_scope, self.pos)
5269 module_scope = submodule_scope
5271 env.declare_module(self.as_name, module_scope, self.pos)
5273 env.declare_module(top_name, top_module_scope, self.pos)
5275 name = self.as_name or self.module_name
5276 env.declare_module(name, module_scope, self.pos)
5278 def analyse_expressions(self, env):
5281 def generate_execution_code(self, code):
5285 class FromCImportStatNode(StatNode):
5286 # from ... cimport statement
5288 # module_name string Qualified name of module
5289 # imported_names [(pos, name, as_name, kind)] Names to be imported
5293 def analyse_declarations(self, env):
5294 if not env.is_module_scope:
5295 error(self.pos, "cimport only allowed at module level")
5297 module_scope = env.find_module(self.module_name, self.pos)
5298 env.add_imported_module(module_scope)
5299 for pos, name, as_name, kind in self.imported_names:
5301 for local_name, entry in module_scope.entries.items():
5302 env.add_imported_entry(local_name, entry, pos)
5304 entry = module_scope.lookup(name)
5306 if kind and not self.declaration_matches(entry, kind):
5307 entry.redeclared(pos)
5309 if kind == 'struct' or kind == 'union':
5310 entry = module_scope.declare_struct_or_union(name,
5311 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5312 elif kind == 'class':
5313 entry = module_scope.declare_c_class(name, pos = pos,
5314 module_name = self.module_name)
5316 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5317 if submodule_scope.parent_module is module_scope:
5318 env.declare_module(as_name or name, submodule_scope, self.pos)
5320 error(pos, "Name '%s' not declared in module '%s'"
5321 % (name, self.module_name))
5324 local_name = as_name or name
5325 env.add_imported_entry(local_name, entry, pos)
5327 def declaration_matches(self, entry, kind):
5328 if not entry.is_type:
5332 if not type.is_extension_type:
5335 if not type.is_struct_or_union:
5337 if kind != type.kind:
5341 def analyse_expressions(self, env):
5344 def generate_execution_code(self, code):
5348 class FromImportStatNode(StatNode):
5349 # from ... import statement
5352 # items [(string, NameNode)]
5353 # interned_items [(string, NameNode, ExprNode)]
5354 # item PyTempNode used internally
5355 # import_star boolean used internally
5357 child_attrs = ["module"]
5360 def analyse_declarations(self, env):
5361 for name, target in self.items:
5363 if not env.is_module_scope:
5364 error(self.pos, "import * only allowed at module level")
5366 env.has_import_star = 1
5367 self.import_star = 1
5369 target.analyse_target_declaration(env)
5371 def analyse_expressions(self, env):
5373 self.module.analyse_expressions(env)
5374 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5375 self.interned_items = []
5376 for name, target in self.items:
5378 for _, entry in env.entries.items():
5379 if not entry.is_type and entry.type.is_extension_type:
5380 env.use_utility_code(ExprNodes.type_test_utility_code)
5383 entry = env.lookup(target.name)
5384 # check whether or not entry is already cimported
5385 if (entry.is_type and entry.type.name == name
5386 and hasattr(entry.type, 'module_name')):
5387 if entry.type.module_name == self.module.module_name.value:
5388 # cimported with absolute name
5391 # cimported with relative name
5392 module = env.find_module(self.module.module_name.value,
5394 if entry.type.module_name == module.qualified_name:
5396 except AttributeError:
5398 target.analyse_target_expression(env, None)
5399 if target.type is py_object_type:
5402 coerced_item = self.item.coerce_to(target.type, env)
5403 self.interned_items.append((name, target, coerced_item))
5405 def generate_execution_code(self, code):
5406 self.module.generate_evaluation_code(code)
5407 if self.import_star:
5409 'if (%s(%s) < 0) %s;' % (
5411 self.module.py_result(),
5412 code.error_goto(self.pos)))
5413 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5414 self.item.set_cname(item_temp)
5415 for name, target, coerced_item in self.interned_items:
5416 cname = code.intern_identifier(name)
5418 '%s = PyObject_GetAttr(%s, %s); %s' % (
5420 self.module.py_result(),
5422 code.error_goto_if_null(item_temp, self.pos)))
5423 code.put_gotref(item_temp)
5424 if coerced_item is None:
5425 target.generate_assignment_code(self.item, code)
5427 coerced_item.allocate_temp_result(code)
5428 coerced_item.generate_result_code(code)
5429 target.generate_assignment_code(coerced_item, code)
5430 code.put_decref_clear(item_temp, py_object_type)
5431 code.funcstate.release_temp(item_temp)
5432 self.module.generate_disposal_code(code)
5433 self.module.free_temps(code)
5437 #------------------------------------------------------------------------------------
5439 # Runtime support code
5441 #------------------------------------------------------------------------------------
5443 utility_function_predeclarations = \
5445 /* inline attribute */
5446 #ifndef CYTHON_INLINE
5447 #if defined(__GNUC__)
5448 #define CYTHON_INLINE __inline__
5449 #elif defined(_MSC_VER)
5450 #define CYTHON_INLINE __inline
5451 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5452 #define CYTHON_INLINE inline
5454 #define CYTHON_INLINE
5458 /* unused attribute */
5459 #ifndef CYTHON_UNUSED
5460 # if defined(__GNUC__)
5461 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5462 # define CYTHON_UNUSED __attribute__ ((__unused__))
5464 # define CYTHON_UNUSED
5466 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5467 # define CYTHON_UNUSED __attribute__ ((__unused__))
5469 # define CYTHON_UNUSED
5473 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*/
5477 if Options.gcc_branch_hints:
5478 branch_prediction_macros = \
5481 /* Test for GCC > 2.95 */
5482 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5483 #define likely(x) __builtin_expect(!!(x), 1)
5484 #define unlikely(x) __builtin_expect(!!(x), 0)
5485 #else /* __GNUC__ > 2 ... */
5486 #define likely(x) (x)
5487 #define unlikely(x) (x)
5488 #endif /* __GNUC__ > 2 ... */
5489 #else /* __GNUC__ */
5490 #define likely(x) (x)
5491 #define unlikely(x) (x)
5492 #endif /* __GNUC__ */
5495 branch_prediction_macros = \
5497 #define likely(x) (x)
5498 #define unlikely(x) (x)
5501 #get_name_predeclaration = \
5502 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5504 #get_name_interned_predeclaration = \
5505 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5507 #------------------------------------------------------------------------------------
5509 printing_utility_code = UtilityCode(
5511 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5512 #if PY_MAJOR_VERSION >= 3
5513 static PyObject* %s = 0;
5514 static PyObject* %s = 0;
5516 """ % (Naming.print_function, Naming.print_function_kwargs),
5518 #if PY_MAJOR_VERSION >= 3
5522 """ % (Naming.print_function, Naming.print_function_kwargs),
5524 #if PY_MAJOR_VERSION < 3
5525 static PyObject *__Pyx_GetStdout(void) {
5526 PyObject *f = PySys_GetObject((char *)"stdout");
5528 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5533 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5538 if (!(f = __Pyx_GetStdout()))
5541 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5542 if (PyFile_SoftSpace(f, 1)) {
5543 if (PyFile_WriteString(" ", f) < 0)
5546 v = PyTuple_GET_ITEM(arg_tuple, i);
5547 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5549 if (PyString_Check(v)) {
5550 char *s = PyString_AsString(v);
5551 Py_ssize_t len = PyString_Size(v);
5553 isspace(Py_CHARMASK(s[len-1])) &&
5555 PyFile_SoftSpace(f, 0);
5559 if (PyFile_WriteString("\n", f) < 0)
5561 PyFile_SoftSpace(f, 0);
5566 #else /* Python 3 has a print function */
5568 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5569 PyObject* kwargs = 0;
5570 PyObject* result = 0;
5571 PyObject* end_string;
5572 if (unlikely(!%(PRINT_FUNCTION)s)) {
5573 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5574 if (!%(PRINT_FUNCTION)s)
5578 kwargs = PyDict_New();
5579 if (unlikely(!kwargs))
5581 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5584 end_string = PyUnicode_FromStringAndSize(" ", 1);
5585 if (unlikely(!end_string))
5587 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5588 Py_DECREF(end_string);
5591 Py_DECREF(end_string);
5593 } else if (!newline) {
5594 if (unlikely(!%(PRINT_KWARGS)s)) {
5595 %(PRINT_KWARGS)s = PyDict_New();
5596 if (unlikely(!%(PRINT_KWARGS)s))
5598 end_string = PyUnicode_FromStringAndSize(" ", 1);
5599 if (unlikely(!end_string))
5601 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5602 Py_DECREF(end_string);
5605 Py_DECREF(end_string);
5607 kwargs = %(PRINT_KWARGS)s;
5609 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5610 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5617 if (kwargs != %(PRINT_KWARGS)s)
5623 """ % {'BUILTINS' : Naming.builtins_cname,
5624 'PRINT_FUNCTION' : Naming.print_function,
5625 'PRINT_KWARGS' : Naming.print_function_kwargs}
5629 printing_one_utility_code = UtilityCode(
5631 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5634 #if PY_MAJOR_VERSION < 3
5636 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5638 if (!(f = __Pyx_GetStdout()))
5641 if (PyFile_SoftSpace(f, 0)) {
5642 if (PyFile_WriteString(" ", f) < 0)
5645 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5647 if (PyFile_WriteString("\n", f) < 0)
5650 /* the line below is just to avoid compiler
5651 * compiler warnings about unused functions */
5652 return __Pyx_Print(f, NULL, 0);
5655 #else /* Python 3 has a print function */
5657 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5659 PyObject* arg_tuple = PyTuple_New(1);
5660 if (unlikely(!arg_tuple))
5663 PyTuple_SET_ITEM(arg_tuple, 0, o);
5664 res = __Pyx_Print(stream, arg_tuple, 1);
5665 Py_DECREF(arg_tuple);
5671 requires=[printing_utility_code])
5675 #------------------------------------------------------------------------------------
5677 # Exception raising code
5679 # Exceptions are raised by __Pyx_Raise() and stored as plain
5680 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5681 # 'except' statement, curexc_* is moved over to exc_* by
5682 # __Pyx_GetException()
5684 restore_exception_utility_code = UtilityCode(
5686 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5687 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5690 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5691 PyObject *tmp_type, *tmp_value, *tmp_tb;
5692 PyThreadState *tstate = PyThreadState_GET();
5694 tmp_type = tstate->curexc_type;
5695 tmp_value = tstate->curexc_value;
5696 tmp_tb = tstate->curexc_traceback;
5697 tstate->curexc_type = type;
5698 tstate->curexc_value = value;
5699 tstate->curexc_traceback = tb;
5700 Py_XDECREF(tmp_type);
5701 Py_XDECREF(tmp_value);
5705 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5706 PyThreadState *tstate = PyThreadState_GET();
5707 *type = tstate->curexc_type;
5708 *value = tstate->curexc_value;
5709 *tb = tstate->curexc_traceback;
5711 tstate->curexc_type = 0;
5712 tstate->curexc_value = 0;
5713 tstate->curexc_traceback = 0;
5718 # The following function is based on do_raise() from ceval.c. There
5719 # are separate versions for Python2 and Python3 as exception handling
5720 # has changed quite a lot between the two versions.
5722 raise_utility_code = UtilityCode(
5724 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5727 #if PY_MAJOR_VERSION < 3
5728 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5732 /* First, check the traceback argument, replacing None with NULL. */
5733 if (tb == Py_None) {
5737 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5738 PyErr_SetString(PyExc_TypeError,
5739 "raise: arg 3 must be a traceback or None");
5742 /* Next, replace a missing value with None */
5743 if (value == NULL) {
5747 #if PY_VERSION_HEX < 0x02050000
5748 if (!PyClass_Check(type))
5750 if (!PyType_Check(type))
5753 /* Raising an instance. The value should be a dummy. */
5754 if (value != Py_None) {
5755 PyErr_SetString(PyExc_TypeError,
5756 "instance exception may not have a separate value");
5759 /* Normalize to raise <class>, <instance> */
5762 #if PY_VERSION_HEX < 0x02050000
5763 if (PyInstance_Check(type)) {
5764 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5769 PyErr_SetString(PyExc_TypeError,
5770 "raise: exception must be an old-style class or instance");
5774 type = (PyObject*) Py_TYPE(type);
5776 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5777 PyErr_SetString(PyExc_TypeError,
5778 "raise: exception class must be a subclass of BaseException");
5784 __Pyx_ErrRestore(type, value, tb);
5793 #else /* Python 3+ */
5795 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5796 if (tb == Py_None) {
5798 } else if (tb && !PyTraceBack_Check(tb)) {
5799 PyErr_SetString(PyExc_TypeError,
5800 "raise: arg 3 must be a traceback or None");
5803 if (value == Py_None)
5806 if (PyExceptionInstance_Check(type)) {
5808 PyErr_SetString(PyExc_TypeError,
5809 "instance exception may not have a separate value");
5813 type = (PyObject*) Py_TYPE(value);
5814 } else if (!PyExceptionClass_Check(type)) {
5815 PyErr_SetString(PyExc_TypeError,
5816 "raise: exception class must be a subclass of BaseException");
5820 PyErr_SetObject(type, value);
5823 PyThreadState *tstate = PyThreadState_GET();
5824 PyObject* tmp_tb = tstate->curexc_traceback;
5827 tstate->curexc_traceback = tb;
5837 requires=[restore_exception_utility_code])
5839 #------------------------------------------------------------------------------------
5841 get_exception_utility_code = UtilityCode(
5843 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5846 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5847 PyObject *local_type, *local_value, *local_tb;
5848 PyObject *tmp_type, *tmp_value, *tmp_tb;
5849 PyThreadState *tstate = PyThreadState_GET();
5850 local_type = tstate->curexc_type;
5851 local_value = tstate->curexc_value;
5852 local_tb = tstate->curexc_traceback;
5853 tstate->curexc_type = 0;
5854 tstate->curexc_value = 0;
5855 tstate->curexc_traceback = 0;
5856 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5857 if (unlikely(tstate->curexc_type))
5859 #if PY_MAJOR_VERSION >= 3
5860 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5864 *value = local_value;
5866 Py_INCREF(local_type);
5867 Py_INCREF(local_value);
5868 Py_INCREF(local_tb);
5869 tmp_type = tstate->exc_type;
5870 tmp_value = tstate->exc_value;
5871 tmp_tb = tstate->exc_traceback;
5872 tstate->exc_type = local_type;
5873 tstate->exc_value = local_value;
5874 tstate->exc_traceback = local_tb;
5875 /* Make sure tstate is in a consistent state when we XDECREF
5876 these objects (XDECREF may run arbitrary code). */
5877 Py_XDECREF(tmp_type);
5878 Py_XDECREF(tmp_value);
5885 Py_XDECREF(local_type);
5886 Py_XDECREF(local_value);
5887 Py_XDECREF(local_tb);
5893 #------------------------------------------------------------------------------------
5895 get_exception_tuple_utility_code = UtilityCode(proto="""
5896 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5898 # I doubt that calling __Pyx_GetException() here is correct as it moves
5899 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5900 # exception handlers later on from receiving it.
5902 static PyObject *__Pyx_GetExceptionTuple(void) {
5903 PyObject *type = NULL, *value = NULL, *tb = NULL;
5904 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5905 PyObject* exc_info = PyTuple_New(3);
5910 PyTuple_SET_ITEM(exc_info, 0, type);
5911 PyTuple_SET_ITEM(exc_info, 1, value);
5912 PyTuple_SET_ITEM(exc_info, 2, tb);
5919 requires=[get_exception_utility_code])
5921 #------------------------------------------------------------------------------------
5923 reset_exception_utility_code = UtilityCode(
5925 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5926 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5929 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5930 PyThreadState *tstate = PyThreadState_GET();
5931 *type = tstate->exc_type;
5932 *value = tstate->exc_value;
5933 *tb = tstate->exc_traceback;
5939 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5940 PyObject *tmp_type, *tmp_value, *tmp_tb;
5941 PyThreadState *tstate = PyThreadState_GET();
5942 tmp_type = tstate->exc_type;
5943 tmp_value = tstate->exc_value;
5944 tmp_tb = tstate->exc_traceback;
5945 tstate->exc_type = type;
5946 tstate->exc_value = value;
5947 tstate->exc_traceback = tb;
5948 Py_XDECREF(tmp_type);
5949 Py_XDECREF(tmp_value);
5954 #------------------------------------------------------------------------------------
5956 arg_type_test_utility_code = UtilityCode(
5958 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5959 const char *name, int exact); /*proto*/
5962 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5963 const char *name, int exact)
5966 PyErr_Format(PyExc_SystemError, "Missing type object");
5969 if (none_allowed && obj == Py_None) return 1;
5971 if (Py_TYPE(obj) == type) return 1;
5974 if (PyObject_TypeCheck(obj, type)) return 1;
5976 PyErr_Format(PyExc_TypeError,
5977 "Argument '%s' has incorrect type (expected %s, got %s)",
5978 name, type->tp_name, Py_TYPE(obj)->tp_name);
5983 #------------------------------------------------------------------------------------
5985 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5986 # many or too few positional arguments were found. This handles
5987 # Py_ssize_t formatting correctly.
5989 raise_argtuple_invalid_utility_code = UtilityCode(
5991 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5992 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5995 static void __Pyx_RaiseArgtupleInvalid(
5996 const char* func_name,
6000 Py_ssize_t num_found)
6002 Py_ssize_t num_expected;
6003 const char *number, *more_or_less;
6005 if (num_found < num_min) {
6006 num_expected = num_min;
6007 more_or_less = "at least";
6009 num_expected = num_max;
6010 more_or_less = "at most";
6013 more_or_less = "exactly";
6015 number = (num_expected == 1) ? "" : "s";
6016 PyErr_Format(PyExc_TypeError,
6017 #if PY_VERSION_HEX < 0x02050000
6018 "%s() takes %s %d positional argument%s (%d given)",
6020 "%s() takes %s %zd positional argument%s (%zd given)",
6022 func_name, more_or_less, num_expected, number, num_found);
6026 raise_keyword_required_utility_code = UtilityCode(
6028 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6031 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6032 const char* func_name,
6035 PyErr_Format(PyExc_TypeError,
6036 #if PY_MAJOR_VERSION >= 3
6037 "%s() needs keyword-only argument %U", func_name, kw_name);
6039 "%s() needs keyword-only argument %s", func_name,
6040 PyString_AS_STRING(kw_name));
6045 raise_double_keywords_utility_code = UtilityCode(
6047 static void __Pyx_RaiseDoubleKeywordsError(
6048 const char* func_name, PyObject* kw_name); /*proto*/
6051 static void __Pyx_RaiseDoubleKeywordsError(
6052 const char* func_name,
6055 PyErr_Format(PyExc_TypeError,
6056 #if PY_MAJOR_VERSION >= 3
6057 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6059 "%s() got multiple values for keyword argument '%s'", func_name,
6060 PyString_AS_STRING(kw_name));
6065 #------------------------------------------------------------------------------------
6067 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6068 # were passed to a function, or if any keywords were passed to a
6069 # function that does not accept them.
6071 keyword_string_check_utility_code = UtilityCode(
6073 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6074 const char* function_name, int kw_allowed); /*proto*/
6077 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6079 const char* function_name,
6084 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6085 #if PY_MAJOR_VERSION < 3
6086 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6088 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6090 goto invalid_keyword_type;
6092 if ((!kw_allowed) && unlikely(key))
6093 goto invalid_keyword;
6095 invalid_keyword_type:
6096 PyErr_Format(PyExc_TypeError,
6097 "%s() keywords must be strings", function_name);
6100 PyErr_Format(PyExc_TypeError,
6101 #if PY_MAJOR_VERSION < 3
6102 "%s() got an unexpected keyword argument '%s'",
6103 function_name, PyString_AsString(key));
6105 "%s() got an unexpected keyword argument '%U'",
6106 function_name, key);
6112 #------------------------------------------------------------------------------------
6114 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6115 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6116 # keywords will raise an invalid keyword error.
6118 # Three kinds of errors are checked: 1) non-string keywords, 2)
6119 # unexpected keywords and 3) overlap with positional arguments.
6121 # If num_posargs is greater 0, it denotes the number of positional
6122 # arguments that were passed and that must therefore not appear
6123 # amongst the keywords as well.
6125 # This method does not check for required keyword arguments.
6128 parse_keywords_utility_code = UtilityCode(
6130 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6131 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6132 const char* function_name); /*proto*/
6135 static int __Pyx_ParseOptionalKeywords(
6137 PyObject **argnames[],
6140 Py_ssize_t num_pos_args,
6141 const char* function_name)
6143 PyObject *key = 0, *value = 0;
6146 PyObject*** first_kw_arg = argnames + num_pos_args;
6148 while (PyDict_Next(kwds, &pos, &key, &value)) {
6149 name = first_kw_arg;
6150 while (*name && (**name != key)) name++;
6152 values[name-argnames] = value;
6154 #if PY_MAJOR_VERSION < 3
6155 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6157 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6159 goto invalid_keyword_type;
6161 for (name = first_kw_arg; *name; name++) {
6162 #if PY_MAJOR_VERSION >= 3
6163 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6164 PyUnicode_Compare(**name, key) == 0) break;
6166 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6167 _PyString_Eq(**name, key)) break;
6171 values[name-argnames] = value;
6173 /* unexpected keyword found */
6174 for (name=argnames; name != first_kw_arg; name++) {
6175 if (**name == key) goto arg_passed_twice;
6176 #if PY_MAJOR_VERSION >= 3
6177 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6178 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6180 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6181 _PyString_Eq(**name, key)) goto arg_passed_twice;
6185 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6187 goto invalid_keyword;
6195 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6197 invalid_keyword_type:
6198 PyErr_Format(PyExc_TypeError,
6199 "%s() keywords must be strings", function_name);
6202 PyErr_Format(PyExc_TypeError,
6203 #if PY_MAJOR_VERSION < 3
6204 "%s() got an unexpected keyword argument '%s'",
6205 function_name, PyString_AsString(key));
6207 "%s() got an unexpected keyword argument '%U'",
6208 function_name, key);
6215 #------------------------------------------------------------------------------------
6217 traceback_utility_code = UtilityCode(
6219 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6222 #include "compile.h"
6223 #include "frameobject.h"
6224 #include "traceback.h"
6226 static void __Pyx_AddTraceback(const char *funcname) {
6227 PyObject *py_srcfile = 0;
6228 PyObject *py_funcname = 0;
6229 PyObject *py_globals = 0;
6230 PyCodeObject *py_code = 0;
6231 PyFrameObject *py_frame = 0;
6233 #if PY_MAJOR_VERSION < 3
6234 py_srcfile = PyString_FromString(%(FILENAME)s);
6236 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6238 if (!py_srcfile) goto bad;
6240 #if PY_MAJOR_VERSION < 3
6241 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6243 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6247 #if PY_MAJOR_VERSION < 3
6248 py_funcname = PyString_FromString(funcname);
6250 py_funcname = PyUnicode_FromString(funcname);
6253 if (!py_funcname) goto bad;
6254 py_globals = PyModule_GetDict(%(GLOBALS)s);
6255 if (!py_globals) goto bad;
6256 py_code = PyCode_New(
6257 0, /*int argcount,*/
6258 #if PY_MAJOR_VERSION >= 3
6259 0, /*int kwonlyargcount,*/
6262 0, /*int stacksize,*/
6264 %(EMPTY_BYTES)s, /*PyObject *code,*/
6265 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6266 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6267 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6268 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6269 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6270 py_srcfile, /*PyObject *filename,*/
6271 py_funcname, /*PyObject *name,*/
6272 %(LINENO)s, /*int firstlineno,*/
6273 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6275 if (!py_code) goto bad;
6276 py_frame = PyFrame_New(
6277 PyThreadState_GET(), /*PyThreadState *tstate,*/
6278 py_code, /*PyCodeObject *code,*/
6279 py_globals, /*PyObject *globals,*/
6280 0 /*PyObject *locals*/
6282 if (!py_frame) goto bad;
6283 py_frame->f_lineno = %(LINENO)s;
6284 PyTraceBack_Here(py_frame);
6286 Py_XDECREF(py_srcfile);
6287 Py_XDECREF(py_funcname);
6288 Py_XDECREF(py_code);
6289 Py_XDECREF(py_frame);
6292 'FILENAME': Naming.filename_cname,
6293 'LINENO': Naming.lineno_cname,
6294 'CFILENAME': Naming.cfilenm_cname,
6295 'CLINENO': Naming.clineno_cname,
6296 'GLOBALS': Naming.module_cname,
6297 'EMPTY_TUPLE' : Naming.empty_tuple,
6298 'EMPTY_BYTES' : Naming.empty_bytes,
6301 #------------------------------------------------------------------------------------
6303 unraisable_exception_utility_code = UtilityCode(
6305 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6308 static void __Pyx_WriteUnraisable(const char *name) {
6309 PyObject *old_exc, *old_val, *old_tb;
6311 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6312 #if PY_MAJOR_VERSION < 3
6313 ctx = PyString_FromString(name);
6315 ctx = PyUnicode_FromString(name);
6317 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6319 PyErr_WriteUnraisable(Py_None);
6321 PyErr_WriteUnraisable(ctx);
6326 requires=[restore_exception_utility_code])
6328 #------------------------------------------------------------------------------------
6330 set_vtable_utility_code = UtilityCode(
6332 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6335 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6336 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6337 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6339 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6343 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6353 #------------------------------------------------------------------------------------
6355 get_vtable_utility_code = UtilityCode(
6357 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6360 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6361 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6364 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6365 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6367 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6369 if (!*(void **)vtabptr)
6379 #------------------------------------------------------------------------------------
6381 init_string_tab_utility_code = UtilityCode(
6383 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6386 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6388 #if PY_MAJOR_VERSION < 3
6389 if (t->is_unicode) {
6390 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6391 } else if (t->intern) {
6392 *t->p = PyString_InternFromString(t->s);
6394 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6396 #else /* Python 3+ has unicode identifiers */
6397 if (t->is_unicode | t->is_str) {
6399 *t->p = PyUnicode_InternFromString(t->s);
6400 } else if (t->encoding) {
6401 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6403 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6406 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6417 #------------------------------------------------------------------------------------
6419 force_init_threads_utility_code = UtilityCode(
6421 #ifndef __PYX_FORCE_INIT_THREADS
6422 #if PY_VERSION_HEX < 0x02040200
6423 #define __PYX_FORCE_INIT_THREADS 1
6425 #define __PYX_FORCE_INIT_THREADS 0
6430 #------------------------------------------------------------------------------------
6432 # Note that cPython ignores PyTrace_EXCEPTION,
6433 # but maybe some other profilers don't.
6435 profile_utility_code = UtilityCode(proto="""
6436 #ifndef CYTHON_PROFILE
6437 #define CYTHON_PROFILE 1
6440 #ifndef CYTHON_PROFILE_REUSE_FRAME
6441 #define CYTHON_PROFILE_REUSE_FRAME 0
6446 #include "compile.h"
6447 #include "frameobject.h"
6448 #include "traceback.h"
6450 #if CYTHON_PROFILE_REUSE_FRAME
6451 #define CYTHON_FRAME_MODIFIER static
6452 #define CYTHON_FRAME_DEL
6454 #define CYTHON_FRAME_MODIFIER
6455 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6458 #define __Pyx_TraceDeclarations \\
6459 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6460 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6461 int __Pyx_use_tracing = 0;
6463 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6464 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6465 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6468 #define __Pyx_TraceException() \\
6469 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6470 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6472 PyThreadState_GET()->c_profilefunc( \\
6473 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6474 Py_DECREF(exc_info); \\
6478 #define __Pyx_TraceReturn(result) \\
6479 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6480 PyThreadState_GET()->c_profilefunc( \\
6481 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6482 CYTHON_FRAME_DEL; \\
6485 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6486 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6490 #define __Pyx_TraceDeclarations
6491 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6492 #define __Pyx_TraceException()
6493 #define __Pyx_TraceReturn(result)
6495 #endif /* CYTHON_PROFILE */
6498 "FRAME": Naming.frame_cname,
6499 "FRAME_CODE": Naming.frame_code_cname,
6505 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6506 PyFrameObject** frame,
6507 const char *funcname,
6508 const char *srcfile,
6510 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6511 if (*code == NULL) {
6512 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6513 if (*code == NULL) return 0;
6515 *frame = PyFrame_New(
6516 PyThreadState_GET(), /*PyThreadState *tstate*/
6517 *code, /*PyCodeObject *code*/
6518 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6519 0 /*PyObject *locals*/
6521 if (*frame == NULL) return 0;
6524 (*frame)->f_tstate = PyThreadState_GET();
6526 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6529 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6530 PyObject *py_srcfile = 0;
6531 PyObject *py_funcname = 0;
6532 PyCodeObject *py_code = 0;
6534 #if PY_MAJOR_VERSION < 3
6535 py_funcname = PyString_FromString(funcname);
6536 py_srcfile = PyString_FromString(srcfile);
6538 py_funcname = PyUnicode_FromString(funcname);
6539 py_srcfile = PyUnicode_FromString(srcfile);
6541 if (!py_funcname | !py_srcfile) goto bad;
6543 py_code = PyCode_New(
6544 0, /*int argcount,*/
6545 #if PY_MAJOR_VERSION >= 3
6546 0, /*int kwonlyargcount,*/
6549 0, /*int stacksize,*/
6551 %(EMPTY_BYTES)s, /*PyObject *code,*/
6552 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6553 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6554 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6555 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6556 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6557 py_srcfile, /*PyObject *filename,*/
6558 py_funcname, /*PyObject *name,*/
6559 firstlineno, /*int firstlineno,*/
6560 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6564 Py_XDECREF(py_srcfile);
6565 Py_XDECREF(py_funcname);
6570 #endif /* CYTHON_PROFILE */
6572 'EMPTY_TUPLE' : Naming.empty_tuple,
6573 'EMPTY_BYTES' : Naming.empty_bytes,
6574 "MODULE": Naming.module_cname,