3 # Pyrex - Parse tree nodes
8 cython.declare(sys=object, os=object, time=object, copy=object,
9 Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10 py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11 StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12 CppClassScope=object, UtilityCode=object, EncodedString=object,
13 absolute_path_length=cython.Py_ssize_t)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
32 absolute_path_length = 0
34 def relative_position(pos):
36 We embed the relative filename in the generated C file, since we
37 don't want to have to regnerate and compile all the source code
38 whenever the Python install directory moves (which could happen,
39 e.g,. when distributing binaries.)
42 a position tuple -- (absolute filename, line number column position)
50 global absolute_path_length
51 if absolute_path_length==0:
52 absolute_path_length = len(os.path.abspath(os.getcwd()))
53 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
63 # make sure we can encode the filename in the docstring encoding
64 # otherwise make the docstring a unicode string
65 encoding = docstring.encoding
66 if encoding is not None:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
86 if len(args) > 1 and isinstance(args[1], CCodeWriter):
87 # here we annotate the code with this function call
88 # but only if new code is generated
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
111 class VerboseCodeWriter(type):
112 # Set this as a metaclass to trace function calls in code.
113 # This slows down code generation and makes much larger files.
114 def __new__(cls, name, bases, attrs):
116 for mname, m in attrs.items():
117 if isinstance(m, FunctionType):
118 attrs[mname] = write_func_call(m)
119 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
134 # All descandants should set child_attrs to a list of the attributes
135 # containing nodes considered "children" in the tree. Each such attribute
136 # can either contain a single node or a list of nodes. See Visitor.py.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
159 def clone_node(self):
160 """Clone the node. This is defined as a shallow copy, except for member lists
161 amongst the child attributes (from get_child_accessors) which are also
162 copied. Lists containing child nodes are thus seen as a way for the node
163 to hold multiple children directly; the list is not treated as a seperate
164 level in the tree."""
165 result = copy.copy(self)
166 for attrname in result.child_attrs:
167 value = getattr(result, attrname)
168 if isinstance(value, list):
169 setattr(result, attrname, [x for x in value])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
181 # (1) analyse_declarations
182 # Make symbol table entries for all declarations at the current
183 # level, both explicit (def, cdef, etc.) and implicit (assignment
184 # to an otherwise undeclared name).
186 # (2) analyse_expressions
187 # Determine the result types of expressions and fill in the
188 # 'type' attribute of each ExprNode. Insert coercion nodes into the
189 # tree where needed to convert to and from Python objects.
190 # Allocate temporary locals for intermediate results. Fill
191 # in the 'result_code' attribute of each ExprNode with a C code
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
249 def dump_child(x, level):
250 if isinstance(x, Node):
251 return x.dump(level, filter_out, cutoff-1, encountered)
252 elif isinstance(x, list):
253 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
263 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264 for key, value in attrs:
265 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
266 res += "%s>" % indent
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
296 def generate_function_definitions(self, env, code):
297 env_old = env.directives
298 code_old = code.globalstate.directives
299 code.globalstate.directives = self.directives
300 self.body.generate_function_definitions(env, code)
301 env.directives = env_old
302 code.globalstate.directives = code_old
304 def generate_execution_code(self, code):
305 old = code.globalstate.directives
306 code.globalstate.directives = self.directives
307 self.body.generate_execution_code(code)
308 code.globalstate.directives = old
310 def annotate(self, code):
311 old = code.globalstate.directives
312 code.globalstate.directives = self.directives
313 self.body.annotate(code)
314 code.globalstate.directives = old
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
319 def generate_cached_builtins_decls(self, env, code):
320 entries = env.global_scope().undeclared_cached_builtins
321 for entry in entries:
322 code.globalstate.add_cached_builtin_decl(entry)
325 def generate_lambda_definitions(self, env, code):
326 for node in env.lambda_defs:
327 node.generate_function_definitions(env, code)
329 class StatListNode(Node):
330 # stats a list of StatNode
332 child_attrs = ["stats"]
334 def create_analysed(pos, env, *args, **kw):
335 node = StatListNode(pos, *args, **kw)
336 return node # No node-specific analysis necesarry
337 create_analysed = staticmethod(create_analysed)
339 def analyse_control_flow(self, env):
340 for stat in self.stats:
341 stat.analyse_control_flow(env)
343 def analyse_declarations(self, env):
344 #print "StatListNode.analyse_declarations" ###
345 for stat in self.stats:
346 stat.analyse_declarations(env)
348 def analyse_expressions(self, env):
349 #print "StatListNode.analyse_expressions" ###
350 for stat in self.stats:
351 stat.analyse_expressions(env)
353 def generate_function_definitions(self, env, code):
354 #print "StatListNode.generate_function_definitions" ###
355 for stat in self.stats:
356 stat.generate_function_definitions(env, code)
358 def generate_execution_code(self, code):
359 #print "StatListNode.generate_execution_code" ###
360 for stat in self.stats:
361 code.mark_pos(stat.pos)
362 stat.generate_execution_code(code)
364 def annotate(self, code):
365 for stat in self.stats:
369 class StatNode(Node):
371 # Code generation for statements is split into the following subphases:
373 # (1) generate_function_definitions
374 # Emit C code for the definitions of any structs,
375 # unions, enums and functions defined in the current
378 # (2) generate_execution_code
379 # Emit C code for executable statements.
382 def generate_function_definitions(self, env, code):
385 def generate_execution_code(self, code):
386 raise InternalError("generate_execution_code not implemented for %s" % \
387 self.__class__.__name__)
390 class CDefExternNode(StatNode):
391 # include_file string or None
394 child_attrs = ["body"]
396 def analyse_declarations(self, env):
397 if self.include_file:
398 env.add_include_file(self.include_file)
399 old_cinclude_flag = env.in_cinclude
401 self.body.analyse_declarations(env)
402 env.in_cinclude = old_cinclude_flag
404 def analyse_expressions(self, env):
407 def generate_execution_code(self, code):
410 def annotate(self, code):
411 self.body.annotate(code)
414 class CDeclaratorNode(Node):
415 # Part of a C declaration.
417 # Processing during analyse_declarations phase:
420 # Returns (name, type) pair where name is the
421 # CNameDeclaratorNode of the name being declared
422 # and type is the type it is being declared as.
424 # calling_convention string Calling convention of CFuncDeclaratorNode
425 # for which this is a base
429 calling_convention = ""
432 class CNameDeclaratorNode(CDeclaratorNode):
433 # name string The Pyrex name being declared
434 # cname string or None C name, if specified
435 # default ExprNode or None the value assigned on declaration
437 child_attrs = ['default']
441 def analyse(self, base_type, env, nonempty = 0):
442 if nonempty and self.name == '':
443 # May have mistaken the name for the type.
444 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
445 error(self.pos, "Missing argument name")
446 elif base_type.is_void:
447 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
449 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
450 base_type = py_object_type
451 self.type = base_type
452 return self, base_type
454 class CPtrDeclaratorNode(CDeclaratorNode):
455 # base CDeclaratorNode
457 child_attrs = ["base"]
459 def analyse(self, base_type, env, nonempty = 0):
460 if base_type.is_pyobject:
462 "Pointer base type cannot be a Python object")
463 ptr_type = PyrexTypes.c_ptr_type(base_type)
464 return self.base.analyse(ptr_type, env, nonempty = nonempty)
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Reference base type cannot be a Python object")
475 ref_type = PyrexTypes.c_ref_type(base_type)
476 return self.base.analyse(ref_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
485 if base_type.is_cpp_class:
486 from ExprNodes import TupleNode
487 if isinstance(self.dimension, TupleNode):
488 args = self.dimension.args
490 args = self.dimension,
491 values = [v.analyse_as_type(env) for v in args]
493 ix = values.index(None)
494 error(args[ix].pos, "Template parameter not a type.")
496 base_type = base_type.specialize_here(self.pos, values)
497 return self.base.analyse(base_type, env, nonempty = nonempty)
499 self.dimension.analyse_const_expression(env)
500 if not self.dimension.type.is_int:
501 error(self.dimension.pos, "Array dimension not integer")
502 size = self.dimension.get_constant_c_result_code()
511 if not base_type.is_complete():
513 "Array element type '%s' is incomplete" % base_type)
514 if base_type.is_pyobject:
516 "Array element cannot be a Python object")
517 if base_type.is_cfunction:
519 "Array element cannot be a function")
520 array_type = PyrexTypes.c_array_type(base_type, size)
521 return self.base.analyse(array_type, env, nonempty = nonempty)
524 class CFuncDeclaratorNode(CDeclaratorNode):
525 # base CDeclaratorNode
526 # args [CArgDeclNode]
527 # has_varargs boolean
528 # exception_value ConstNode
529 # exception_check boolean True if PyErr_Occurred check needed
530 # nogil boolean Can be called without gil
531 # with_gil boolean Acquire gil around function body
533 child_attrs = ["base", "args", "exception_value"]
536 optional_arg_count = 0
538 def analyse(self, return_type, env, nonempty = 0):
542 for i, arg_node in enumerate(self.args):
543 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544 is_self_arg = (i == 0 and env.is_c_class_scope))
545 name = name_declarator.name
546 if name_declarator.cname:
548 "Function argument cannot have C name specification")
549 # Turn *[] argument into **
551 type = PyrexTypes.c_ptr_type(type.base_type)
552 # Catch attempted C-style func(void) decl
554 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
555 func_type_args.append(
556 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
558 self.optional_arg_count += 1
559 elif self.optional_arg_count:
560 error(self.pos, "Non-default argument follows default argument")
562 if self.optional_arg_count:
563 scope = StructOrUnionScope()
564 arg_count_member = '%sn' % Naming.pyrex_prefix
565 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
566 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
567 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
568 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
569 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
574 cname = struct_cname)
575 self.op_args_struct.defined_in_pxd = 1
576 self.op_args_struct.used = 1
580 if self.exception_check == '+':
581 env.add_include_file('stdexcept')
582 if return_type.is_pyobject \
583 and (self.exception_value or self.exception_check) \
584 and self.exception_check != '+':
586 "Exception clause not allowed for function returning Python object")
588 if self.exception_value:
589 self.exception_value.analyse_const_expression(env)
590 if self.exception_check == '+':
591 self.exception_value.analyse_types(env)
592 exc_val_type = self.exception_value.type
593 if not exc_val_type.is_error and \
594 not exc_val_type.is_pyobject and \
595 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
596 error(self.exception_value.pos,
597 "Exception value must be a Python exception or cdef function with no arguments.")
598 exc_val = self.exception_value
600 self.exception_value = self.exception_value.coerce_to(return_type, env)
601 if self.exception_value.analyse_const_expression(env):
602 exc_val = self.exception_value.get_constant_c_result_code()
604 raise InternalError("get_constant_c_result_code not implemented for %s" %
605 self.exception_value.__class__.__name__)
606 if not return_type.assignable_from(self.exception_value.type):
607 error(self.exception_value.pos,
608 "Exception value incompatible with function return type")
609 exc_check = self.exception_check
610 if return_type.is_array:
612 "Function cannot return an array")
613 if return_type.is_cfunction:
615 "Function cannot return a function")
616 func_type = PyrexTypes.CFuncType(
617 return_type, func_type_args, self.has_varargs,
618 optional_arg_count = self.optional_arg_count,
619 exception_value = exc_val, exception_check = exc_check,
620 calling_convention = self.base.calling_convention,
621 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
622 if self.optional_arg_count:
623 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
624 callspec = env.directives['callspec']
626 current = func_type.calling_convention
627 if current and current != callspec:
628 error(self.pos, "cannot have both '%s' and '%s' "
629 "calling conventions" % (current, callspec))
630 func_type.calling_convention = callspec
631 return self.base.analyse(func_type, env)
634 class CArgDeclNode(Node):
635 # Item in a function declaration argument list.
637 # base_type CBaseTypeNode
638 # declarator CDeclaratorNode
639 # not_none boolean Tagged with 'not None'
640 # or_none boolean Tagged with 'or None'
641 # accept_none boolean Resolved boolean for not_none/or_none
642 # default ExprNode or None
643 # default_value PyObjectConst constant for default value
644 # annotation ExprNode or None Py3 function arg annotation
645 # is_self_arg boolean Is the "self" arg of an extension type method
646 # is_type_arg boolean Is the "class" arg of an extension type classmethod
647 # is_kw_only boolean Is a keyword-only argument
649 child_attrs = ["base_type", "declarator", "default"]
655 name_declarator = None
659 def analyse(self, env, nonempty = 0, is_self_arg = False):
661 self.base_type.is_self_arg = self.is_self_arg = True
662 if self.type is None:
663 # The parser may missinterpret names as types...
665 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
667 self.declarator.name = self.base_type.name
668 self.base_type.name = None
669 self.base_type.is_basic_c_type = False
672 could_be_name = False
673 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
674 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
675 self.declarator.name = self.base_type.arg_name
676 # The parser is unable to resolve the ambiguity of [] as part of the
677 # type (e.g. in buffers) or empty declarator (as with arrays).
678 # This is only arises for empty multi-dimensional arrays.
679 if (base_type.is_array
680 and isinstance(self.base_type, TemplatedTypeNode)
681 and isinstance(self.declarator, CArrayDeclaratorNode)):
682 declarator = self.declarator
683 while isinstance(declarator.base, CArrayDeclaratorNode):
684 declarator = declarator.base
685 declarator.base = self.base_type.array_declarator
686 base_type = base_type.base_type
687 return self.declarator.analyse(base_type, env, nonempty = nonempty)
689 return self.name_declarator, self.type
691 def calculate_default_value_code(self, code):
692 if self.default_value is None:
694 if self.default.is_literal:
695 # will not output any code, just assign the result_code
696 self.default.generate_evaluation_code(code)
697 return self.type.cast_code(self.default.result())
698 self.default_value = code.get_argument_default_const(self.type)
699 return self.default_value
701 def annotate(self, code):
703 self.default.annotate(code)
706 class CBaseTypeNode(Node):
707 # Abstract base class for C base type nodes.
709 # Processing during analyse_declarations phase:
716 def analyse_as_type(self, env):
717 return self.analyse(env)
719 class CAnalysedBaseTypeNode(Node):
724 def analyse(self, env, could_be_name = False):
727 class CSimpleBaseTypeNode(CBaseTypeNode):
729 # module_path [string] Qualifying name components
730 # is_basic_c_type boolean
734 # is_self_arg boolean Is self argument of C method
735 # ##is_type_arg boolean Is type argument of class method
738 arg_name = None # in case the argument name was interpreted as a type
740 def analyse(self, env, could_be_name = False):
741 # Return type descriptor.
742 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
744 if self.is_basic_c_type:
745 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
747 error(self.pos, "Unrecognised type modifier combination")
748 elif self.name == "object" and not self.module_path:
749 type = py_object_type
750 elif self.name is None:
751 if self.is_self_arg and env.is_c_class_scope:
752 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
753 type = env.parent_type
754 ## elif self.is_type_arg and env.is_c_class_scope:
755 ## type = Builtin.type_type
757 type = py_object_type
760 scope = env.find_imported_module(self.module_path, self.pos)
764 if scope.is_c_class_scope:
765 scope = scope.global_scope()
766 entry = scope.lookup(self.name)
767 if entry and entry.is_type:
770 if self.is_self_arg and env.is_c_class_scope:
771 type = env.parent_type
772 ## elif self.is_type_arg and env.is_c_class_scope:
773 ## type = Builtin.type_type
775 type = py_object_type
776 self.arg_name = self.name
779 if not self.name in self.templates:
780 error(self.pos, "'%s' is not a type identifier" % self.name)
781 type = PyrexTypes.TemplatePlaceholderType(self.name)
783 error(self.pos, "'%s' is not a type identifier" % self.name)
785 if not type.is_numeric or type.is_complex:
786 error(self.pos, "can only complexify c numeric types")
787 type = PyrexTypes.CComplexType(type)
788 type.create_declaration_utility_code(env)
789 elif type is Builtin.complex_type:
790 # Special case: optimise builtin complex type into C's
791 # double complex. The parser cannot do this (as for the
792 # normal scalar types) as the user may have redeclared the
793 # 'complex' type. Testing for the exact type here works.
794 type = PyrexTypes.c_double_complex_type
795 type.create_declaration_utility_code(env)
800 return PyrexTypes.error_type
802 class CNestedBaseTypeNode(CBaseTypeNode):
803 # For C++ classes that live inside other C++ classes.
806 # base_type CBaseTypeNode
808 child_attrs = ['base_type']
810 def analyse(self, env, could_be_name = None):
811 base_type = self.base_type.analyse(env)
812 if base_type is PyrexTypes.error_type:
813 return PyrexTypes.error_type
814 if not base_type.is_cpp_class:
815 error(self.pos, "'%s' is not a valid type scope" % base_type)
816 return PyrexTypes.error_type
817 type_entry = base_type.scope.lookup_here(self.name)
818 if not type_entry or not type_entry.is_type:
819 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
820 return PyrexTypes.error_type
821 return type_entry.type
823 class TemplatedTypeNode(CBaseTypeNode):
825 # positional_args [ExprNode] List of positional arguments
826 # keyword_args DictNode Keyword arguments
827 # base_type_node CBaseTypeNode
830 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
833 child_attrs = ["base_type_node", "positional_args",
834 "keyword_args", "dtype_node"]
840 def analyse(self, env, could_be_name = False, base_type = None):
841 if base_type is None:
842 base_type = self.base_type_node.analyse(env)
843 if base_type.is_error: return base_type
845 if base_type.is_cpp_class:
847 if self.keyword_args and self.keyword_args.key_value_pairs:
848 error(self.pos, "c++ templates cannot take keyword arguments");
849 self.type = PyrexTypes.error_type
852 for template_node in self.positional_args:
853 type = template_node.analyse_as_type(env)
855 error(template_node.pos, "unknown type in template argument")
857 template_types.append(type)
858 self.type = base_type.specialize_here(self.pos, template_types)
860 elif base_type.is_pyobject:
864 options = Buffer.analyse_buffer_options(
867 self.positional_args,
869 base_type.buffer_defaults)
871 if sys.version_info[0] < 3:
872 # Py 2.x enforces byte strings as keyword arguments ...
873 options = dict([ (name.encode('ASCII'), value)
874 for name, value in options.items() ])
876 self.type = PyrexTypes.BufferType(base_type, **options)
880 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
881 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
882 error(self.pos, "invalid array declaration")
883 self.type = PyrexTypes.error_type
885 # It would be nice to merge this class with CArrayDeclaratorNode,
886 # but arrays are part of the declaration, not the type...
887 if not self.positional_args:
890 dimension = self.positional_args[0]
891 self.array_declarator = CArrayDeclaratorNode(self.pos,
892 base = empty_declarator,
893 dimension = dimension)
894 self.type = self.array_declarator.analyse(base_type, env)[1]
898 class CComplexBaseTypeNode(CBaseTypeNode):
899 # base_type CBaseTypeNode
900 # declarator CDeclaratorNode
902 child_attrs = ["base_type", "declarator"]
904 def analyse(self, env, could_be_name = False):
905 base = self.base_type.analyse(env, could_be_name)
906 _, type = self.declarator.analyse(base, env)
910 class CVarDefNode(StatNode):
911 # C variable definition or forward/extern function declaration.
913 # visibility 'private' or 'public' or 'extern'
914 # base_type CBaseTypeNode
915 # declarators [CDeclaratorNode]
919 # decorators [cython.locals(...)] or None
920 # directive_locals { string : NameNode } locals defined by cython.locals(...)
922 child_attrs = ["base_type", "declarators"]
925 directive_locals = {}
927 def analyse_declarations(self, env, dest_scope = None):
930 self.dest_scope = dest_scope
931 base_type = self.base_type.analyse(env)
933 # If the field is an external typedef, we cannot be sure about the type,
934 # so do conversion ourself rather than rely on the CPython mechanism (through
935 # a property; made in AnalyseDeclarationsTransform).
936 if (dest_scope.is_c_class_scope
937 and self.visibility in ('public', 'readonly')):
940 need_property = False
941 visibility = self.visibility
943 for declarator in self.declarators:
944 name_declarator, type = declarator.analyse(base_type, env)
945 if not type.is_complete():
946 if not (self.visibility == 'extern' and type.is_array):
947 error(declarator.pos,
948 "Variable type '%s' is incomplete" % type)
949 if self.visibility == 'extern' and type.is_pyobject:
950 error(declarator.pos,
951 "Python object cannot be declared extern")
952 name = name_declarator.name
953 cname = name_declarator.cname
955 error(declarator.pos, "Missing name in declaration.")
957 if type.is_cfunction:
958 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
959 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
961 if entry is not None:
962 entry.directive_locals = self.directive_locals
964 if self.directive_locals:
965 error(self.pos, "Decorators can only be followed by functions")
966 if self.in_pxd and self.visibility != 'extern':
968 "Only 'extern' C variable declaration allowed in .pxd file")
969 entry = dest_scope.declare_var(name, type, declarator.pos,
970 cname = cname, visibility = visibility, is_cdef = 1)
971 entry.needs_property = need_property
974 class CStructOrUnionDefNode(StatNode):
976 # cname string or None
977 # kind "struct" or "union"
978 # typedef_flag boolean
979 # visibility "public" or "private"
981 # attributes [CVarDefNode] or None
985 child_attrs = ["attributes"]
987 def analyse_declarations(self, env):
989 if self.visibility == 'extern' and self.packed:
990 error(self.pos, "Cannot declare extern struct as 'packed'")
991 if self.attributes is not None:
992 scope = StructOrUnionScope(self.name)
993 self.entry = env.declare_struct_or_union(
994 self.name, self.kind, scope, self.typedef_flag, self.pos,
995 self.cname, visibility = self.visibility, packed = self.packed)
996 if self.attributes is not None:
997 if self.in_pxd and not env.in_cinclude:
998 self.entry.defined_in_pxd = 1
999 for attr in self.attributes:
1000 attr.analyse_declarations(env, scope)
1001 if self.visibility != 'extern':
1002 need_typedef_indirection = False
1003 for attr in scope.var_entries:
1005 while type.is_array:
1006 type = type.base_type
1007 if type == self.entry.type:
1008 error(attr.pos, "Struct cannot contain itself as a member.")
1009 if self.typedef_flag:
1011 type = type.base_type
1012 if type == self.entry.type:
1013 need_typedef_indirection = True
1014 if need_typedef_indirection:
1015 # C can't handle typedef structs that refer to themselves.
1016 struct_entry = self.entry
1017 self.entry = env.declare_typedef(
1018 self.name, struct_entry.type, self.pos,
1019 cname = self.cname, visibility='ignore')
1020 struct_entry.type.typedef_flag = False
1021 # FIXME: this might be considered a hack ;-)
1022 struct_entry.cname = struct_entry.type.cname = \
1023 '_' + self.entry.type.typedef_cname
1025 def analyse_expressions(self, env):
1028 def generate_execution_code(self, code):
1032 class CppClassNode(CStructOrUnionDefNode):
1035 # cname string or None
1036 # visibility "extern"
1038 # attributes [CVarDefNode] or None
1040 # base_classes [string]
1041 # templates [string] or None
1043 def analyse_declarations(self, env):
1045 if self.attributes is not None:
1046 scope = CppClassScope(self.name, env)
1047 base_class_types = []
1048 for base_class_name in self.base_classes:
1049 base_class_entry = env.lookup(base_class_name)
1050 if base_class_entry is None:
1051 error(self.pos, "'%s' not found" % base_class_name)
1052 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1053 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1055 base_class_types.append(base_class_entry.type)
1056 if self.templates is None:
1057 template_types = None
1059 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1060 self.entry = env.declare_cpp_class(
1061 self.name, scope, self.pos,
1062 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1063 self.entry.is_cpp_class = 1
1064 if self.attributes is not None:
1065 if self.in_pxd and not env.in_cinclude:
1066 self.entry.defined_in_pxd = 1
1067 for attr in self.attributes:
1068 attr.analyse_declarations(scope)
1070 class CEnumDefNode(StatNode):
1071 # name string or None
1072 # cname string or None
1073 # items [CEnumDefItemNode]
1074 # typedef_flag boolean
1075 # visibility "public" or "private"
1079 child_attrs = ["items"]
1081 def analyse_declarations(self, env):
1082 self.entry = env.declare_enum(self.name, self.pos,
1083 cname = self.cname, typedef_flag = self.typedef_flag,
1084 visibility = self.visibility)
1085 if self.items is not None:
1086 if self.in_pxd and not env.in_cinclude:
1087 self.entry.defined_in_pxd = 1
1088 for item in self.items:
1089 item.analyse_declarations(env, self.entry)
1091 def analyse_expressions(self, env):
1094 def generate_execution_code(self, code):
1095 if self.visibility == 'public':
1096 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1097 for item in self.entry.enum_values:
1098 code.putln("%s = PyInt_FromLong(%s); %s" % (
1101 code.error_goto_if_null(temp, item.pos)))
1102 code.put_gotref(temp)
1103 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1104 Naming.module_cname,
1107 code.error_goto(item.pos)))
1108 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1109 code.funcstate.release_temp(temp)
1112 class CEnumDefItemNode(StatNode):
1114 # cname string or None
1115 # value ExprNode or None
1117 child_attrs = ["value"]
1119 def analyse_declarations(self, env, enum_entry):
1121 self.value.analyse_const_expression(env)
1122 if not self.value.type.is_int:
1123 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1124 self.value.analyse_const_expression(env)
1125 entry = env.declare_const(self.name, enum_entry.type,
1126 self.value, self.pos, cname = self.cname,
1127 visibility = enum_entry.visibility)
1128 enum_entry.enum_values.append(entry)
1131 class CTypeDefNode(StatNode):
1132 # base_type CBaseTypeNode
1133 # declarator CDeclaratorNode
1134 # visibility "public" or "private"
1137 child_attrs = ["base_type", "declarator"]
1139 def analyse_declarations(self, env):
1140 base = self.base_type.analyse(env)
1141 name_declarator, type = self.declarator.analyse(base, env)
1142 name = name_declarator.name
1143 cname = name_declarator.cname
1144 entry = env.declare_typedef(name, type, self.pos,
1145 cname = cname, visibility = self.visibility)
1146 if self.in_pxd and not env.in_cinclude:
1147 entry.defined_in_pxd = 1
1149 def analyse_expressions(self, env):
1151 def generate_execution_code(self, code):
1155 class FuncDefNode(StatNode, BlockNode):
1156 # Base class for function definition nodes.
1158 # return_type PyrexType
1159 # #filename string C name of filename string const
1160 # entry Symtab.Entry
1161 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1162 # needs_outer_scope boolean Whether or not this function requires outer scope
1163 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1167 needs_closure = False
1168 needs_outer_scope = False
1171 def analyse_default_values(self, env):
1172 genv = env.global_scope()
1174 for arg in self.args:
1178 arg.default.analyse_types(env)
1179 arg.default = arg.default.coerce_to(arg.type, genv)
1182 "This argument cannot have a default value")
1187 error(arg.pos, "Non-default argument following default argument")
1189 def need_gil_acquisition(self, lenv):
1192 def create_local_scope(self, env):
1194 while genv.is_py_class_scope or genv.is_c_class_scope:
1195 genv = genv.outer_scope
1196 if self.needs_closure:
1197 lenv = ClosureScope(name=self.entry.name,
1199 scope_name=self.entry.cname)
1201 lenv = LocalScope(name=self.entry.name,
1204 lenv.return_type = self.return_type
1205 type = self.entry.type
1206 if type.is_cfunction:
1207 lenv.nogil = type.nogil and not type.with_gil
1208 self.local_scope = lenv
1209 lenv.directives = env.directives
1212 def generate_function_definitions(self, env, code):
1215 lenv = self.local_scope
1216 if lenv.is_closure_scope and not lenv.is_passthrough:
1217 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1218 Naming.outer_scope_cname)
1220 outer_scope_cname = Naming.outer_scope_cname
1221 lenv.mangle_closure_cnames(outer_scope_cname)
1222 # Generate closure function definitions
1223 self.body.generate_function_definitions(lenv, code)
1224 # generate lambda function definitions
1225 self.generate_lambda_definitions(lenv, code)
1227 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1228 self.entry.scope.is_c_class_scope)
1229 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1230 self.entry.scope.is_c_class_scope)
1231 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1233 if 'cython_unused' not in self.modifiers:
1234 self.modifiers = self.modifiers + ['cython_unused']
1236 preprocessor_guard = None
1237 if self.entry.is_special and not is_buffer_slot:
1238 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1240 preprocessor_guard = slot.preprocessor_guard_code()
1241 if (self.entry.name == '__long__' and
1242 not self.entry.scope.lookup_here('__int__')):
1243 preprocessor_guard = None
1245 profile = code.globalstate.directives['profile']
1248 error(self.pos, "Cannot profile nogil function.")
1249 code.globalstate.use_utility_code(profile_utility_code)
1251 # Generate C code for header and body of function
1252 code.enter_cfunc_scope()
1253 code.return_from_error_cleanup_label = code.new_label()
1255 # ----- Top-level constants used by this function
1256 code.mark_pos(self.pos)
1257 self.generate_cached_builtins_decls(lenv, code)
1258 # ----- Function header
1261 if preprocessor_guard:
1262 code.putln(preprocessor_guard)
1264 with_pymethdef = self.needs_assignment_synthesis(env, code)
1266 self.py_func.generate_function_header(code,
1267 with_pymethdef = with_pymethdef,
1269 self.generate_function_header(code,
1270 with_pymethdef = with_pymethdef)
1271 # ----- Local variable declarations
1272 # Find function scope
1274 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1275 cenv = cenv.outer_scope
1276 if self.needs_closure:
1277 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1279 elif self.needs_outer_scope:
1280 if lenv.is_passthrough:
1281 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1283 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1285 self.generate_argument_declarations(lenv, code)
1286 for entry in lenv.var_entries:
1287 if not entry.in_closure:
1288 code.put_var_declaration(entry)
1290 if not self.return_type.is_void:
1291 if self.return_type.is_pyobject:
1295 (self.return_type.declaration_code(Naming.retval_cname),
1297 tempvardecl_code = code.insertion_point()
1298 self.generate_keyword_list(code)
1300 code.put_trace_declarations()
1301 # ----- Extern library function declarations
1302 lenv.generate_library_function_declarations(code)
1303 # ----- GIL acquisition
1304 acquire_gil = self.acquire_gil
1306 env.use_utility_code(force_init_threads_utility_code)
1307 code.putln("#ifdef WITH_THREAD")
1308 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1309 code.putln("#endif")
1310 # ----- set up refnanny
1312 code.put_setup_refcount_context(self.entry.name)
1313 # ----- Automatic lead-ins for certain special functions
1314 if is_getbuffer_slot:
1315 self.getbuffer_init(code)
1316 # ----- Create closure scope object
1317 if self.needs_closure:
1318 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1319 Naming.cur_scope_cname,
1320 lenv.scope_class.type.declaration_code(''),
1321 lenv.scope_class.type.typeptr_cname,
1322 lenv.scope_class.type.typeptr_cname,
1323 Naming.empty_tuple))
1324 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1325 if is_getbuffer_slot:
1326 self.getbuffer_error_cleanup(code)
1328 code.put_finish_refcount_context()
1329 # FIXME: what if the error return value is a Python value?
1330 code.putln("return %s;" % self.error_value())
1332 code.put_gotref(Naming.cur_scope_cname)
1333 # Note that it is unsafe to decref the scope at this point.
1334 if self.needs_outer_scope:
1335 code.putln("%s = (%s)%s;" % (
1337 cenv.scope_class.type.declaration_code(''),
1339 if lenv.is_passthrough:
1340 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1341 elif self.needs_closure:
1342 # inner closures own a reference to their outer parent
1343 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1344 code.put_giveref(outer_scope_cname)
1345 # ----- Trace function call
1347 # this looks a bit late, but if we don't get here due to a
1348 # fatal error before hand, it's not really worth tracing
1349 code.put_trace_call(self.entry.name, self.pos)
1350 # ----- Fetch arguments
1351 self.generate_argument_parsing_code(env, code)
1352 # If an argument is assigned to in the body, we must
1353 # incref it to properly keep track of refcounts.
1354 for entry in lenv.arg_entries:
1355 if entry.type.is_pyobject:
1356 if (acquire_gil or entry.assignments) and not entry.in_closure:
1357 code.put_var_incref(entry)
1358 # ----- Initialise local variables
1359 for entry in lenv.var_entries:
1360 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1361 code.put_init_var_to_py_none(entry)
1362 # ----- Initialise local buffer auxiliary variables
1363 for entry in lenv.var_entries + lenv.arg_entries:
1364 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1365 code.putln("%s.buf = NULL;" %
1366 entry.buffer_aux.buffer_info_var.cname)
1367 # ----- Check and convert arguments
1368 self.generate_argument_type_tests(code)
1369 # ----- Acquire buffer arguments
1370 for entry in lenv.arg_entries:
1371 if entry.type.is_buffer:
1372 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1374 # -------------------------
1375 # ----- Function body -----
1376 # -------------------------
1377 self.body.generate_execution_code(code)
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 acquire_gil or entry.assignments:
1467 code.put_var_decref(entry)
1468 if self.needs_closure:
1469 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1472 # This code is duplicated in ModuleNode.generate_module_init_func
1474 default_retval = self.return_type.default_value
1475 err_val = self.error_value()
1476 if err_val is None and default_retval:
1477 err_val = default_retval
1478 if self.return_type.is_pyobject:
1479 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1481 if self.entry.is_special and self.entry.name == "__hash__":
1482 # Returning -1 for __hash__ is supposed to signal an error
1483 # We do as Python instances and coerce -1 into -2.
1484 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1485 Naming.retval_cname, Naming.retval_cname))
1488 if self.return_type.is_pyobject:
1489 code.put_trace_return(Naming.retval_cname)
1491 code.put_trace_return("Py_None")
1493 code.put_finish_refcount_context()
1496 code.putln("#ifdef WITH_THREAD")
1497 code.putln("PyGILState_Release(_save);")
1498 code.putln("#endif")
1500 if not self.return_type.is_void:
1501 code.putln("return %s;" % Naming.retval_cname)
1505 if preprocessor_guard:
1506 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1508 # ----- Go back and insert temp variable declarations
1509 tempvardecl_code.put_temp_declarations(code.funcstate)
1510 # ----- Python version
1511 code.exit_cfunc_scope()
1513 self.py_func.generate_function_definitions(env, code)
1514 self.generate_wrapper_functions(code)
1516 def declare_argument(self, env, arg):
1517 if arg.type.is_void:
1518 error(arg.pos, "Invalid use of 'void'")
1519 elif not arg.type.is_complete() and not arg.type.is_array:
1521 "Argument type '%s' is incomplete" % arg.type)
1522 return env.declare_arg(arg.name, arg.type, arg.pos)
1524 def generate_arg_type_test(self, arg, code):
1525 # Generate type test for one argument.
1526 if arg.type.typeobj_is_available():
1527 code.globalstate.use_utility_code(arg_type_test_utility_code)
1528 typeptr_cname = arg.type.typeptr_cname
1529 arg_code = "((PyObject *)%s)" % arg.entry.cname
1531 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1536 arg.type.is_builtin_type,
1537 code.error_goto(arg.pos)))
1539 error(arg.pos, "Cannot test type of extern C class "
1540 "without type object name specification")
1542 def generate_arg_none_check(self, arg, code):
1543 # Generate None check for one argument.
1544 code.globalstate.use_utility_code(arg_type_test_utility_code)
1545 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1546 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1548 code.error_goto(arg.pos)))
1551 def generate_wrapper_functions(self, code):
1554 def generate_execution_code(self, code):
1555 # Evaluate and store argument default values
1556 for arg in self.args:
1557 default = arg.default
1559 if not default.is_literal:
1560 default.generate_evaluation_code(code)
1561 default.make_owned_reference(code)
1562 result = default.result_as(arg.type)
1565 arg.calculate_default_value_code(code),
1567 if arg.type.is_pyobject:
1568 code.put_giveref(default.result())
1569 default.generate_post_assignment_code(code)
1570 default.free_temps(code)
1571 # For Python class methods, create and store function object
1573 self.assmt.generate_execution_code(code)
1576 # Special code for the __getbuffer__ function
1578 def getbuffer_init(self, code):
1579 info = self.local_scope.arg_entries[1].cname
1580 # Python 3.0 betas have a bug in memoryview which makes it call
1581 # getbuffer with a NULL parameter. For now we work around this;
1582 # the following line should be removed when this bug is fixed.
1583 code.putln("if (%s == NULL) return 0;" % info)
1584 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1585 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1587 def getbuffer_error_cleanup(self, code):
1588 info = self.local_scope.arg_entries[1].cname
1589 code.put_gotref("%s->obj" % info)
1590 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1593 def getbuffer_normal_cleanup(self, code):
1594 info = self.local_scope.arg_entries[1].cname
1595 code.putln("if (%s->obj == Py_None) {" % info)
1596 code.put_gotref("Py_None")
1597 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1600 class CFuncDefNode(FuncDefNode):
1601 # C function definition.
1603 # modifiers ['inline']
1604 # visibility 'private' or 'public' or 'extern'
1605 # base_type CBaseTypeNode
1606 # declarator CDeclaratorNode
1609 # decorators [DecoratorNode] list of decorators
1611 # with_gil boolean Acquire GIL around body
1613 # py_func wrapper for calling from Python
1614 # overridable whether or not this is a cpdef function
1615 # inline_in_pxd whether this is an inline function in a pxd file
1617 child_attrs = ["base_type", "declarator", "body", "py_func"]
1619 inline_in_pxd = False
1621 directive_locals = {}
1623 def unqualified_name(self):
1624 return self.entry.name
1626 def analyse_declarations(self, env):
1627 self.directive_locals.update(env.directives['locals'])
1628 base_type = self.base_type.analyse(env)
1629 # The 2 here is because we need both function and argument names.
1630 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1631 if not type.is_cfunction:
1633 "Suite attached to non-function declaration")
1634 # Remember the actual type according to the function header
1635 # written here, because the type in the symbol table entry
1636 # may be different if we're overriding a C method inherited
1637 # from the base type of an extension type.
1639 type.is_overridable = self.overridable
1640 declarator = self.declarator
1641 while not hasattr(declarator, 'args'):
1642 declarator = declarator.base
1643 self.args = declarator.args
1644 for formal_arg, type_arg in zip(self.args, type.args):
1645 formal_arg.type = type_arg.type
1646 formal_arg.name = type_arg.name
1647 formal_arg.cname = type_arg.cname
1648 name = name_declarator.name
1649 cname = name_declarator.cname
1650 self.entry = env.declare_cfunction(
1651 name, type, self.pos,
1652 cname = cname, visibility = self.visibility,
1653 defining = self.body is not None,
1654 api = self.api, modifiers = self.modifiers)
1655 self.entry.inline_func_in_pxd = self.inline_in_pxd
1656 self.return_type = type.return_type
1658 if self.overridable and not env.is_module_scope:
1659 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1660 # An error will be produced in the cdef function
1661 self.overridable = False
1663 if self.overridable:
1665 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1666 self.py_func = DefNode(pos = self.pos,
1667 name = self.entry.name,
1670 starstar_arg = None,
1672 body = py_func_body,
1674 self.py_func.is_module_scope = env.is_module_scope
1675 self.py_func.analyse_declarations(env)
1676 self.entry.as_variable = self.py_func.entry
1677 # Reset scope entry the above cfunction
1678 env.entries[name] = self.entry
1679 if not env.is_module_scope or Options.lookup_module_cpdef:
1680 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1681 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1682 self.create_local_scope(env)
1684 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1686 args = self.type.args
1687 if omit_optional_args:
1688 args = args[:len(args) - self.type.optional_arg_count]
1689 arg_names = [arg.name for arg in args]
1691 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1693 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1694 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1695 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1696 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)
1697 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1699 def declare_arguments(self, env):
1700 for arg in self.type.args:
1702 error(arg.pos, "Missing argument name")
1703 self.declare_argument(env, arg)
1705 def need_gil_acquisition(self, lenv):
1706 return self.type.with_gil
1708 def nogil_check(self, env):
1710 with_gil = type.with_gil
1711 if type.nogil and not with_gil:
1712 if type.return_type.is_pyobject:
1714 "Function with Python return type cannot be declared nogil")
1715 for entry in self.local_scope.var_entries:
1716 if entry.type.is_pyobject:
1717 error(self.pos, "Function declared nogil has Python locals or temporaries")
1719 def analyse_expressions(self, env):
1720 self.local_scope.directives = env.directives
1721 if self.py_func is not None:
1722 # this will also analyse the default values
1723 self.py_func.analyse_expressions(env)
1725 self.analyse_default_values(env)
1726 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1728 def needs_assignment_synthesis(self, env, code=None):
1731 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1734 visibility = self.entry.visibility
1735 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1736 arg_decls.append(arg.declaration_code())
1737 if with_dispatch and self.overridable:
1738 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1739 if type.optional_arg_count and with_opt_args:
1740 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1741 if type.has_varargs:
1742 arg_decls.append("...")
1744 arg_decls = ["void"]
1746 cname = self.entry.func_cname
1747 entity = type.function_header_code(cname, ', '.join(arg_decls))
1748 if visibility == 'public':
1749 dll_linkage = "DL_EXPORT"
1752 header = self.return_type.declaration_code(entity,
1753 dll_linkage = dll_linkage)
1754 if visibility == 'extern':
1755 storage_class = "%s " % Naming.extern_c_macro
1756 elif visibility == 'public':
1759 storage_class = "static "
1760 if 'inline' in self.modifiers:
1761 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1762 code.putln("%s%s %s {" % (
1764 ' '.join(self.modifiers).upper(), # macro forms
1767 def generate_argument_declarations(self, env, code):
1768 for arg in self.args:
1770 result = arg.calculate_default_value_code(code)
1771 code.putln('%s = %s;' % (
1772 arg.type.declaration_code(arg.cname), result))
1774 def generate_keyword_list(self, code):
1777 def generate_argument_parsing_code(self, env, code):
1779 if self.type.optional_arg_count:
1780 code.putln('if (%s) {' % Naming.optional_args_cname)
1781 for arg in self.args:
1783 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1784 declarator = arg.declarator
1785 while not hasattr(declarator, 'name'):
1786 declarator = declarator.base
1787 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1789 for _ in range(self.type.optional_arg_count):
1793 def generate_argument_conversion_code(self, code):
1796 def generate_argument_type_tests(self, code):
1797 # Generate type tests for args whose type in a parent
1798 # class is a supertype of the declared type.
1799 for arg in self.type.args:
1800 if arg.needs_type_test:
1801 self.generate_arg_type_test(arg, code)
1802 elif arg.type.is_pyobject and not arg.accept_none:
1803 self.generate_arg_none_check(arg, code)
1805 def error_value(self):
1806 if self.return_type.is_pyobject:
1810 return self.entry.type.exception_value
1812 def caller_will_check_exceptions(self):
1813 return self.entry.type.exception_check
1815 def generate_wrapper_functions(self, code):
1816 # If the C signature of a function has changed, we need to generate
1817 # wrappers to put in the slots here.
1820 func_type = entry.type
1821 while entry.prev_entry is not None:
1823 entry = entry.prev_entry
1824 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1826 self.generate_function_header(code,
1828 with_dispatch = entry.type.is_overridable,
1829 with_opt_args = entry.type.optional_arg_count,
1830 cname = entry.func_cname)
1831 if not self.return_type.is_void:
1833 args = self.type.args
1834 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1835 if entry.type.is_overridable:
1836 arglist.append(Naming.skip_dispatch_cname)
1837 elif func_type.is_overridable:
1839 if entry.type.optional_arg_count:
1840 arglist.append(Naming.optional_args_cname)
1841 elif func_type.optional_arg_count:
1842 arglist.append('NULL')
1843 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1847 class PyArgDeclNode(Node):
1848 # Argument which must be a Python object (used
1849 # for * and ** arguments).
1852 # entry Symtab.Entry
1853 # annotation ExprNode or None Py3 argument annotation
1856 def generate_function_definitions(self, env, code):
1857 self.entry.generate_function_definitions(env, code)
1859 class DecoratorNode(Node):
1862 # decorator NameNode or CallNode or AttributeNode
1863 child_attrs = ['decorator']
1866 class DefNode(FuncDefNode):
1867 # A Python function definition.
1869 # name string the Python name of the function
1870 # lambda_name string the internal name of a lambda 'function'
1871 # decorators [DecoratorNode] list of decorators
1872 # args [CArgDeclNode] formal arguments
1873 # star_arg PyArgDeclNode or None * argument
1874 # starstar_arg PyArgDeclNode or None ** argument
1875 # doc EncodedString or None
1877 # return_type_annotation
1878 # ExprNode or None the Py3 return type annotation
1880 # The following subnode is constructed internally
1881 # when the def statement is inside a Python class definition.
1883 # assmt AssignmentNode Function construction/assignment
1885 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1890 num_required_kw_args = 0
1891 reqd_kw_flags_cname = "0"
1894 return_type_annotation = None
1899 def __init__(self, pos, **kwds):
1900 FuncDefNode.__init__(self, pos, **kwds)
1902 for arg in self.args:
1909 self.num_kwonly_args = k
1910 self.num_required_kw_args = rk
1911 self.num_required_args = r
1913 def as_cfunction(self, cfunc=None, scope=None):
1915 error(self.star_arg.pos, "cdef function cannot have star argument")
1916 if self.starstar_arg:
1917 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1920 for formal_arg in self.args:
1921 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1922 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1924 type = py_object_type,
1925 pos = formal_arg.pos))
1926 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1928 has_varargs = False,
1929 exception_value = None,
1930 exception_check = False,
1933 is_overridable = True)
1934 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1938 cfunc_type = cfunc.type
1939 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1940 error(self.pos, "wrong number of arguments")
1941 error(cfunc.pos, "previous declaration here")
1942 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1943 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1944 is_self_arg = (i == 0 and scope.is_c_class_scope))
1945 if type is None or type is PyrexTypes.py_object_type:
1946 formal_arg.type = type_arg.type
1947 formal_arg.name_declarator = name_declarator
1949 if cfunc_type.exception_value is None:
1950 exception_value = None
1952 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1953 declarator = CFuncDeclaratorNode(self.pos,
1954 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1956 has_varargs = False,
1957 exception_check = cfunc_type.exception_check,
1958 exception_value = exception_value,
1959 with_gil = cfunc_type.with_gil,
1960 nogil = cfunc_type.nogil)
1961 return CFuncDefNode(self.pos,
1963 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1964 declarator = declarator,
1967 overridable = cfunc_type.is_overridable,
1969 with_gil = cfunc_type.with_gil,
1970 nogil = cfunc_type.nogil,
1971 visibility = 'private',
1973 directive_locals = getattr(cfunc, 'directive_locals', {}))
1975 def analyse_declarations(self, env):
1976 self.is_classmethod = self.is_staticmethod = False
1978 for decorator in self.decorators:
1979 func = decorator.decorator
1981 self.is_classmethod |= func.name == 'classmethod'
1982 self.is_staticmethod |= func.name == 'staticmethod'
1984 if self.is_classmethod and env.lookup_here('classmethod'):
1985 # classmethod() was overridden - not much we can do here ...
1986 self.is_classmethod = False
1987 if self.is_staticmethod and env.lookup_here('staticmethod'):
1988 # staticmethod() was overridden - not much we can do here ...
1989 self.is_staticmethod = False
1991 if self.name == '__new__' and env.is_py_class_scope:
1992 self.is_staticmethod = 1
1994 self.analyse_argument_types(env)
1995 if self.name == '<lambda>':
1996 self.declare_lambda_function(env)
1998 self.declare_pyfunction(env)
1999 self.analyse_signature(env)
2000 self.return_type = self.entry.signature.return_type()
2001 self.create_local_scope(env)
2003 def analyse_argument_types(self, env):
2004 directive_locals = self.directive_locals = env.directives['locals']
2005 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2006 for arg in self.args:
2007 if hasattr(arg, 'name'):
2009 name_declarator = None
2011 base_type = arg.base_type.analyse(env)
2012 name_declarator, type = \
2013 arg.declarator.analyse(base_type, env)
2014 arg.name = name_declarator.name
2015 if arg.name in directive_locals:
2016 type_node = directive_locals[arg.name]
2017 other_type = type_node.analyse_as_type(env)
2018 if other_type is None:
2019 error(type_node.pos, "Not a type")
2020 elif (type is not PyrexTypes.py_object_type
2021 and not type.same_as(other_type)):
2022 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2023 error(type_node.pos, "Previous declaration here")
2026 if name_declarator and name_declarator.cname:
2028 "Python function argument cannot have C name specification")
2029 arg.type = type.as_argument_type()
2031 arg.needs_conversion = 0
2032 arg.needs_type_test = 0
2034 if arg.type.is_pyobject:
2036 arg.accept_none = True
2038 arg.accept_none = False
2039 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2040 if arg.default and arg.default.constant_result is None:
2041 # special case: def func(MyType obj = None)
2042 arg.accept_none = True
2044 # default depends on compiler directive
2045 arg.accept_none = allow_none_for_extension_args
2047 # probably just a plain 'object'
2048 arg.accept_none = True
2050 arg.accept_none = True # won't be used, but must be there
2052 error(arg.pos, "Only Python type arguments can have 'not None'")
2054 error(arg.pos, "Only Python type arguments can have 'or None'")
2056 def analyse_signature(self, env):
2057 if self.entry.is_special:
2059 error(self.pos, "special functions of cdef classes cannot have decorators")
2060 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2061 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2062 # Use the simpler calling signature for zero- and one-argument functions.
2063 if self.entry.signature is TypeSlots.pyfunction_signature:
2064 if len(self.args) == 0:
2065 self.entry.signature = TypeSlots.pyfunction_noargs
2066 elif len(self.args) == 1:
2067 if self.args[0].default is None and not self.args[0].kw_only:
2068 self.entry.signature = TypeSlots.pyfunction_onearg
2069 elif self.entry.signature is TypeSlots.pymethod_signature:
2070 if len(self.args) == 1:
2071 self.entry.signature = TypeSlots.unaryfunc
2072 elif len(self.args) == 2:
2073 if self.args[1].default is None and not self.args[1].kw_only:
2074 self.entry.signature = TypeSlots.ibinaryfunc
2076 sig = self.entry.signature
2077 nfixed = sig.num_fixed_args()
2078 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2079 and len(self.args) == 0 and self.star_arg:
2080 # this is the only case where a diverging number of
2081 # arguments is not an error - when we have no explicit
2082 # 'self' parameter as in method(*args)
2083 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2084 self.self_in_stararg = 1
2087 for i in range(min(nfixed, len(self.args))):
2090 if sig.is_self_arg(i) and not self.is_staticmethod:
2091 if self.is_classmethod:
2093 arg.hdr_type = arg.type = Builtin.type_type
2096 arg.hdr_type = arg.type = env.parent_type
2097 arg.needs_conversion = 0
2099 arg.hdr_type = sig.fixed_arg_type(i)
2100 if not arg.type.same_as(arg.hdr_type):
2101 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2102 arg.needs_type_test = 1
2104 arg.needs_conversion = 1
2105 if arg.needs_conversion:
2106 arg.hdr_cname = Naming.arg_prefix + arg.name
2108 arg.hdr_cname = Naming.var_prefix + arg.name
2110 if nfixed > len(self.args):
2111 self.bad_signature()
2113 elif nfixed < len(self.args):
2114 if not sig.has_generic_args:
2115 self.bad_signature()
2116 for arg in self.args:
2117 if arg.is_generic and \
2118 (arg.type.is_extension_type or arg.type.is_builtin_type):
2119 arg.needs_type_test = 1
2121 def bad_signature(self):
2122 sig = self.entry.signature
2123 expected_str = "%d" % sig.num_fixed_args()
2124 if sig.has_generic_args:
2125 expected_str = expected_str + " or more"
2127 if name.startswith("__") and name.endswith("__"):
2128 desc = "Special method"
2132 "%s %s has wrong number of arguments "
2133 "(%d declared, %s expected)" % (
2134 desc, self.name, len(self.args), expected_str))
2136 def signature_has_nongeneric_args(self):
2137 argcount = len(self.args)
2138 if argcount == 0 or (
2139 argcount == 1 and (self.args[0].is_self_arg or
2140 self.args[0].is_type_arg)):
2144 def signature_has_generic_args(self):
2145 return self.entry.signature.has_generic_args
2147 def declare_pyfunction(self, env):
2148 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2150 entry = env.lookup_here(name)
2151 if entry and entry.type.is_cfunction and not self.is_wrapper:
2152 warning(self.pos, "Overriding cdef method with def method.", 5)
2153 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2155 prefix = env.next_id(env.scope_prefix)
2157 entry.func_cname = \
2158 Naming.pyfunc_prefix + prefix + name
2159 entry.pymethdef_cname = \
2160 Naming.pymethdef_prefix + prefix + name
2161 if Options.docstrings:
2162 entry.doc = embed_position(self.pos, self.doc)
2164 Naming.funcdoc_prefix + prefix + name
2165 if entry.is_special:
2166 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2167 entry.wrapperbase_cname = None
2169 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2173 def declare_lambda_function(self, env):
2175 prefix = env.scope_prefix
2177 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2178 entry = env.declare_lambda_function(func_cname, self.pos)
2179 entry.pymethdef_cname = \
2180 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2181 entry.qualified_name = env.qualify_name(self.lambda_name)
2185 def declare_arguments(self, env):
2186 for arg in self.args:
2188 error(arg.pos, "Missing argument name")
2190 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2191 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2192 if arg.needs_conversion:
2193 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2194 if arg.type.is_pyobject:
2195 arg.entry.init = "0"
2196 arg.entry.init_to_none = 0
2198 arg.entry = self.declare_argument(env, arg)
2200 arg.entry.is_self_arg = arg.is_self_arg
2202 if arg.is_self_arg or arg.is_type_arg or \
2203 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2204 arg.entry.is_declared_generic = 1
2205 self.declare_python_arg(env, self.star_arg)
2206 self.declare_python_arg(env, self.starstar_arg)
2208 def declare_python_arg(self, env, arg):
2210 if env.directives['infer_types'] != False:
2211 type = PyrexTypes.unspecified_type
2213 type = py_object_type
2214 entry = env.declare_var(arg.name, type, arg.pos)
2217 entry.init_to_none = 0
2218 entry.xdecref_cleanup = 1
2220 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2222 def analyse_expressions(self, env):
2223 self.local_scope.directives = env.directives
2224 self.analyse_default_values(env)
2225 if self.needs_assignment_synthesis(env):
2226 # Shouldn't we be doing this at the module level too?
2227 self.synthesize_assignment_node(env)
2229 def needs_assignment_synthesis(self, env, code=None):
2230 # Should enable for module level as well, that will require more testing...
2231 if self.entry.is_anonymous:
2233 if env.is_module_scope:
2235 return env.directives['binding']
2237 return code.globalstate.directives['binding']
2238 return env.is_py_class_scope or env.is_closure_scope
2240 def synthesize_assignment_node(self, env):
2243 while genv.is_py_class_scope or genv.is_c_class_scope:
2244 genv = genv.outer_scope
2246 if genv.is_closure_scope:
2247 rhs = ExprNodes.InnerFunctionNode(
2248 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2250 rhs = ExprNodes.PyCFunctionNode(
2251 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2253 if env.is_py_class_scope:
2254 if not self.is_staticmethod and not self.is_classmethod:
2257 self.assmt = SingleAssignmentNode(self.pos,
2258 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2260 self.assmt.analyse_declarations(env)
2261 self.assmt.analyse_expressions(env)
2263 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2265 sig = self.entry.signature
2266 if sig.has_dummy_arg or self.self_in_stararg:
2267 arg_code_list.append(
2268 "PyObject *%s" % Naming.self_cname)
2269 for arg in self.args:
2270 if not arg.is_generic:
2271 if arg.is_self_arg or arg.is_type_arg:
2272 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2274 arg_code_list.append(
2275 arg.hdr_type.declaration_code(arg.hdr_cname))
2276 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2277 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2278 if sig.has_generic_args:
2279 arg_code_list.append(
2280 "PyObject *%s, PyObject *%s"
2281 % (Naming.args_cname, Naming.kwds_cname))
2282 arg_code = ", ".join(arg_code_list)
2283 dc = self.return_type.declaration_code(self.entry.func_cname)
2284 mf = " ".join(self.modifiers).upper()
2286 header = "static %s%s(%s)" % (mf, dc, arg_code)
2287 code.putln("%s; /*proto*/" % header)
2290 if (Options.docstrings and self.entry.doc and
2291 not self.entry.scope.is_property_scope and
2292 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2293 docstr = self.entry.doc
2294 if docstr.is_unicode:
2295 docstr = docstr.utf8encode()
2297 'static char %s[] = "%s";' % (
2298 self.entry.doc_cname,
2299 split_string_literal(escape_byte_string(docstr))))
2300 if self.entry.is_special:
2302 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2305 "static PyMethodDef %s = " %
2306 self.entry.pymethdef_cname)
2307 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2308 code.putln("%s {" % header)
2310 def generate_argument_declarations(self, env, code):
2311 for arg in self.args:
2312 if arg.is_generic: # or arg.needs_conversion:
2313 if arg.needs_conversion:
2314 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2315 elif not arg.entry.in_closure:
2316 code.put_var_declaration(arg.entry)
2318 def generate_keyword_list(self, code):
2319 if self.signature_has_generic_args() and \
2320 self.signature_has_nongeneric_args():
2322 "static PyObject **%s[] = {" %
2323 Naming.pykwdlist_cname)
2324 for arg in self.args:
2326 pystring_cname = code.intern_identifier(arg.name)
2327 code.put('&%s,' % pystring_cname)
2330 def generate_argument_parsing_code(self, env, code):
2331 # Generate PyArg_ParseTuple call for generic
2332 # arguments, if any.
2333 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2334 # get rid of unused argument warning
2335 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2337 old_error_label = code.new_error_label()
2338 our_error_label = code.error_label
2339 end_label = code.new_label("argument_unpacking_done")
2341 has_kwonly_args = self.num_kwonly_args > 0
2342 has_star_or_kw_args = self.star_arg is not None \
2343 or self.starstar_arg is not None or has_kwonly_args
2345 for arg in self.args:
2346 if not arg.type.is_pyobject:
2347 done = arg.type.create_from_py_utility_code(env)
2348 if not done: pass # will fail later
2350 if not self.signature_has_generic_args():
2351 if has_star_or_kw_args:
2352 error(self.pos, "This method cannot have * or keyword arguments")
2353 self.generate_argument_conversion_code(code)
2355 elif not self.signature_has_nongeneric_args():
2356 # func(*args) or func(**kw) or func(*args, **kw)
2357 self.generate_stararg_copy_code(code)
2360 positional_args = []
2362 for arg in self.args:
2363 arg_entry = arg.entry
2366 if not arg.is_self_arg and not arg.is_type_arg:
2368 kw_only_args.append(arg)
2370 positional_args.append(arg)
2372 kw_only_args.append(arg)
2373 elif not arg.is_self_arg and not arg.is_type_arg:
2374 positional_args.append(arg)
2376 self.generate_tuple_and_keyword_parsing_code(
2377 positional_args, kw_only_args, end_label, code)
2379 code.error_label = old_error_label
2380 if code.label_used(our_error_label):
2381 if not code.label_used(end_label):
2382 code.put_goto(end_label)
2383 code.put_label(our_error_label)
2384 if has_star_or_kw_args:
2385 self.generate_arg_decref(self.star_arg, code)
2386 if self.starstar_arg:
2387 if self.starstar_arg.entry.xdecref_cleanup:
2388 code.put_var_xdecref(self.starstar_arg.entry)
2390 code.put_var_decref(self.starstar_arg.entry)
2391 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2392 # The arguments are put into the closure one after the
2393 # other, so when type errors are found, all references in
2394 # the closure instance must be properly ref-counted to
2395 # facilitate generic closure instance deallocation. In
2396 # the case of an argument type error, it's best to just
2397 # DECREF+clear the already handled references, as this
2398 # frees their references as early as possible.
2399 for arg in self.args:
2400 if arg.type.is_pyobject and arg.entry.in_closure:
2401 code.put_var_xdecref_clear(arg.entry)
2402 if self.needs_closure:
2403 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2404 code.put_finish_refcount_context()
2405 code.putln("return %s;" % self.error_value())
2406 if code.label_used(end_label):
2407 code.put_label(end_label)
2409 def generate_arg_assignment(self, arg, item, code):
2410 if arg.type.is_pyobject:
2412 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2414 code.putln("%s = %s;" % (entry.cname, item))
2415 if entry.in_closure:
2416 code.put_var_incref(entry)
2418 func = arg.type.from_py_function
2420 code.putln("%s = %s(%s); %s" % (
2424 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2426 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2428 def generate_arg_xdecref(self, arg, code):
2430 code.put_var_xdecref(arg.entry)
2432 def generate_arg_decref(self, arg, code):
2434 code.put_var_decref(arg.entry)
2436 def generate_stararg_copy_code(self, code):
2437 if not self.star_arg:
2438 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2439 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2441 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2442 self.name, Naming.args_cname, self.error_value()))
2445 if self.starstar_arg:
2447 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2449 kwarg_check = "%s" % Naming.kwds_cname
2451 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2452 Naming.kwds_cname, Naming.kwds_cname)
2453 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2455 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2456 kwarg_check, Naming.kwds_cname, self.name,
2457 bool(self.starstar_arg), self.error_value()))
2459 if self.starstar_arg:
2460 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2461 self.starstar_arg.entry.cname,
2464 code.putln("if (unlikely(!%s)) return %s;" % (
2465 self.starstar_arg.entry.cname, self.error_value()))
2466 self.starstar_arg.entry.xdecref_cleanup = 0
2467 code.put_gotref(self.starstar_arg.entry.cname)
2469 if self.self_in_stararg:
2470 # need to create a new tuple with 'self' inserted as first item
2471 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2472 self.star_arg.entry.cname,
2474 self.star_arg.entry.cname))
2475 if self.starstar_arg:
2477 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2478 code.putln("return %s;" % self.error_value())
2481 code.putln("return %s;" % self.error_value())
2482 code.put_gotref(self.star_arg.entry.cname)
2483 code.put_incref(Naming.self_cname, py_object_type)
2484 code.put_giveref(Naming.self_cname)
2485 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2486 self.star_arg.entry.cname, Naming.self_cname))
2487 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2488 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2489 temp, temp, Naming.args_cname, temp))
2490 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2491 Naming.args_cname, temp))
2492 code.put_incref("item", py_object_type)
2493 code.put_giveref("item")
2494 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2495 self.star_arg.entry.cname, temp))
2497 code.funcstate.release_temp(temp)
2498 self.star_arg.entry.xdecref_cleanup = 0
2500 code.put_incref(Naming.args_cname, py_object_type)
2501 code.putln("%s = %s;" % (
2502 self.star_arg.entry.cname,
2504 self.star_arg.entry.xdecref_cleanup = 0
2506 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2507 kw_only_args, success_label, code):
2508 argtuple_error_label = code.new_label("argtuple_error")
2510 min_positional_args = self.num_required_args - self.num_required_kw_args
2511 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2512 min_positional_args -= 1
2513 max_positional_args = len(positional_args)
2514 has_fixed_positional_count = not self.star_arg and \
2515 min_positional_args == max_positional_args
2517 if self.num_required_kw_args:
2518 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2520 if self.starstar_arg or self.star_arg:
2521 self.generate_stararg_init_code(max_positional_args, code)
2523 # --- optimised code when we receive keyword arguments
2524 if self.num_required_kw_args:
2525 likely_hint = "likely"
2527 likely_hint = "unlikely"
2528 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2529 self.generate_keyword_unpacking_code(
2530 min_positional_args, max_positional_args,
2531 has_fixed_positional_count,
2532 positional_args, kw_only_args, argtuple_error_label, code)
2534 # --- optimised code when we do not receive any keyword arguments
2535 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2536 # Python raises arg tuple related errors first, so we must
2537 # check the length here
2538 if min_positional_args == max_positional_args and not self.star_arg:
2542 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2543 Naming.args_cname, compare, min_positional_args))
2544 code.put_goto(argtuple_error_label)
2546 if self.num_required_kw_args:
2547 # pure error case: keywords required but not passed
2548 if max_positional_args > min_positional_args and not self.star_arg:
2549 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2550 Naming.args_cname, max_positional_args))
2551 code.put_goto(argtuple_error_label)
2552 code.putln('} else {')
2553 for i, arg in enumerate(kw_only_args):
2555 pystring_cname = code.intern_identifier(arg.name)
2556 # required keyword-only argument missing
2557 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2560 code.putln(code.error_goto(self.pos))
2563 elif min_positional_args == max_positional_args:
2564 # parse the exact number of positional arguments from the
2566 code.putln('} else {')
2567 for i, arg in enumerate(positional_args):
2568 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2569 self.generate_arg_assignment(arg, item, code)
2570 self.generate_arg_default_assignments(code)
2573 # parse the positional arguments from the variable length
2575 code.putln('} else {')
2576 self.generate_arg_default_assignments(code)
2577 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2579 code.putln('default:')
2580 reversed_args = list(enumerate(positional_args))[::-1]
2581 for i, arg in reversed_args:
2582 if i >= min_positional_args-1:
2583 if min_positional_args > 1:
2584 code.putln('case %2d:' % (i+1)) # pure code beautification
2586 code.put('case %2d: ' % (i+1))
2587 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2588 self.generate_arg_assignment(arg, item, code)
2589 if min_positional_args == 0:
2590 code.put('case 0: ')
2591 code.putln('break;')
2593 if min_positional_args:
2594 for i in range(min_positional_args-1, -1, -1):
2595 code.putln('case %2d:' % i)
2596 code.put_goto(argtuple_error_label)
2598 code.put('default: ')
2599 code.put_goto(argtuple_error_label)
2604 if code.label_used(argtuple_error_label):
2605 code.put_goto(success_label)
2606 code.put_label(argtuple_error_label)
2607 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2608 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2609 self.name, has_fixed_positional_count,
2610 min_positional_args, max_positional_args,
2612 code.putln(code.error_goto(self.pos))
2614 def generate_arg_default_assignments(self, code):
2615 for arg in self.args:
2616 if arg.is_generic and arg.default:
2620 arg.calculate_default_value_code(code)))
2622 def generate_stararg_init_code(self, max_positional_args, code):
2623 if self.starstar_arg:
2624 self.starstar_arg.entry.xdecref_cleanup = 0
2625 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2626 self.starstar_arg.entry.cname,
2627 self.starstar_arg.entry.cname,
2628 self.error_value()))
2629 code.put_gotref(self.starstar_arg.entry.cname)
2631 self.star_arg.entry.xdecref_cleanup = 0
2632 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2634 max_positional_args))
2635 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2636 self.star_arg.entry.cname, Naming.args_cname,
2637 max_positional_args, Naming.args_cname))
2638 code.put_gotref(self.star_arg.entry.cname)
2639 if self.starstar_arg:
2641 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2642 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2643 code.putln('return %s;' % self.error_value())
2646 code.putln("if (unlikely(!%s)) return %s;" % (
2647 self.star_arg.entry.cname, self.error_value()))
2648 code.putln('} else {')
2649 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2650 code.put_incref(Naming.empty_tuple, py_object_type)
2653 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2654 has_fixed_positional_count, positional_args,
2655 kw_only_args, argtuple_error_label, code):
2656 all_args = tuple(positional_args) + tuple(kw_only_args)
2657 max_args = len(all_args)
2659 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2661 # the 'values' array collects borrowed references to arguments
2662 # before doing any type coercion etc.
2663 code.putln("PyObject* values[%d] = {%s};" % (
2664 max_args, ','.join('0'*max_args)))
2666 # assign borrowed Python default values to the values array,
2667 # so that they can be overwritten by received arguments below
2668 for i, arg in enumerate(all_args):
2669 if arg.default and arg.type.is_pyobject:
2670 default_value = arg.calculate_default_value_code(code)
2671 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2673 # parse the args tuple and check that it's not too long
2674 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2676 code.putln('default:')
2677 for i in range(max_positional_args-1, -1, -1):
2678 code.put('case %2d: ' % (i+1))
2679 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2680 i, Naming.args_cname, i))
2681 code.putln('case 0: break;')
2682 if not self.star_arg:
2683 code.put('default: ') # more arguments than allowed
2684 code.put_goto(argtuple_error_label)
2687 # now fill up the positional/required arguments with values
2689 if self.num_required_args or max_positional_args > 0:
2690 last_required_arg = -1
2691 for i, arg in enumerate(all_args):
2693 last_required_arg = i
2694 if last_required_arg < max_positional_args:
2695 last_required_arg = max_positional_args-1
2696 num_required_args = self.num_required_args
2697 if max_positional_args > 0:
2698 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2699 for i, arg in enumerate(all_args[:last_required_arg+1]):
2700 if max_positional_args > 0 and i <= max_positional_args:
2701 if self.star_arg and i == max_positional_args:
2702 code.putln('default:')
2704 code.putln('case %2d:' % i)
2705 pystring_cname = code.intern_identifier(arg.name)
2708 # handled separately below
2710 code.putln('if (kw_args > 0) {')
2711 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2712 Naming.kwds_cname, pystring_cname))
2713 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2716 num_required_args -= 1
2717 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2718 i, Naming.kwds_cname, pystring_cname))
2719 code.putln('if (likely(values[%d])) kw_args--;' % i);
2720 if i < min_positional_args:
2722 # special case: we know arg 0 is missing
2724 code.put_goto(argtuple_error_label)
2726 # print the correct number of values (args or
2727 # kwargs) that were passed into positional
2728 # arguments up to this point
2729 code.putln('else {')
2730 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2731 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2732 self.name, has_fixed_positional_count,
2733 min_positional_args, max_positional_args, i))
2734 code.putln(code.error_goto(self.pos))
2737 code.putln('else {')
2738 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2739 self.name, pystring_cname))
2740 code.putln(code.error_goto(self.pos))
2742 if max_positional_args > 0:
2745 if kw_only_args and not self.starstar_arg:
2746 # unpack optional keyword-only arguments
2747 # checking for interned strings in a dict is faster than iterating
2748 # but it's too likely that we must iterate if we expect **kwargs
2750 for i, arg in enumerate(all_args[max_positional_args:]):
2751 if not arg.kw_only or not arg.default:
2753 optional_args.append((i+max_positional_args, arg))
2755 # this mimics an unrolled loop so that we can "break" out of it
2756 code.putln('while (kw_args > 0) {')
2757 code.putln('PyObject* value;')
2758 for i, arg in optional_args:
2759 pystring_cname = code.intern_identifier(arg.name)
2761 'value = PyDict_GetItem(%s, %s);' % (
2762 Naming.kwds_cname, pystring_cname))
2764 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2765 code.putln('break;')
2768 code.putln('if (unlikely(kw_args > 0)) {')
2769 # non-positional/-required kw args left in dict: default args,
2770 # kw-only args, **kwargs or error
2772 # This is sort of a catch-all: except for checking required
2773 # arguments, this will always do the right thing for unpacking
2774 # keyword arguments, so that we can concentrate on optimising
2775 # common cases above.
2776 if max_positional_args == 0:
2779 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2780 Naming.args_cname, max_positional_args,
2781 Naming.args_cname, max_positional_args))
2782 pos_arg_count = "used_pos_args"
2784 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2785 code.globalstate.use_utility_code(parse_keywords_utility_code)
2787 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2789 Naming.pykwdlist_cname,
2790 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2793 code.putln(code.error_goto(self.pos))
2796 # convert arg values to their final type and assign them
2797 for i, arg in enumerate(all_args):
2798 if arg.default and not arg.type.is_pyobject:
2799 code.putln("if (values[%d]) {" % i)
2800 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2801 if arg.default and not arg.type.is_pyobject:
2802 code.putln('} else {')
2806 arg.calculate_default_value_code(code)))
2809 def generate_argument_conversion_code(self, code):
2810 # Generate code to convert arguments from signature type to
2811 # declared type, if needed. Also copies signature arguments
2812 # into closure fields.
2813 for arg in self.args:
2814 if arg.needs_conversion:
2815 self.generate_arg_conversion(arg, code)
2816 elif arg.entry.in_closure:
2817 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2818 if arg.type.is_pyobject:
2819 code.put_var_incref(arg.entry)
2821 def generate_arg_conversion(self, arg, code):
2822 # Generate conversion code for one argument.
2823 old_type = arg.hdr_type
2825 if old_type.is_pyobject:
2827 code.putln("if (%s) {" % arg.hdr_cname)
2829 code.putln("assert(%s); {" % arg.hdr_cname)
2830 self.generate_arg_conversion_from_pyobject(arg, code)
2832 elif new_type.is_pyobject:
2833 self.generate_arg_conversion_to_pyobject(arg, code)
2835 if new_type.assignable_from(old_type):
2837 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2840 "Cannot convert 1 argument from '%s' to '%s'" %
2841 (old_type, new_type))
2843 def generate_arg_conversion_from_pyobject(self, arg, code):
2845 func = new_type.from_py_function
2846 # copied from CoerceFromPyTypeNode
2848 lhs = arg.entry.cname
2849 rhs = "%s(%s)" % (func, arg.hdr_cname)
2850 if new_type.is_enum:
2851 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2852 code.putln("%s = %s; %s" % (
2855 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2858 "Cannot convert Python object argument to type '%s'"
2861 def generate_arg_conversion_to_pyobject(self, arg, code):
2862 old_type = arg.hdr_type
2863 func = old_type.to_py_function
2865 code.putln("%s = %s(%s); %s" % (
2869 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2870 code.put_var_gotref(arg.entry)
2873 "Cannot convert argument of type '%s' to Python object"
2876 def generate_argument_type_tests(self, code):
2877 # Generate type tests for args whose signature
2878 # type is PyObject * and whose declared type is
2879 # a subtype thereof.
2880 for arg in self.args:
2881 if arg.needs_type_test:
2882 self.generate_arg_type_test(arg, code)
2883 elif not arg.accept_none and arg.type.is_pyobject:
2884 self.generate_arg_none_check(arg, code)
2886 def error_value(self):
2887 return self.entry.signature.error_value
2889 def caller_will_check_exceptions(self):
2892 class OverrideCheckNode(StatNode):
2893 # A Node for dispatching to the def method if it
2902 child_attrs = ['body']
2906 def analyse_expressions(self, env):
2907 self.args = env.arg_entries
2908 if self.py_func.is_module_scope:
2913 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2914 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2915 call_node = ExprNodes.SimpleCallNode(self.pos,
2916 function=self.func_node,
2917 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2918 self.body = ReturnStatNode(self.pos, value=call_node)
2919 self.body.analyse_expressions(env)
2921 def generate_execution_code(self, code):
2922 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2923 # Check to see if we are an extension type
2924 if self.py_func.is_module_scope:
2925 self_arg = "((PyObject *)%s)" % Naming.module_cname
2927 self_arg = "((PyObject *)%s)" % self.args[0].cname
2928 code.putln("/* Check if called by wrapper */")
2929 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2930 code.putln("/* Check if overriden in Python */")
2931 if self.py_func.is_module_scope:
2932 code.putln("else {")
2934 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2935 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2936 self.func_node.set_cname(func_node_temp)
2937 # need to get attribute manually--scope would return cdef method
2938 err = code.error_goto_if_null(func_node_temp, self.pos)
2939 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2940 func_node_temp, self_arg, interned_attr_cname, err))
2941 code.put_gotref(func_node_temp)
2942 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2943 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2944 func_node_temp, self.py_func.entry.func_cname)
2945 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2946 self.body.generate_execution_code(code)
2948 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2949 code.funcstate.release_temp(func_node_temp)
2952 class ClassDefNode(StatNode, BlockNode):
2955 class PyClassDefNode(ClassDefNode):
2956 # A Python class definition.
2958 # name EncodedString Name of the class
2959 # doc string or None
2960 # body StatNode Attribute definition code
2961 # entry Symtab.Entry
2962 # scope PyClassScope
2963 # decorators [DecoratorNode] list of decorators or None
2965 # The following subnodes are constructed internally:
2967 # dict DictNode Class dictionary or Py3 namespace
2968 # classobj ClassNode Class object
2969 # target NameNode Variable to assign class object to
2971 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2973 py3_style_class = False # Python3 style class (bases+kwargs)
2975 def __init__(self, pos, name, bases, doc, body, decorators = None,
2976 keyword_args = None, starstar_arg = None):
2977 StatNode.__init__(self, pos)
2981 self.decorators = decorators
2983 if self.doc and Options.docstrings:
2984 doc = embed_position(self.pos, self.doc)
2985 doc_node = ExprNodes.StringNode(pos, value = doc)
2988 if keyword_args or starstar_arg:
2989 self.py3_style_class = True
2991 self.metaclass = None
2992 if keyword_args and not starstar_arg:
2993 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
2994 if item.key.value == 'metaclass':
2995 if self.metaclass is not None:
2996 error(item.pos, "keyword argument 'metaclass' passed multiple times")
2997 # special case: we already know the metaclass,
2998 # so we don't need to do the "build kwargs,
2999 # find metaclass" dance at runtime
3000 self.metaclass = item.value
3001 del keyword_args.key_value_pairs[i]
3002 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3003 self.mkw = ExprNodes.KeywordArgsNode(
3004 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3006 self.mkw = ExprNodes.NullNode(pos)
3007 if self.metaclass is None:
3008 self.metaclass = ExprNodes.PyClassMetaclassNode(
3009 pos, mkw = self.mkw, bases = self.bases)
3010 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3011 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3013 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3014 bases = self.bases, dict = self.dict, doc = doc_node,
3015 metaclass = self.metaclass, mkw = self.mkw)
3017 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3018 self.metaclass = None
3021 self.classobj = ExprNodes.ClassNode(pos, name = name,
3022 bases = bases, dict = self.dict, doc = doc_node)
3023 self.target = ExprNodes.NameNode(pos, name = name)
3025 def as_cclass(self):
3027 Return this node as if it were declared as an extension class
3029 if self.py3_style_class:
3030 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3032 bases = self.classobj.bases.args
3034 base_class_name = None
3035 base_class_module = None
3036 elif len(bases) == 1:
3039 from ExprNodes import AttributeNode, NameNode
3040 while isinstance(base, AttributeNode):
3041 path.insert(0, base.attribute)
3043 if isinstance(base, NameNode):
3044 path.insert(0, base.name)
3045 base_class_name = path[-1]
3047 base_class_module = u'.'.join(path[:-1])
3049 base_class_module = None
3051 error(self.classobj.bases.args.pos, "Invalid base class")
3053 error(self.classobj.bases.args.pos, "C class may only have one base class")
3056 return CClassDefNode(self.pos,
3057 visibility = 'private',
3059 class_name = self.name,
3060 base_class_module = base_class_module,
3061 base_class_name = base_class_name,
3062 decorators = self.decorators,
3067 def create_scope(self, env):
3069 while genv.is_py_class_scope or genv.is_c_class_scope:
3070 genv = genv.outer_scope
3071 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3074 def analyse_declarations(self, env):
3075 self.target.analyse_target_declaration(env)
3076 cenv = self.create_scope(env)
3077 cenv.directives = env.directives
3078 cenv.class_obj_cname = self.target.entry.cname
3079 self.body.analyse_declarations(cenv)
3081 def analyse_expressions(self, env):
3082 if self.py3_style_class:
3083 self.bases.analyse_expressions(env)
3084 self.metaclass.analyse_expressions(env)
3085 self.mkw.analyse_expressions(env)
3086 self.dict.analyse_expressions(env)
3087 self.classobj.analyse_expressions(env)
3088 genv = env.global_scope()
3090 self.body.analyse_expressions(cenv)
3091 self.target.analyse_target_expression(env, self.classobj)
3093 def generate_function_definitions(self, env, code):
3094 self.generate_lambda_definitions(self.scope, code)
3095 self.body.generate_function_definitions(self.scope, code)
3097 def generate_execution_code(self, code):
3098 code.pyclass_stack.append(self)
3100 if self.py3_style_class:
3101 self.bases.generate_evaluation_code(code)
3102 self.mkw.generate_evaluation_code(code)
3103 self.metaclass.generate_evaluation_code(code)
3104 self.dict.generate_evaluation_code(code)
3105 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3106 self.body.generate_execution_code(code)
3107 self.classobj.generate_evaluation_code(code)
3108 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3109 self.target.generate_assignment_code(self.classobj, code)
3110 self.dict.generate_disposal_code(code)
3111 self.dict.free_temps(code)
3112 if self.py3_style_class:
3113 self.mkw.generate_disposal_code(code)
3114 self.mkw.free_temps(code)
3115 self.metaclass.generate_disposal_code(code)
3116 self.metaclass.free_temps(code)
3117 self.bases.generate_disposal_code(code)
3118 self.bases.free_temps(code)
3119 code.pyclass_stack.pop()
3121 class CClassDefNode(ClassDefNode):
3122 # An extension type definition.
3124 # visibility 'private' or 'public' or 'extern'
3125 # typedef_flag boolean
3127 # module_name string or None For import of extern type objects
3128 # class_name string Unqualified name of class
3129 # as_name string or None Name to declare as in this scope
3130 # base_class_module string or None Module containing the base class
3131 # base_class_name string or None Name of the base class
3132 # objstruct_name string or None Specified C name of object struct
3133 # typeobj_name string or None Specified C name of type object
3134 # in_pxd boolean Is in a .pxd file
3135 # decorators [DecoratorNode] list of decorators or None
3136 # doc string or None
3137 # body StatNode or None
3138 # entry Symtab.Entry
3139 # base_type PyExtensionType or None
3140 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3141 # buffer_defaults_pos
3143 child_attrs = ["body"]
3144 buffer_defaults_node = None
3145 buffer_defaults_pos = None
3146 typedef_flag = False
3148 objstruct_name = None
3152 def analyse_declarations(self, env):
3153 #print "CClassDefNode.analyse_declarations:", self.class_name
3154 #print "...visibility =", self.visibility
3155 #print "...module_name =", self.module_name
3158 if self.buffer_defaults_node:
3159 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3160 env, [], self.buffer_defaults_node,
3161 need_complete=False)
3163 buffer_defaults = None
3165 if env.in_cinclude and not self.objstruct_name:
3166 error(self.pos, "Object struct name specification required for "
3167 "C class defined in 'extern from' block")
3168 self.base_type = None
3169 # Now that module imports are cached, we need to
3170 # import the modules for extern classes.
3171 if self.module_name:
3173 for module in env.cimported_modules:
3174 if module.name == self.module_name:
3175 self.module = module
3176 if self.module is None:
3177 self.module = ModuleScope(self.module_name, None, env.context)
3178 self.module.has_extern_class = 1
3179 env.add_imported_module(self.module)
3181 if self.base_class_name:
3182 if self.base_class_module:
3183 base_class_scope = env.find_module(self.base_class_module, self.pos)
3185 base_class_scope = env
3186 if self.base_class_name == 'object':
3187 # extension classes are special and don't need to inherit from object
3188 if base_class_scope is None or base_class_scope.lookup('object') is None:
3189 self.base_class_name = None
3190 self.base_class_module = None
3191 base_class_scope = None
3192 if base_class_scope:
3193 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3194 if base_class_entry:
3195 if not base_class_entry.is_type:
3196 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3197 elif not base_class_entry.type.is_extension_type and \
3198 not (base_class_entry.type.is_builtin_type and \
3199 base_class_entry.type.objstruct_cname):
3200 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3201 elif not base_class_entry.type.is_complete():
3202 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3203 self.base_class_name, self.class_name))
3204 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3205 base_class_entry.type.scope.directives['final']:
3206 error(self.pos, "Base class '%s' of type '%s' is final" % (
3207 self.base_class_name, self.class_name))
3208 elif base_class_entry.type.is_builtin_type and \
3209 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3210 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3211 % base_class_entry.type.name)
3213 self.base_type = base_class_entry.type
3214 has_body = self.body is not None
3215 if self.module_name and self.visibility != 'extern':
3216 module_path = self.module_name.split(".")
3217 home_scope = env.find_imported_module(module_path, self.pos)
3223 if self.visibility == 'extern':
3224 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3225 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3227 self.entry = home_scope.declare_c_class(
3228 name = self.class_name,
3230 defining = has_body and self.in_pxd,
3231 implementing = has_body and not self.in_pxd,
3232 module_name = self.module_name,
3233 base_type = self.base_type,
3234 objstruct_cname = self.objstruct_name,
3235 typeobj_cname = self.typeobj_name,
3236 visibility = self.visibility,
3237 typedef_flag = self.typedef_flag,
3239 buffer_defaults = buffer_defaults)
3240 if home_scope is not env and self.visibility == 'extern':
3241 env.add_imported_entry(self.class_name, self.entry, self.pos)
3242 self.scope = scope = self.entry.type.scope
3243 if scope is not None:
3244 scope.directives = env.directives
3246 if self.doc and Options.docstrings:
3247 scope.doc = embed_position(self.pos, self.doc)
3250 self.body.analyse_declarations(scope)
3254 scope.implemented = 1
3255 env.allocate_vtable_names(self.entry)
3257 def analyse_expressions(self, env):
3259 scope = self.entry.type.scope
3260 self.body.analyse_expressions(scope)
3262 def generate_function_definitions(self, env, code):
3264 self.generate_lambda_definitions(self.scope, code)
3265 self.body.generate_function_definitions(self.scope, code)
3267 def generate_execution_code(self, code):
3268 # This is needed to generate evaluation code for
3269 # default values of method arguments.
3271 self.body.generate_execution_code(code)
3273 def annotate(self, code):
3275 self.body.annotate(code)
3278 class PropertyNode(StatNode):
3279 # Definition of a property in an extension type.
3282 # doc EncodedString or None Doc string
3285 child_attrs = ["body"]
3287 def analyse_declarations(self, env):
3288 entry = env.declare_property(self.name, self.doc, self.pos)
3290 entry.scope.directives = env.directives
3291 self.body.analyse_declarations(entry.scope)
3293 def analyse_expressions(self, env):
3294 self.body.analyse_expressions(env)
3296 def generate_function_definitions(self, env, code):
3297 self.body.generate_function_definitions(env, code)
3299 def generate_execution_code(self, code):
3302 def annotate(self, code):
3303 self.body.annotate(code)
3306 class GlobalNode(StatNode):
3307 # Global variable declaration.
3313 def analyse_declarations(self, env):
3314 for name in self.names:
3315 env.declare_global(name, self.pos)
3317 def analyse_expressions(self, env):
3320 def generate_execution_code(self, code):
3324 class ExprStatNode(StatNode):
3325 # Expression used as a statement.
3329 child_attrs = ["expr"]
3331 def analyse_declarations(self, env):
3333 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3334 func = self.expr.function.as_cython_attribute()
3335 if func == u'declare':
3336 args, kwds = self.expr.explicit_args_kwds()
3338 error(self.expr.pos, "Variable names must be specified.")
3339 for var, type_node in kwds.key_value_pairs:
3340 type = type_node.analyse_as_type(env)
3342 error(type_node.pos, "Unknown type")
3344 env.declare_var(var.value, type, var.pos, is_cdef = True)
3345 self.__class__ = PassStatNode
3347 def analyse_expressions(self, env):
3348 self.expr.analyse_expressions(env)
3350 def nogil_check(self, env):
3351 if self.expr.type.is_pyobject and self.expr.is_temp:
3354 gil_message = "Discarding owned Python object"
3356 def generate_execution_code(self, code):
3357 self.expr.generate_evaluation_code(code)
3358 if not self.expr.is_temp and self.expr.result():
3359 code.putln("%s;" % self.expr.result())
3360 self.expr.generate_disposal_code(code)
3361 self.expr.free_temps(code)
3363 def generate_function_definitions(self, env, code):
3364 self.expr.generate_function_definitions(env, code)
3366 def annotate(self, code):
3367 self.expr.annotate(code)
3370 class AssignmentNode(StatNode):
3371 # Abstract base class for assignment nodes.
3373 # The analyse_expressions and generate_execution_code
3374 # phases of assignments are split into two sub-phases
3375 # each, to enable all the right hand sides of a
3376 # parallel assignment to be evaluated before assigning
3377 # to any of the left hand sides.
3379 def analyse_expressions(self, env):
3380 self.analyse_types(env)
3382 # def analyse_expressions(self, env):
3383 # self.analyse_expressions_1(env)
3384 # self.analyse_expressions_2(env)
3386 def generate_execution_code(self, code):
3387 self.generate_rhs_evaluation_code(code)
3388 self.generate_assignment_code(code)
3391 class SingleAssignmentNode(AssignmentNode):
3392 # The simplest case:
3396 # lhs ExprNode Left hand side
3397 # rhs ExprNode Right hand side
3398 # first bool Is this guaranteed the first assignment to lhs?
3400 child_attrs = ["lhs", "rhs"]
3402 declaration_only = False
3404 def analyse_declarations(self, env):
3407 # handle declarations of the form x = cython.foo()
3408 if isinstance(self.rhs, ExprNodes.CallNode):
3409 func_name = self.rhs.function.as_cython_attribute()
3411 args, kwds = self.rhs.explicit_args_kwds()
3413 if func_name in ['declare', 'typedef']:
3414 if len(args) > 2 or kwds is not None:
3415 error(self.rhs.pos, "Can only declare one type at a time.")
3417 type = args[0].analyse_as_type(env)
3419 error(args[0].pos, "Unknown type")
3422 if func_name == 'declare':
3423 if isinstance(lhs, ExprNodes.NameNode):
3424 vars = [(lhs.name, lhs.pos)]
3425 elif isinstance(lhs, ExprNodes.TupleNode):
3426 vars = [(var.name, var.pos) for var in lhs.args]
3428 error(lhs.pos, "Invalid declaration")
3430 for var, pos in vars:
3431 env.declare_var(var, type, pos, is_cdef = True)
3436 self.declaration_only = True
3438 self.declaration_only = True
3439 if not isinstance(lhs, ExprNodes.NameNode):
3440 error(lhs.pos, "Invalid declaration.")
3441 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3443 elif func_name in ['struct', 'union']:
3444 self.declaration_only = True
3445 if len(args) > 0 or kwds is None:
3446 error(self.rhs.pos, "Struct or union members must be given by name.")
3449 for member, type_node in kwds.key_value_pairs:
3450 type = type_node.analyse_as_type(env)
3452 error(type_node.pos, "Unknown type")
3454 members.append((member.value, type, member.pos))
3455 if len(members) < len(kwds.key_value_pairs):
3457 if not isinstance(self.lhs, ExprNodes.NameNode):
3458 error(self.lhs.pos, "Invalid declaration.")
3459 name = self.lhs.name
3460 scope = StructOrUnionScope(name)
3461 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3462 for member, type, pos in members:
3463 scope.declare_var(member, type, pos)
3465 if self.declaration_only:
3468 self.lhs.analyse_target_declaration(env)
3470 def analyse_types(self, env, use_temp = 0):
3471 self.rhs.analyse_types(env)
3472 self.lhs.analyse_target_types(env)
3473 self.lhs.gil_assignment_check(env)
3474 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3476 self.rhs = self.rhs.coerce_to_temp(env)
3478 def generate_rhs_evaluation_code(self, code):
3479 self.rhs.generate_evaluation_code(code)
3481 def generate_assignment_code(self, code):
3482 self.lhs.generate_assignment_code(self.rhs, code)
3484 def generate_function_definitions(self, env, code):
3485 self.rhs.generate_function_definitions(env, code)
3487 def annotate(self, code):
3488 self.lhs.annotate(code)
3489 self.rhs.annotate(code)
3492 class CascadedAssignmentNode(AssignmentNode):
3493 # An assignment with multiple left hand sides:
3497 # lhs_list [ExprNode] Left hand sides
3498 # rhs ExprNode Right hand sides
3502 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3504 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3505 coerced_rhs_list = None
3507 def analyse_declarations(self, env):
3508 for lhs in self.lhs_list:
3509 lhs.analyse_target_declaration(env)
3511 def analyse_types(self, env, use_temp = 0):
3512 self.rhs.analyse_types(env)
3513 if not self.rhs.is_simple():
3515 self.rhs = self.rhs.coerce_to_temp(env)
3517 self.rhs = self.rhs.coerce_to_simple(env)
3518 from ExprNodes import CloneNode
3519 self.coerced_rhs_list = []
3520 for lhs in self.lhs_list:
3521 lhs.analyse_target_types(env)
3522 lhs.gil_assignment_check(env)
3523 rhs = CloneNode(self.rhs)
3524 rhs = rhs.coerce_to(lhs.type, env)
3525 self.coerced_rhs_list.append(rhs)
3527 def generate_rhs_evaluation_code(self, code):
3528 self.rhs.generate_evaluation_code(code)
3530 def generate_assignment_code(self, code):
3531 for i in range(len(self.lhs_list)):
3532 lhs = self.lhs_list[i]
3533 rhs = self.coerced_rhs_list[i]
3534 rhs.generate_evaluation_code(code)
3535 lhs.generate_assignment_code(rhs, code)
3536 # Assignment has disposed of the cloned RHS
3537 self.rhs.generate_disposal_code(code)
3538 self.rhs.free_temps(code)
3540 def generate_function_definitions(self, env, code):
3541 self.rhs.generate_function_definitions(env, code)
3543 def annotate(self, code):
3544 for i in range(len(self.lhs_list)):
3545 lhs = self.lhs_list[i].annotate(code)
3546 rhs = self.coerced_rhs_list[i].annotate(code)
3547 self.rhs.annotate(code)
3550 class ParallelAssignmentNode(AssignmentNode):
3551 # A combined packing/unpacking assignment:
3555 # This has been rearranged by the parser into
3557 # a = d ; b = e ; c = f
3559 # but we must evaluate all the right hand sides
3560 # before assigning to any of the left hand sides.
3562 # stats [AssignmentNode] The constituent assignments
3564 child_attrs = ["stats"]
3566 def analyse_declarations(self, env):
3567 for stat in self.stats:
3568 stat.analyse_declarations(env)
3570 def analyse_expressions(self, env):
3571 for stat in self.stats:
3572 stat.analyse_types(env, use_temp = 1)
3574 # def analyse_expressions(self, env):
3575 # for stat in self.stats:
3576 # stat.analyse_expressions_1(env, use_temp = 1)
3577 # for stat in self.stats:
3578 # stat.analyse_expressions_2(env)
3580 def generate_execution_code(self, code):
3581 for stat in self.stats:
3582 stat.generate_rhs_evaluation_code(code)
3583 for stat in self.stats:
3584 stat.generate_assignment_code(code)
3586 def generate_function_definitions(self, env, code):
3587 for stat in self.stats:
3588 stat.generate_function_definitions(env, code)
3590 def annotate(self, code):
3591 for stat in self.stats:
3595 class InPlaceAssignmentNode(AssignmentNode):
3596 # An in place arithmetic operand:
3602 # lhs ExprNode Left hand side
3603 # rhs ExprNode Right hand side
3604 # op char one of "+-*/%^&|"
3605 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3607 # This code is a bit tricky because in order to obey Python
3608 # semantics the sub-expressions (e.g. indices) of the lhs must
3609 # not be evaluated twice. So we must re-use the values calculated
3610 # in evaluation phase for the assignment phase as well.
3611 # Fortunately, the type of the lhs node is fairly constrained
3612 # (it must be a NameNode, AttributeNode, or IndexNode).
3614 child_attrs = ["lhs", "rhs"]
3616 def analyse_declarations(self, env):
3617 self.lhs.analyse_target_declaration(env)
3619 def analyse_types(self, env):
3620 self.rhs.analyse_types(env)
3621 self.lhs.analyse_target_types(env)
3623 def generate_execution_code(self, code):
3625 self.rhs.generate_evaluation_code(code)
3626 self.lhs.generate_subexpr_evaluation_code(code)
3627 c_op = self.operator
3631 error(self.pos, "No C inplace power operator")
3632 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3633 if self.lhs.type.is_pyobject:
3634 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3635 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3636 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3637 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3640 # TODO: make sure overload is declared
3641 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3642 self.lhs.generate_subexpr_disposal_code(code)
3643 self.lhs.free_subexpr_temps(code)
3644 self.rhs.generate_disposal_code(code)
3645 self.rhs.free_temps(code)
3647 def annotate(self, code):
3648 self.lhs.annotate(code)
3649 self.rhs.annotate(code)
3651 def create_binop_node(self):
3653 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3656 class PrintStatNode(StatNode):
3659 # arg_tuple TupleNode
3660 # stream ExprNode or None (stdout)
3661 # append_newline boolean
3663 child_attrs = ["arg_tuple", "stream"]
3665 def analyse_expressions(self, env):
3667 self.stream.analyse_expressions(env)
3668 self.stream = self.stream.coerce_to_pyobject(env)
3669 self.arg_tuple.analyse_expressions(env)
3670 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3671 env.use_utility_code(printing_utility_code)
3672 if len(self.arg_tuple.args) == 1 and self.append_newline:
3673 env.use_utility_code(printing_one_utility_code)
3675 nogil_check = Node.gil_error
3676 gil_message = "Python print statement"
3678 def generate_execution_code(self, code):
3680 self.stream.generate_evaluation_code(code)
3681 stream_result = self.stream.py_result()
3684 if len(self.arg_tuple.args) == 1 and self.append_newline:
3685 arg = self.arg_tuple.args[0]
3686 arg.generate_evaluation_code(code)
3689 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3692 code.error_goto(self.pos)))
3693 arg.generate_disposal_code(code)
3694 arg.free_temps(code)
3696 self.arg_tuple.generate_evaluation_code(code)
3698 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3700 self.arg_tuple.py_result(),
3701 self.append_newline,
3702 code.error_goto(self.pos)))
3703 self.arg_tuple.generate_disposal_code(code)
3704 self.arg_tuple.free_temps(code)
3707 self.stream.generate_disposal_code(code)
3708 self.stream.free_temps(code)
3710 def generate_function_definitions(self, env, code):
3712 self.stream.generate_function_definitions(env, code)
3713 self.arg_tuple.generate_function_definitions(env, code)
3715 def annotate(self, code):
3717 self.stream.annotate(code)
3718 self.arg_tuple.annotate(code)
3721 class ExecStatNode(StatNode):
3726 child_attrs = ["args"]
3728 def analyse_expressions(self, env):
3729 for i, arg in enumerate(self.args):
3730 arg.analyse_expressions(env)
3731 arg = arg.coerce_to_pyobject(env)
3733 env.use_utility_code(Builtin.pyexec_utility_code)
3735 nogil_check = Node.gil_error
3736 gil_message = "Python exec statement"
3738 def generate_execution_code(self, code):
3740 for arg in self.args:
3741 arg.generate_evaluation_code(code)
3742 args.append( arg.py_result() )
3743 args = tuple(args + ['0', '0'][:3-len(args)])
3744 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3745 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3746 (temp_result,) + args))
3747 for arg in self.args:
3748 arg.generate_disposal_code(code)
3749 arg.free_temps(code)
3751 code.error_goto_if_null(temp_result, self.pos))
3752 code.put_gotref(temp_result)
3753 code.put_decref_clear(temp_result, py_object_type)
3754 code.funcstate.release_temp(temp_result)
3756 def annotate(self, code):
3757 for arg in self.args:
3761 class DelStatNode(StatNode):
3766 child_attrs = ["args"]
3768 def analyse_declarations(self, env):
3769 for arg in self.args:
3770 arg.analyse_target_declaration(env)
3772 def analyse_expressions(self, env):
3773 for arg in self.args:
3774 arg.analyse_target_expression(env, None)
3775 if arg.type.is_pyobject:
3777 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3779 elif arg.type.is_cpp_class:
3780 error(arg.pos, "Deletion of non-heap C++ object")
3782 error(arg.pos, "Deletion of non-Python, non-C++ object")
3783 #arg.release_target_temp(env)
3785 def nogil_check(self, env):
3786 for arg in self.args:
3787 if arg.type.is_pyobject:
3790 gil_message = "Deleting Python object"
3792 def generate_execution_code(self, code):
3793 for arg in self.args:
3794 if arg.type.is_pyobject:
3795 arg.generate_deletion_code(code)
3796 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3797 arg.generate_result_code(code)
3798 code.putln("delete %s;" % arg.result())
3799 # else error reported earlier
3801 def annotate(self, code):
3802 for arg in self.args:
3806 class PassStatNode(StatNode):
3811 def analyse_expressions(self, env):
3814 def generate_execution_code(self, code):
3818 class BreakStatNode(StatNode):
3822 def analyse_expressions(self, env):
3825 def generate_execution_code(self, code):
3826 if not code.break_label:
3827 error(self.pos, "break statement not inside loop")
3829 code.put_goto(code.break_label)
3832 class ContinueStatNode(StatNode):
3836 def analyse_expressions(self, env):
3839 def generate_execution_code(self, code):
3840 if code.funcstate.in_try_finally:
3841 error(self.pos, "continue statement inside try of try...finally")
3842 elif not code.continue_label:
3843 error(self.pos, "continue statement not inside loop")
3845 code.put_goto(code.continue_label)
3848 class ReturnStatNode(StatNode):
3851 # value ExprNode or None
3852 # return_type PyrexType
3854 child_attrs = ["value"]
3856 def analyse_expressions(self, env):
3857 return_type = env.return_type
3858 self.return_type = return_type
3860 error(self.pos, "Return not inside a function body")
3863 self.value.analyse_types(env)
3864 if return_type.is_void or return_type.is_returncode:
3865 error(self.value.pos,
3866 "Return with value in void function")
3868 self.value = self.value.coerce_to(env.return_type, env)
3870 if (not return_type.is_void
3871 and not return_type.is_pyobject
3872 and not return_type.is_returncode):
3873 error(self.pos, "Return value required")
3875 def nogil_check(self, env):
3876 if self.return_type.is_pyobject:
3879 gil_message = "Returning Python object"
3881 def generate_execution_code(self, code):
3882 code.mark_pos(self.pos)
3883 if not self.return_type:
3884 # error reported earlier
3886 if self.return_type.is_pyobject:
3887 code.put_xdecref(Naming.retval_cname,
3890 self.value.generate_evaluation_code(code)
3891 self.value.make_owned_reference(code)
3894 Naming.retval_cname,
3895 self.value.result_as(self.return_type)))
3896 self.value.generate_post_assignment_code(code)
3897 self.value.free_temps(code)
3899 if self.return_type.is_pyobject:
3900 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3901 elif self.return_type.is_returncode:
3904 Naming.retval_cname,
3905 self.return_type.default_value))
3906 for cname, type in code.funcstate.temps_holding_reference():
3907 code.put_decref_clear(cname, type)
3908 code.put_goto(code.return_label)
3910 def generate_function_definitions(self, env, code):
3911 if self.value is not None:
3912 self.value.generate_function_definitions(env, code)
3914 def annotate(self, code):
3916 self.value.annotate(code)
3919 class RaiseStatNode(StatNode):
3922 # exc_type ExprNode or None
3923 # exc_value ExprNode or None
3924 # exc_tb ExprNode or None
3926 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3928 def analyse_expressions(self, env):
3930 self.exc_type.analyse_types(env)
3931 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3933 self.exc_value.analyse_types(env)
3934 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3936 self.exc_tb.analyse_types(env)
3937 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3938 # special cases for builtin exceptions
3939 self.builtin_exc_name = None
3940 if self.exc_type and not self.exc_value and not self.exc_tb:
3943 if isinstance(exc, ExprNodes.SimpleCallNode) and not exc.args:
3944 exc = exc.function # extract the exception type
3945 if exc.is_name and exc.entry.is_builtin:
3946 self.builtin_exc_name = exc.name
3947 if self.builtin_exc_name == 'MemoryError':
3948 self.exc_type = None # has a separate implementation
3950 nogil_check = Node.gil_error
3951 gil_message = "Raising exception"
3953 def generate_execution_code(self, code):
3954 if self.builtin_exc_name == 'MemoryError':
3955 code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
3959 self.exc_type.generate_evaluation_code(code)
3960 type_code = self.exc_type.py_result()
3964 self.exc_value.generate_evaluation_code(code)
3965 value_code = self.exc_value.py_result()
3969 self.exc_tb.generate_evaluation_code(code)
3970 tb_code = self.exc_tb.py_result()
3973 code.globalstate.use_utility_code(raise_utility_code)
3975 "__Pyx_Raise(%s, %s, %s);" % (
3979 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3981 obj.generate_disposal_code(code)
3982 obj.free_temps(code)
3984 code.error_goto(self.pos))
3986 def generate_function_definitions(self, env, code):
3987 if self.exc_type is not None:
3988 self.exc_type.generate_function_definitions(env, code)
3989 if self.exc_value is not None:
3990 self.exc_value.generate_function_definitions(env, code)
3991 if self.exc_tb is not None:
3992 self.exc_tb.generate_function_definitions(env, code)
3994 def annotate(self, code):
3996 self.exc_type.annotate(code)
3998 self.exc_value.annotate(code)
4000 self.exc_tb.annotate(code)
4003 class ReraiseStatNode(StatNode):
4007 def analyse_expressions(self, env):
4008 env.use_utility_code(restore_exception_utility_code)
4010 nogil_check = Node.gil_error
4011 gil_message = "Raising exception"
4013 def generate_execution_code(self, code):
4014 vars = code.funcstate.exc_vars
4016 for varname in vars:
4017 code.put_giveref(varname)
4018 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4019 for varname in vars:
4020 code.put("%s = 0; " % varname)
4022 code.putln(code.error_goto(self.pos))
4024 error(self.pos, "Reraise not inside except clause")
4027 class AssertStatNode(StatNode):
4031 # value ExprNode or None
4033 child_attrs = ["cond", "value"]
4035 def analyse_expressions(self, env):
4036 self.cond = self.cond.analyse_boolean_expression(env)
4038 self.value.analyse_types(env)
4039 self.value = self.value.coerce_to_pyobject(env)
4041 nogil_check = Node.gil_error
4042 gil_message = "Raising exception"
4044 def generate_execution_code(self, code):
4045 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4046 self.cond.generate_evaluation_code(code)
4048 "if (unlikely(!%s)) {" %
4051 self.value.generate_evaluation_code(code)
4053 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4054 self.value.py_result())
4055 self.value.generate_disposal_code(code)
4056 self.value.free_temps(code)
4059 "PyErr_SetNone(PyExc_AssertionError);")
4061 code.error_goto(self.pos))
4064 self.cond.generate_disposal_code(code)
4065 self.cond.free_temps(code)
4066 code.putln("#endif")
4068 def generate_function_definitions(self, env, code):
4069 self.cond.generate_function_definitions(env, code)
4070 if self.value is not None:
4071 self.value.generate_function_definitions(env, code)
4073 def annotate(self, code):
4074 self.cond.annotate(code)
4076 self.value.annotate(code)
4079 class IfStatNode(StatNode):
4082 # if_clauses [IfClauseNode]
4083 # else_clause StatNode or None
4085 child_attrs = ["if_clauses", "else_clause"]
4087 def analyse_control_flow(self, env):
4088 env.start_branching(self.pos)
4089 for if_clause in self.if_clauses:
4090 if_clause.analyse_control_flow(env)
4091 env.next_branch(if_clause.end_pos())
4092 if self.else_clause:
4093 self.else_clause.analyse_control_flow(env)
4094 env.finish_branching(self.end_pos())
4096 def analyse_declarations(self, env):
4097 for if_clause in self.if_clauses:
4098 if_clause.analyse_declarations(env)
4099 if self.else_clause:
4100 self.else_clause.analyse_declarations(env)
4102 def analyse_expressions(self, env):
4103 for if_clause in self.if_clauses:
4104 if_clause.analyse_expressions(env)
4105 if self.else_clause:
4106 self.else_clause.analyse_expressions(env)
4108 def generate_execution_code(self, code):
4109 code.mark_pos(self.pos)
4110 end_label = code.new_label()
4111 for if_clause in self.if_clauses:
4112 if_clause.generate_execution_code(code, end_label)
4113 if self.else_clause:
4114 code.putln("/*else*/ {")
4115 self.else_clause.generate_execution_code(code)
4117 code.put_label(end_label)
4119 def generate_function_definitions(self, env, code):
4120 for clause in self.if_clauses:
4121 clause.generate_function_definitions(env, code)
4122 if self.else_clause is not None:
4123 self.else_clause.generate_function_definitions(env, code)
4125 def annotate(self, code):
4126 for if_clause in self.if_clauses:
4127 if_clause.annotate(code)
4128 if self.else_clause:
4129 self.else_clause.annotate(code)
4132 class IfClauseNode(Node):
4133 # if or elif clause in an if statement
4135 # condition ExprNode
4138 child_attrs = ["condition", "body"]
4140 def analyse_control_flow(self, env):
4141 self.body.analyse_control_flow(env)
4143 def analyse_declarations(self, env):
4144 self.body.analyse_declarations(env)
4146 def analyse_expressions(self, env):
4148 self.condition.analyse_temp_boolean_expression(env)
4149 self.body.analyse_expressions(env)
4151 def get_constant_condition_result(self):
4152 if self.condition.has_constant_result():
4153 return bool(self.condition.constant_result)
4157 def generate_execution_code(self, code, end_label):
4158 self.condition.generate_evaluation_code(code)
4161 self.condition.result())
4162 self.condition.generate_disposal_code(code)
4163 self.condition.free_temps(code)
4164 self.body.generate_execution_code(code)
4165 code.put_goto(end_label)
4168 def generate_function_definitions(self, env, code):
4169 self.condition.generate_function_definitions(env, code)
4170 self.body.generate_function_definitions(env, code)
4172 def annotate(self, code):
4173 self.condition.annotate(code)
4174 self.body.annotate(code)
4177 class SwitchCaseNode(StatNode):
4178 # Generated in the optimization of an if-elif-else node
4180 # conditions [ExprNode]
4183 child_attrs = ['conditions', 'body']
4185 def generate_execution_code(self, code):
4186 for cond in self.conditions:
4187 code.mark_pos(cond.pos)
4188 cond.generate_evaluation_code(code)
4189 code.putln("case %s:" % cond.result())
4190 self.body.generate_execution_code(code)
4191 code.putln("break;")
4193 def generate_function_definitions(self, env, code):
4194 for cond in self.conditions:
4195 cond.generate_function_definitions(env, code)
4196 self.body.generate_function_definitions(env, code)
4198 def annotate(self, code):
4199 for cond in self.conditions:
4201 self.body.annotate(code)
4203 class SwitchStatNode(StatNode):
4204 # Generated in the optimization of an if-elif-else node
4207 # cases [SwitchCaseNode]
4208 # else_clause StatNode or None
4210 child_attrs = ['test', 'cases', 'else_clause']
4212 def generate_execution_code(self, code):
4213 self.test.generate_evaluation_code(code)
4214 code.putln("switch (%s) {" % self.test.result())
4215 for case in self.cases:
4216 case.generate_execution_code(code)
4217 if self.else_clause is not None:
4218 code.putln("default:")
4219 self.else_clause.generate_execution_code(code)
4220 code.putln("break;")
4223 def generate_function_definitions(self, env, code):
4224 self.test.generate_function_definitions(env, code)
4225 for case in self.cases:
4226 case.generate_function_definitions(env, code)
4227 if self.else_clause is not None:
4228 self.else_clause.generate_function_definitions(env, code)
4230 def annotate(self, code):
4231 self.test.annotate(code)
4232 for case in self.cases:
4234 if self.else_clause is not None:
4235 self.else_clause.annotate(code)
4237 class LoopNode(object):
4239 def analyse_control_flow(self, env):
4240 env.start_branching(self.pos)
4241 self.body.analyse_control_flow(env)
4242 env.next_branch(self.body.end_pos())
4243 if self.else_clause:
4244 self.else_clause.analyse_control_flow(env)
4245 env.finish_branching(self.end_pos())
4248 class WhileStatNode(LoopNode, StatNode):
4251 # condition ExprNode
4253 # else_clause StatNode
4255 child_attrs = ["condition", "body", "else_clause"]
4257 def analyse_declarations(self, env):
4258 self.body.analyse_declarations(env)
4259 if self.else_clause:
4260 self.else_clause.analyse_declarations(env)
4262 def analyse_expressions(self, env):
4264 self.condition.analyse_temp_boolean_expression(env)
4265 self.body.analyse_expressions(env)
4266 if self.else_clause:
4267 self.else_clause.analyse_expressions(env)
4269 def generate_execution_code(self, code):
4270 old_loop_labels = code.new_loop_labels()
4273 self.condition.generate_evaluation_code(code)
4274 self.condition.generate_disposal_code(code)
4277 self.condition.result())
4278 self.condition.free_temps(code)
4279 self.body.generate_execution_code(code)
4280 code.put_label(code.continue_label)
4282 break_label = code.break_label
4283 code.set_loop_labels(old_loop_labels)
4284 if self.else_clause:
4285 code.putln("/*else*/ {")
4286 self.else_clause.generate_execution_code(code)
4288 code.put_label(break_label)
4290 def generate_function_definitions(self, env, code):
4291 self.condition.generate_function_definitions(env, code)
4292 self.body.generate_function_definitions(env, code)
4293 if self.else_clause is not None:
4294 self.else_clause.generate_function_definitions(env, code)
4296 def annotate(self, code):
4297 self.condition.annotate(code)
4298 self.body.annotate(code)
4299 if self.else_clause:
4300 self.else_clause.annotate(code)
4303 def ForStatNode(pos, **kw):
4304 if 'iterator' in kw:
4305 return ForInStatNode(pos, **kw)
4307 return ForFromStatNode(pos, **kw)
4309 class ForInStatNode(LoopNode, StatNode):
4313 # iterator IteratorNode
4315 # else_clause StatNode
4316 # item NextNode used internally
4318 child_attrs = ["target", "iterator", "body", "else_clause"]
4321 def analyse_declarations(self, env):
4322 self.target.analyse_target_declaration(env)
4323 self.body.analyse_declarations(env)
4324 if self.else_clause:
4325 self.else_clause.analyse_declarations(env)
4327 def analyse_expressions(self, env):
4329 self.target.analyse_target_types(env)
4330 self.iterator.analyse_expressions(env)
4331 self.item = ExprNodes.NextNode(self.iterator, env)
4332 self.item = self.item.coerce_to(self.target.type, env)
4333 self.body.analyse_expressions(env)
4334 if self.else_clause:
4335 self.else_clause.analyse_expressions(env)
4337 def generate_execution_code(self, code):
4338 old_loop_labels = code.new_loop_labels()
4339 self.iterator.allocate_counter_temp(code)
4340 self.iterator.generate_evaluation_code(code)
4343 self.item.generate_evaluation_code(code)
4344 self.target.generate_assignment_code(self.item, code)
4345 self.body.generate_execution_code(code)
4346 code.put_label(code.continue_label)
4349 break_label = code.break_label
4350 code.set_loop_labels(old_loop_labels)
4352 if self.else_clause:
4353 # in nested loops, the 'else' block can contain a
4354 # 'continue' statement for the outer loop, but we may need
4355 # to generate cleanup code before taking that path, so we
4357 orig_continue_label = code.continue_label
4358 code.continue_label = code.new_label('outer_continue')
4360 code.putln("/*else*/ {")
4361 self.else_clause.generate_execution_code(code)
4364 if code.label_used(code.continue_label):
4365 code.put_goto(break_label)
4366 code.put_label(code.continue_label)
4367 self.iterator.generate_disposal_code(code)
4368 code.put_goto(orig_continue_label)
4369 code.set_loop_labels(old_loop_labels)
4371 if code.label_used(break_label):
4372 code.put_label(break_label)
4373 self.iterator.release_counter_temp(code)
4374 self.iterator.generate_disposal_code(code)
4375 self.iterator.free_temps(code)
4377 def generate_function_definitions(self, env, code):
4378 self.target.generate_function_definitions(env, code)
4379 self.iterator.generate_function_definitions(env, code)
4380 self.body.generate_function_definitions(env, code)
4381 if self.else_clause is not None:
4382 self.else_clause.generate_function_definitions(env, code)
4384 def annotate(self, code):
4385 self.target.annotate(code)
4386 self.iterator.annotate(code)
4387 self.body.annotate(code)
4388 if self.else_clause:
4389 self.else_clause.annotate(code)
4390 self.item.annotate(code)
4393 class ForFromStatNode(LoopNode, StatNode):
4394 # for name from expr rel name rel expr
4401 # step ExprNode or None
4403 # else_clause StatNode or None
4409 # loopvar_node ExprNode (usually a NameNode or temp node)
4410 # py_loopvar_node PyTempNode or None
4411 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4413 is_py_target = False
4415 py_loopvar_node = None
4418 gil_message = "For-loop using object bounds or target"
4420 def nogil_check(self, env):
4421 for x in (self.target, self.bound1, self.bound2):
4422 if x.type.is_pyobject:
4425 def analyse_declarations(self, env):
4426 self.target.analyse_target_declaration(env)
4427 self.body.analyse_declarations(env)
4428 if self.else_clause:
4429 self.else_clause.analyse_declarations(env)
4431 def analyse_expressions(self, env):
4433 self.target.analyse_target_types(env)
4434 self.bound1.analyse_types(env)
4435 self.bound2.analyse_types(env)
4436 if self.step is not None:
4437 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4438 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4439 self.step.analyse_types(env)
4441 target_type = self.target.type
4442 if self.target.type.is_numeric:
4443 loop_type = self.target.type
4445 loop_type = PyrexTypes.c_int_type
4446 if not self.bound1.type.is_pyobject:
4447 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4448 if not self.bound2.type.is_pyobject:
4449 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4450 if self.step is not None and not self.step.type.is_pyobject:
4451 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4452 self.bound1 = self.bound1.coerce_to(loop_type, env)
4453 self.bound2 = self.bound2.coerce_to(loop_type, env)
4454 if not self.bound2.is_literal:
4455 self.bound2 = self.bound2.coerce_to_temp(env)
4456 if self.step is not None:
4457 self.step = self.step.coerce_to(loop_type, env)
4458 if not self.step.is_literal:
4459 self.step = self.step.coerce_to_temp(env)
4461 target_type = self.target.type
4462 if not (target_type.is_pyobject or target_type.is_numeric):
4463 error(self.target.pos,
4464 "for-from loop variable must be c numeric type or Python object")
4465 if target_type.is_numeric:
4466 self.is_py_target = False
4467 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4468 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4469 self.loopvar_node = self.target
4470 self.py_loopvar_node = None
4472 self.is_py_target = True
4473 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4474 self.loopvar_node = c_loopvar_node
4475 self.py_loopvar_node = \
4476 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4477 self.body.analyse_expressions(env)
4478 if self.else_clause:
4479 self.else_clause.analyse_expressions(env)
4481 def generate_execution_code(self, code):
4482 old_loop_labels = code.new_loop_labels()
4483 from_range = self.from_range
4484 self.bound1.generate_evaluation_code(code)
4485 self.bound2.generate_evaluation_code(code)
4486 offset, incop = self.relation_table[self.relation1]
4487 if self.step is not None:
4488 self.step.generate_evaluation_code(code)
4489 step = self.step.result()
4490 incop = "%s=%s" % (incop[0], step)
4492 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4493 self.loopvar_node.allocate(code)
4494 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4495 self.py_loopvar_node.allocate(code)
4497 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4499 loopvar_name = self.loopvar_node.result()
4501 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4503 self.bound1.result(), offset,
4504 loopvar_name, self.relation2, self.bound2.result(),
4505 loopvar_name, incop))
4506 if self.py_loopvar_node:
4507 self.py_loopvar_node.generate_evaluation_code(code)
4508 self.target.generate_assignment_code(self.py_loopvar_node, code)
4510 code.putln("%s = %s;" % (
4511 self.target.result(), loopvar_name))
4512 self.body.generate_execution_code(code)
4513 code.put_label(code.continue_label)
4514 if self.py_loopvar_node:
4515 # This mess is to make for..from loops with python targets behave
4516 # exactly like those with C targets with regards to re-assignment
4517 # of the loop variable.
4519 if self.target.entry.is_pyglobal:
4520 # We know target is a NameNode, this is the only ugly case.
4521 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4522 target_node.allocate(code)
4523 interned_cname = code.intern_identifier(self.target.entry.name)
4524 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4525 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4526 target_node.result(),
4527 Naming.module_cname,
4529 code.error_goto_if_null(target_node.result(), self.target.pos)))
4530 code.put_gotref(target_node.result())
4532 target_node = self.target
4533 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4534 from_py_node.temp_code = loopvar_name
4535 from_py_node.generate_result_code(code)
4536 if self.target.entry.is_pyglobal:
4537 code.put_decref(target_node.result(), target_node.type)
4538 target_node.release(code)
4540 if self.py_loopvar_node:
4541 # This is potentially wasteful, but we don't want the semantics to
4542 # depend on whether or not the loop is a python type.
4543 self.py_loopvar_node.generate_evaluation_code(code)
4544 self.target.generate_assignment_code(self.py_loopvar_node, code)
4546 code.funcstate.release_temp(loopvar_name)
4547 break_label = code.break_label
4548 code.set_loop_labels(old_loop_labels)
4549 if self.else_clause:
4550 code.putln("/*else*/ {")
4551 self.else_clause.generate_execution_code(code)
4553 code.put_label(break_label)
4554 self.bound1.generate_disposal_code(code)
4555 self.bound1.free_temps(code)
4556 self.bound2.generate_disposal_code(code)
4557 self.bound2.free_temps(code)
4558 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4559 self.loopvar_node.release(code)
4560 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4561 self.py_loopvar_node.release(code)
4562 if self.step is not None:
4563 self.step.generate_disposal_code(code)
4564 self.step.free_temps(code)
4567 # {relop : (initial offset, increment op)}
4574 def generate_function_definitions(self, env, code):
4575 self.target.generate_function_definitions(env, code)
4576 self.bound1.generate_function_definitions(env, code)
4577 self.bound2.generate_function_definitions(env, code)
4578 if self.step is not None:
4579 self.step.generate_function_definitions(env, code)
4580 self.body.generate_function_definitions(env, code)
4581 if self.else_clause is not None:
4582 self.else_clause.generate_function_definitions(env, code)
4584 def annotate(self, code):
4585 self.target.annotate(code)
4586 self.bound1.annotate(code)
4587 self.bound2.annotate(code)
4589 self.step.annotate(code)
4590 self.body.annotate(code)
4591 if self.else_clause:
4592 self.else_clause.annotate(code)
4595 class WithStatNode(StatNode):
4597 Represents a Python with statement.
4599 This is only used at parse tree level; and is not present in
4600 analysis or generation phases.
4602 # manager The with statement manager object
4603 # target Node (lhs expression)
4605 child_attrs = ["manager", "target", "body"]
4607 class TryExceptStatNode(StatNode):
4608 # try .. except statement
4611 # except_clauses [ExceptClauseNode]
4612 # else_clause StatNode or None
4614 child_attrs = ["body", "except_clauses", "else_clause"]
4616 def analyse_control_flow(self, env):
4617 env.start_branching(self.pos)
4618 self.body.analyse_control_flow(env)
4619 successful_try = env.control_flow # grab this for later
4620 env.next_branch(self.body.end_pos())
4621 env.finish_branching(self.body.end_pos())
4623 env.start_branching(self.except_clauses[0].pos)
4624 for except_clause in self.except_clauses:
4625 except_clause.analyse_control_flow(env)
4626 env.next_branch(except_clause.end_pos())
4628 # the else cause it executed only when the try clause finishes
4629 env.control_flow.incoming = successful_try
4630 if self.else_clause:
4631 self.else_clause.analyse_control_flow(env)
4632 env.finish_branching(self.end_pos())
4634 def analyse_declarations(self, env):
4635 self.body.analyse_declarations(env)
4636 for except_clause in self.except_clauses:
4637 except_clause.analyse_declarations(env)
4638 if self.else_clause:
4639 self.else_clause.analyse_declarations(env)
4640 env.use_utility_code(reset_exception_utility_code)
4642 def analyse_expressions(self, env):
4643 self.body.analyse_expressions(env)
4644 default_clause_seen = 0
4645 for except_clause in self.except_clauses:
4646 except_clause.analyse_expressions(env)
4647 if default_clause_seen:
4648 error(except_clause.pos, "default 'except:' must be last")
4649 if not except_clause.pattern:
4650 default_clause_seen = 1
4651 self.has_default_clause = default_clause_seen
4652 if self.else_clause:
4653 self.else_clause.analyse_expressions(env)
4655 nogil_check = Node.gil_error
4656 gil_message = "Try-except statement"
4658 def generate_execution_code(self, code):
4659 old_return_label = code.return_label
4660 old_break_label = code.break_label
4661 old_continue_label = code.continue_label
4662 old_error_label = code.new_error_label()
4663 our_error_label = code.error_label
4664 except_end_label = code.new_label('exception_handled')
4665 except_error_label = code.new_label('except_error')
4666 except_return_label = code.new_label('except_return')
4667 try_return_label = code.new_label('try_return')
4668 try_break_label = code.new_label('try_break')
4669 try_continue_label = code.new_label('try_continue')
4670 try_end_label = code.new_label('try_end')
4673 code.putln("PyObject %s;" %
4674 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4675 code.putln("__Pyx_ExceptionSave(%s);" %
4676 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4677 for var in Naming.exc_save_vars:
4678 code.put_xgotref(var)
4681 code.return_label = try_return_label
4682 code.break_label = try_break_label
4683 code.continue_label = try_continue_label
4684 self.body.generate_execution_code(code)
4687 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4688 code.error_label = except_error_label
4689 code.return_label = except_return_label
4690 if self.else_clause:
4693 self.else_clause.generate_execution_code(code)
4696 for var in Naming.exc_save_vars:
4697 code.put_xdecref_clear(var, py_object_type)
4698 code.put_goto(try_end_label)
4699 if code.label_used(try_return_label):
4700 code.put_label(try_return_label)
4701 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4702 code.putln("__Pyx_ExceptionReset(%s);" %
4703 ', '.join(Naming.exc_save_vars))
4704 code.put_goto(old_return_label)
4705 code.put_label(our_error_label)
4706 for temp_name, type in temps_to_clean_up:
4707 code.put_xdecref_clear(temp_name, type)
4708 for except_clause in self.except_clauses:
4709 except_clause.generate_handling_code(code, except_end_label)
4711 error_label_used = code.label_used(except_error_label)
4712 if error_label_used or not self.has_default_clause:
4713 if error_label_used:
4714 code.put_label(except_error_label)
4715 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4716 code.putln("__Pyx_ExceptionReset(%s);" %
4717 ', '.join(Naming.exc_save_vars))
4718 code.put_goto(old_error_label)
4720 for exit_label, old_label in zip(
4721 [try_break_label, try_continue_label, except_return_label],
4722 [old_break_label, old_continue_label, old_return_label]):
4724 if code.label_used(exit_label):
4725 code.put_label(exit_label)
4726 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4727 code.putln("__Pyx_ExceptionReset(%s);" %
4728 ', '.join(Naming.exc_save_vars))
4729 code.put_goto(old_label)
4731 if code.label_used(except_end_label):
4732 code.put_label(except_end_label)
4733 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4734 code.putln("__Pyx_ExceptionReset(%s);" %
4735 ', '.join(Naming.exc_save_vars))
4736 code.put_label(try_end_label)
4739 code.return_label = old_return_label
4740 code.break_label = old_break_label
4741 code.continue_label = old_continue_label
4742 code.error_label = old_error_label
4744 def generate_function_definitions(self, env, code):
4745 self.body.generate_function_definitions(env, code)
4746 for except_clause in self.except_clauses:
4747 except_clause.generate_function_definitions(env, code)
4748 if self.else_clause is not None:
4749 self.else_clause.generate_function_definitions(env, code)
4751 def annotate(self, code):
4752 self.body.annotate(code)
4753 for except_node in self.except_clauses:
4754 except_node.annotate(code)
4755 if self.else_clause:
4756 self.else_clause.annotate(code)
4759 class ExceptClauseNode(Node):
4760 # Part of try ... except statement.
4762 # pattern [ExprNode]
4763 # target ExprNode or None
4765 # excinfo_target NameNode or None optional target for exception info
4766 # match_flag string result of exception match
4767 # exc_value ExcValueNode used internally
4768 # function_name string qualified name of enclosing function
4769 # exc_vars (string * 3) local exception variables
4771 # excinfo_target is never set by the parser, but can be set by a transform
4772 # in order to extract more extensive information about the exception as a
4773 # sys.exc_info()-style tuple into a target variable
4775 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4778 excinfo_target = None
4780 def analyse_declarations(self, env):
4782 self.target.analyse_target_declaration(env)
4783 if self.excinfo_target is not None:
4784 self.excinfo_target.analyse_target_declaration(env)
4785 self.body.analyse_declarations(env)
4787 def analyse_expressions(self, env):
4789 genv = env.global_scope()
4790 self.function_name = env.qualified_name
4792 # normalise/unpack self.pattern into a list
4793 for i, pattern in enumerate(self.pattern):
4794 pattern.analyse_expressions(env)
4795 self.pattern[i] = pattern.coerce_to_pyobject(env)
4798 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4799 self.target.analyse_target_expression(env, self.exc_value)
4800 if self.excinfo_target is not None:
4802 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4803 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4804 self.excinfo_tuple.analyse_expressions(env)
4805 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4807 self.body.analyse_expressions(env)
4809 def generate_handling_code(self, code, end_label):
4810 code.mark_pos(self.pos)
4813 for pattern in self.pattern:
4814 pattern.generate_evaluation_code(code)
4815 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4817 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4819 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4820 for pattern in self.pattern:
4821 pattern.generate_disposal_code(code)
4822 pattern.free_temps(code)
4826 code.funcstate.release_temp(match_flag)
4828 code.putln("/*except:*/ {")
4830 if not getattr(self.body, 'stats', True) and \
4831 self.excinfo_target is None and self.target is None:
4832 # most simple case: no exception variable, empty body (pass)
4833 # => reset the exception state, done
4834 code.putln("PyErr_Restore(0,0,0);")
4835 code.put_goto(end_label)
4839 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4842 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4843 # We always have to fetch the exception value even if
4844 # there is no target, because this also normalises the
4845 # exception and stores it in the thread state.
4846 code.globalstate.use_utility_code(get_exception_utility_code)
4847 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4848 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4849 code.error_goto(self.pos)))
4853 self.exc_value.set_var(exc_vars[1])
4854 self.exc_value.generate_evaluation_code(code)
4855 self.target.generate_assignment_code(self.exc_value, code)
4856 if self.excinfo_target is not None:
4857 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4858 node.set_var(tempvar)
4859 self.excinfo_tuple.generate_evaluation_code(code)
4860 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4862 old_break_label, old_continue_label = code.break_label, code.continue_label
4863 code.break_label = code.new_label('except_break')
4864 code.continue_label = code.new_label('except_continue')
4866 old_exc_vars = code.funcstate.exc_vars
4867 code.funcstate.exc_vars = exc_vars
4868 self.body.generate_execution_code(code)
4869 code.funcstate.exc_vars = old_exc_vars
4870 for var in exc_vars:
4871 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4872 code.put_goto(end_label)
4874 if code.label_used(code.break_label):
4875 code.put_label(code.break_label)
4876 for var in exc_vars:
4877 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4878 code.put_goto(old_break_label)
4879 code.break_label = old_break_label
4881 if code.label_used(code.continue_label):
4882 code.put_label(code.continue_label)
4883 for var in exc_vars:
4884 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4885 code.put_goto(old_continue_label)
4886 code.continue_label = old_continue_label
4888 for temp in exc_vars:
4889 code.funcstate.release_temp(temp)
4894 def generate_function_definitions(self, env, code):
4895 if self.target is not None:
4896 self.target.generate_function_definitions(env, code)
4897 self.body.generate_function_definitions(env, code)
4899 def annotate(self, code):
4901 for pattern in self.pattern:
4902 pattern.annotate(code)
4904 self.target.annotate(code)
4905 self.body.annotate(code)
4908 class TryFinallyStatNode(StatNode):
4909 # try ... finally statement
4912 # finally_clause StatNode
4914 # The plan is that we funnel all continue, break
4915 # return and error gotos into the beginning of the
4916 # finally block, setting a variable to remember which
4917 # one we're doing. At the end of the finally block, we
4918 # switch on the variable to figure out where to go.
4919 # In addition, if we're doing an error, we save the
4920 # exception on entry to the finally block and restore
4923 child_attrs = ["body", "finally_clause"]
4925 preserve_exception = 1
4927 disallow_continue_in_try_finally = 0
4928 # There doesn't seem to be any point in disallowing
4929 # continue in the try block, since we have no problem
4932 def create_analysed(pos, env, body, finally_clause):
4933 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4935 create_analysed = staticmethod(create_analysed)
4937 def analyse_control_flow(self, env):
4938 env.start_branching(self.pos)
4939 self.body.analyse_control_flow(env)
4940 env.next_branch(self.body.end_pos())
4941 env.finish_branching(self.body.end_pos())
4942 self.finally_clause.analyse_control_flow(env)
4944 def analyse_declarations(self, env):
4945 self.body.analyse_declarations(env)
4946 self.finally_clause.analyse_declarations(env)
4948 def analyse_expressions(self, env):
4949 self.body.analyse_expressions(env)
4950 self.finally_clause.analyse_expressions(env)
4952 nogil_check = Node.gil_error
4953 gil_message = "Try-finally statement"
4955 def generate_execution_code(self, code):
4956 old_error_label = code.error_label
4957 old_labels = code.all_new_labels()
4958 new_labels = code.get_all_labels()
4959 new_error_label = code.error_label
4960 catch_label = code.new_label()
4963 if self.disallow_continue_in_try_finally:
4964 was_in_try_finally = code.funcstate.in_try_finally
4965 code.funcstate.in_try_finally = 1
4966 self.body.generate_execution_code(code)
4967 if self.disallow_continue_in_try_finally:
4968 code.funcstate.in_try_finally = was_in_try_finally
4971 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4972 code.mark_pos(self.finally_clause.pos)
4976 error_label_used = 0
4977 for i, new_label in enumerate(new_labels):
4978 if new_label in code.labels_used:
4979 cases_used.append(i)
4980 if new_label == new_error_label:
4981 error_label_used = 1
4982 error_label_case = i
4986 if error_label_used and self.preserve_exception:
4988 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4990 "int %s;" % Naming.exc_lineno_name)
4991 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4992 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4993 code.putln(exc_var_init_zero)
4995 exc_var_init_zero = None
4996 code.use_label(catch_label)
4998 "__pyx_why = 0; goto %s;" % catch_label)
4999 for i in cases_used:
5000 new_label = new_labels[i]
5001 #if new_label and new_label != "<try>":
5002 if new_label == new_error_label and self.preserve_exception:
5003 self.put_error_catcher(code,
5004 new_error_label, i+1, catch_label, temps_to_clean_up)
5006 code.put('%s: ' % new_label)
5007 if exc_var_init_zero:
5008 code.putln(exc_var_init_zero)
5009 code.putln("__pyx_why = %s; goto %s;" % (
5012 code.put_label(catch_label)
5013 code.set_all_labels(old_labels)
5014 if error_label_used:
5015 code.new_error_label()
5016 finally_error_label = code.error_label
5017 self.finally_clause.generate_execution_code(code)
5018 if error_label_used:
5019 if finally_error_label in code.labels_used and self.preserve_exception:
5020 over_label = code.new_label()
5021 code.put_goto(over_label);
5022 code.put_label(finally_error_label)
5023 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5024 for var in Naming.exc_vars:
5025 code.putln("Py_XDECREF(%s);" % var)
5027 code.put_goto(old_error_label)
5028 code.put_label(over_label)
5029 code.error_label = old_error_label
5032 "switch (__pyx_why) {")
5033 for i in cases_used:
5034 old_label = old_labels[i]
5035 if old_label == old_error_label and self.preserve_exception:
5036 self.put_error_uncatcher(code, i+1, old_error_label)
5038 code.use_label(old_label)
5040 "case %s: goto %s;" % (
5048 def generate_function_definitions(self, env, code):
5049 self.body.generate_function_definitions(env, code)
5050 self.finally_clause.generate_function_definitions(env, code)
5052 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5053 code.globalstate.use_utility_code(restore_exception_utility_code)
5060 for temp_name, type in temps_to_clean_up:
5061 code.put_xdecref_clear(temp_name, type)
5063 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5067 Naming.exc_lineno_name, Naming.lineno_cname))
5068 code.put_goto(catch_label)
5071 def put_error_uncatcher(self, code, i, error_label):
5072 code.globalstate.use_utility_code(restore_exception_utility_code)
5077 "__Pyx_ErrRestore(%s, %s, %s);" %
5081 Naming.lineno_cname, Naming.exc_lineno_name))
5082 for var in Naming.exc_vars:
5086 code.put_goto(error_label)
5090 def annotate(self, code):
5091 self.body.annotate(code)
5092 self.finally_clause.annotate(code)
5095 class GILStatNode(TryFinallyStatNode):
5096 # 'with gil' or 'with nogil' statement
5098 # state string 'gil' or 'nogil'
5102 preserve_exception = 0
5104 def __init__(self, pos, state, body):
5106 TryFinallyStatNode.__init__(self, pos,
5108 finally_clause = GILExitNode(pos, state = state))
5110 def analyse_expressions(self, env):
5111 env.use_utility_code(force_init_threads_utility_code)
5112 was_nogil = env.nogil
5114 TryFinallyStatNode.analyse_expressions(self, env)
5115 env.nogil = was_nogil
5119 def generate_execution_code(self, code):
5120 code.mark_pos(self.pos)
5122 if self.state == 'gil':
5123 code.putln("#ifdef WITH_THREAD")
5124 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5125 code.putln("#endif")
5127 code.putln("#ifdef WITH_THREAD")
5128 code.putln("PyThreadState *_save;")
5129 code.putln("#endif")
5130 code.putln("Py_UNBLOCK_THREADS")
5131 TryFinallyStatNode.generate_execution_code(self, code)
5135 class GILExitNode(StatNode):
5136 # Used as the 'finally' block in a GILStatNode
5138 # state string 'gil' or 'nogil'
5142 def analyse_expressions(self, env):
5145 def generate_execution_code(self, code):
5146 if self.state == 'gil':
5147 code.putln("#ifdef WITH_THREAD")
5148 code.putln("PyGILState_Release(_save);")
5149 code.putln("#endif")
5151 code.putln("Py_BLOCK_THREADS")
5154 class CImportStatNode(StatNode):
5157 # module_name string Qualified name of module being imported
5158 # as_name string or None Name specified in "as" clause, if any
5162 def analyse_declarations(self, env):
5163 if not env.is_module_scope:
5164 error(self.pos, "cimport only allowed at module level")
5166 module_scope = env.find_module(self.module_name, self.pos)
5167 if "." in self.module_name:
5168 names = [EncodedString(name) for name in self.module_name.split(".")]
5170 top_module_scope = env.context.find_submodule(top_name)
5171 module_scope = top_module_scope
5172 for name in names[1:]:
5173 submodule_scope = module_scope.find_submodule(name)
5174 module_scope.declare_module(name, submodule_scope, self.pos)
5175 module_scope = submodule_scope
5177 env.declare_module(self.as_name, module_scope, self.pos)
5179 env.declare_module(top_name, top_module_scope, self.pos)
5181 name = self.as_name or self.module_name
5182 env.declare_module(name, module_scope, self.pos)
5184 def analyse_expressions(self, env):
5187 def generate_execution_code(self, code):
5191 class FromCImportStatNode(StatNode):
5192 # from ... cimport statement
5194 # module_name string Qualified name of module
5195 # imported_names [(pos, name, as_name, kind)] Names to be imported
5199 def analyse_declarations(self, env):
5200 if not env.is_module_scope:
5201 error(self.pos, "cimport only allowed at module level")
5203 module_scope = env.find_module(self.module_name, self.pos)
5204 env.add_imported_module(module_scope)
5205 for pos, name, as_name, kind in self.imported_names:
5207 for local_name, entry in module_scope.entries.items():
5208 env.add_imported_entry(local_name, entry, pos)
5210 entry = module_scope.lookup(name)
5212 if kind and not self.declaration_matches(entry, kind):
5213 entry.redeclared(pos)
5215 if kind == 'struct' or kind == 'union':
5216 entry = module_scope.declare_struct_or_union(name,
5217 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5218 elif kind == 'class':
5219 entry = module_scope.declare_c_class(name, pos = pos,
5220 module_name = self.module_name)
5222 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5223 if submodule_scope.parent_module is module_scope:
5224 env.declare_module(as_name or name, submodule_scope, self.pos)
5226 error(pos, "Name '%s' not declared in module '%s'"
5227 % (name, self.module_name))
5230 local_name = as_name or name
5231 env.add_imported_entry(local_name, entry, pos)
5233 def declaration_matches(self, entry, kind):
5234 if not entry.is_type:
5238 if not type.is_extension_type:
5241 if not type.is_struct_or_union:
5243 if kind != type.kind:
5247 def analyse_expressions(self, env):
5250 def generate_execution_code(self, code):
5254 class FromImportStatNode(StatNode):
5255 # from ... import statement
5258 # items [(string, NameNode)]
5259 # interned_items [(string, NameNode, ExprNode)]
5260 # item PyTempNode used internally
5261 # import_star boolean used internally
5263 child_attrs = ["module"]
5266 def analyse_declarations(self, env):
5267 for name, target in self.items:
5269 if not env.is_module_scope:
5270 error(self.pos, "import * only allowed at module level")
5272 env.has_import_star = 1
5273 self.import_star = 1
5275 target.analyse_target_declaration(env)
5277 def analyse_expressions(self, env):
5279 self.module.analyse_expressions(env)
5280 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5281 self.interned_items = []
5282 for name, target in self.items:
5284 for _, entry in env.entries.items():
5285 if not entry.is_type and entry.type.is_extension_type:
5286 env.use_utility_code(ExprNodes.type_test_utility_code)
5289 entry = env.lookup(target.name)
5290 # check whether or not entry is already cimported
5291 if (entry.is_type and entry.type.name == name
5292 and hasattr(entry.type, 'module_name')):
5293 if entry.type.module_name == self.module.module_name.value:
5294 # cimported with absolute name
5297 # cimported with relative name
5298 module = env.find_module(self.module.module_name.value,
5300 if entry.type.module_name == module.qualified_name:
5302 except AttributeError:
5304 target.analyse_target_expression(env, None)
5305 if target.type is py_object_type:
5308 coerced_item = self.item.coerce_to(target.type, env)
5309 self.interned_items.append((name, target, coerced_item))
5311 def generate_execution_code(self, code):
5312 self.module.generate_evaluation_code(code)
5313 if self.import_star:
5315 'if (%s(%s) < 0) %s;' % (
5317 self.module.py_result(),
5318 code.error_goto(self.pos)))
5319 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5320 self.item.set_cname(item_temp)
5321 for name, target, coerced_item in self.interned_items:
5322 cname = code.intern_identifier(name)
5324 '%s = PyObject_GetAttr(%s, %s); %s' % (
5326 self.module.py_result(),
5328 code.error_goto_if_null(item_temp, self.pos)))
5329 code.put_gotref(item_temp)
5330 if coerced_item is None:
5331 target.generate_assignment_code(self.item, code)
5333 coerced_item.allocate_temp_result(code)
5334 coerced_item.generate_result_code(code)
5335 target.generate_assignment_code(coerced_item, code)
5336 code.put_decref_clear(item_temp, py_object_type)
5337 code.funcstate.release_temp(item_temp)
5338 self.module.generate_disposal_code(code)
5339 self.module.free_temps(code)
5343 #------------------------------------------------------------------------------------
5345 # Runtime support code
5347 #------------------------------------------------------------------------------------
5349 utility_function_predeclarations = \
5351 /* inline attribute */
5352 #ifndef CYTHON_INLINE
5353 #if defined(__GNUC__)
5354 #define CYTHON_INLINE __inline__
5355 #elif defined(_MSC_VER)
5356 #define CYTHON_INLINE __inline
5357 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5358 #define CYTHON_INLINE inline
5360 #define CYTHON_INLINE
5364 /* unused attribute */
5365 #ifndef CYTHON_UNUSED
5366 # if defined(__GNUC__)
5367 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5368 # define CYTHON_UNUSED __attribute__ ((__unused__))
5370 # define CYTHON_UNUSED
5372 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5373 # define CYTHON_UNUSED __attribute__ ((__unused__))
5375 # define CYTHON_UNUSED
5379 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*/
5383 if Options.gcc_branch_hints:
5384 branch_prediction_macros = \
5387 /* Test for GCC > 2.95 */
5388 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5389 #define likely(x) __builtin_expect(!!(x), 1)
5390 #define unlikely(x) __builtin_expect(!!(x), 0)
5391 #else /* __GNUC__ > 2 ... */
5392 #define likely(x) (x)
5393 #define unlikely(x) (x)
5394 #endif /* __GNUC__ > 2 ... */
5395 #else /* __GNUC__ */
5396 #define likely(x) (x)
5397 #define unlikely(x) (x)
5398 #endif /* __GNUC__ */
5401 branch_prediction_macros = \
5403 #define likely(x) (x)
5404 #define unlikely(x) (x)
5407 #get_name_predeclaration = \
5408 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5410 #get_name_interned_predeclaration = \
5411 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5413 #------------------------------------------------------------------------------------
5415 printing_utility_code = UtilityCode(
5417 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5418 #if PY_MAJOR_VERSION >= 3
5419 static PyObject* %s = 0;
5420 static PyObject* %s = 0;
5422 """ % (Naming.print_function, Naming.print_function_kwargs),
5424 #if PY_MAJOR_VERSION >= 3
5428 """ % (Naming.print_function, Naming.print_function_kwargs),
5430 #if PY_MAJOR_VERSION < 3
5431 static PyObject *__Pyx_GetStdout(void) {
5432 PyObject *f = PySys_GetObject((char *)"stdout");
5434 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5439 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5444 if (!(f = __Pyx_GetStdout()))
5447 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5448 if (PyFile_SoftSpace(f, 1)) {
5449 if (PyFile_WriteString(" ", f) < 0)
5452 v = PyTuple_GET_ITEM(arg_tuple, i);
5453 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5455 if (PyString_Check(v)) {
5456 char *s = PyString_AsString(v);
5457 Py_ssize_t len = PyString_Size(v);
5459 isspace(Py_CHARMASK(s[len-1])) &&
5461 PyFile_SoftSpace(f, 0);
5465 if (PyFile_WriteString("\n", f) < 0)
5467 PyFile_SoftSpace(f, 0);
5472 #else /* Python 3 has a print function */
5474 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5475 PyObject* kwargs = 0;
5476 PyObject* result = 0;
5477 PyObject* end_string;
5478 if (unlikely(!%(PRINT_FUNCTION)s)) {
5479 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5480 if (!%(PRINT_FUNCTION)s)
5484 kwargs = PyDict_New();
5485 if (unlikely(!kwargs))
5487 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5490 end_string = PyUnicode_FromStringAndSize(" ", 1);
5491 if (unlikely(!end_string))
5493 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5494 Py_DECREF(end_string);
5497 Py_DECREF(end_string);
5499 } else if (!newline) {
5500 if (unlikely(!%(PRINT_KWARGS)s)) {
5501 %(PRINT_KWARGS)s = PyDict_New();
5502 if (unlikely(!%(PRINT_KWARGS)s))
5504 end_string = PyUnicode_FromStringAndSize(" ", 1);
5505 if (unlikely(!end_string))
5507 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5508 Py_DECREF(end_string);
5511 Py_DECREF(end_string);
5513 kwargs = %(PRINT_KWARGS)s;
5515 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5516 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5523 if (kwargs != %(PRINT_KWARGS)s)
5529 """ % {'BUILTINS' : Naming.builtins_cname,
5530 'PRINT_FUNCTION' : Naming.print_function,
5531 'PRINT_KWARGS' : Naming.print_function_kwargs}
5535 printing_one_utility_code = UtilityCode(
5537 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5540 #if PY_MAJOR_VERSION < 3
5542 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5544 if (!(f = __Pyx_GetStdout()))
5547 if (PyFile_SoftSpace(f, 0)) {
5548 if (PyFile_WriteString(" ", f) < 0)
5551 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5553 if (PyFile_WriteString("\n", f) < 0)
5556 /* the line below is just to avoid compiler
5557 * compiler warnings about unused functions */
5558 return __Pyx_Print(f, NULL, 0);
5561 #else /* Python 3 has a print function */
5563 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5565 PyObject* arg_tuple = PyTuple_New(1);
5566 if (unlikely(!arg_tuple))
5569 PyTuple_SET_ITEM(arg_tuple, 0, o);
5570 res = __Pyx_Print(stream, arg_tuple, 1);
5571 Py_DECREF(arg_tuple);
5577 requires=[printing_utility_code])
5581 #------------------------------------------------------------------------------------
5583 # Exception raising code
5585 # Exceptions are raised by __Pyx_Raise() and stored as plain
5586 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5587 # 'except' statement, curexc_* is moved over to exc_* by
5588 # __Pyx_GetException()
5590 restore_exception_utility_code = UtilityCode(
5592 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5593 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5596 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5597 PyObject *tmp_type, *tmp_value, *tmp_tb;
5598 PyThreadState *tstate = PyThreadState_GET();
5600 tmp_type = tstate->curexc_type;
5601 tmp_value = tstate->curexc_value;
5602 tmp_tb = tstate->curexc_traceback;
5603 tstate->curexc_type = type;
5604 tstate->curexc_value = value;
5605 tstate->curexc_traceback = tb;
5606 Py_XDECREF(tmp_type);
5607 Py_XDECREF(tmp_value);
5611 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5612 PyThreadState *tstate = PyThreadState_GET();
5613 *type = tstate->curexc_type;
5614 *value = tstate->curexc_value;
5615 *tb = tstate->curexc_traceback;
5617 tstate->curexc_type = 0;
5618 tstate->curexc_value = 0;
5619 tstate->curexc_traceback = 0;
5624 # The following function is based on do_raise() from ceval.c. There
5625 # are separate versions for Python2 and Python3 as exception handling
5626 # has changed quite a lot between the two versions.
5628 raise_utility_code = UtilityCode(
5630 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5633 #if PY_MAJOR_VERSION < 3
5634 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5638 /* First, check the traceback argument, replacing None with NULL. */
5639 if (tb == Py_None) {
5643 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5644 PyErr_SetString(PyExc_TypeError,
5645 "raise: arg 3 must be a traceback or None");
5648 /* Next, replace a missing value with None */
5649 if (value == NULL) {
5653 #if PY_VERSION_HEX < 0x02050000
5654 if (!PyClass_Check(type))
5656 if (!PyType_Check(type))
5659 /* Raising an instance. The value should be a dummy. */
5660 if (value != Py_None) {
5661 PyErr_SetString(PyExc_TypeError,
5662 "instance exception may not have a separate value");
5665 /* Normalize to raise <class>, <instance> */
5668 #if PY_VERSION_HEX < 0x02050000
5669 if (PyInstance_Check(type)) {
5670 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5675 PyErr_SetString(PyExc_TypeError,
5676 "raise: exception must be an old-style class or instance");
5680 type = (PyObject*) Py_TYPE(type);
5682 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5683 PyErr_SetString(PyExc_TypeError,
5684 "raise: exception class must be a subclass of BaseException");
5690 __Pyx_ErrRestore(type, value, tb);
5699 #else /* Python 3+ */
5701 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5702 if (tb == Py_None) {
5704 } else if (tb && !PyTraceBack_Check(tb)) {
5705 PyErr_SetString(PyExc_TypeError,
5706 "raise: arg 3 must be a traceback or None");
5709 if (value == Py_None)
5712 if (PyExceptionInstance_Check(type)) {
5714 PyErr_SetString(PyExc_TypeError,
5715 "instance exception may not have a separate value");
5719 type = (PyObject*) Py_TYPE(value);
5720 } else if (!PyExceptionClass_Check(type)) {
5721 PyErr_SetString(PyExc_TypeError,
5722 "raise: exception class must be a subclass of BaseException");
5726 PyErr_SetObject(type, value);
5729 PyThreadState *tstate = PyThreadState_GET();
5730 PyObject* tmp_tb = tstate->curexc_traceback;
5733 tstate->curexc_traceback = tb;
5743 requires=[restore_exception_utility_code])
5745 #------------------------------------------------------------------------------------
5747 get_exception_utility_code = UtilityCode(
5749 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5752 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5753 PyObject *local_type, *local_value, *local_tb;
5754 PyObject *tmp_type, *tmp_value, *tmp_tb;
5755 PyThreadState *tstate = PyThreadState_GET();
5756 local_type = tstate->curexc_type;
5757 local_value = tstate->curexc_value;
5758 local_tb = tstate->curexc_traceback;
5759 tstate->curexc_type = 0;
5760 tstate->curexc_value = 0;
5761 tstate->curexc_traceback = 0;
5762 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5763 if (unlikely(tstate->curexc_type))
5765 #if PY_MAJOR_VERSION >= 3
5766 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5770 *value = local_value;
5772 Py_INCREF(local_type);
5773 Py_INCREF(local_value);
5774 Py_INCREF(local_tb);
5775 tmp_type = tstate->exc_type;
5776 tmp_value = tstate->exc_value;
5777 tmp_tb = tstate->exc_traceback;
5778 tstate->exc_type = local_type;
5779 tstate->exc_value = local_value;
5780 tstate->exc_traceback = local_tb;
5781 /* Make sure tstate is in a consistent state when we XDECREF
5782 these objects (XDECREF may run arbitrary code). */
5783 Py_XDECREF(tmp_type);
5784 Py_XDECREF(tmp_value);
5791 Py_XDECREF(local_type);
5792 Py_XDECREF(local_value);
5793 Py_XDECREF(local_tb);
5799 #------------------------------------------------------------------------------------
5801 get_exception_tuple_utility_code = UtilityCode(proto="""
5802 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5804 # I doubt that calling __Pyx_GetException() here is correct as it moves
5805 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5806 # exception handlers later on from receiving it.
5808 static PyObject *__Pyx_GetExceptionTuple(void) {
5809 PyObject *type = NULL, *value = NULL, *tb = NULL;
5810 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5811 PyObject* exc_info = PyTuple_New(3);
5816 PyTuple_SET_ITEM(exc_info, 0, type);
5817 PyTuple_SET_ITEM(exc_info, 1, value);
5818 PyTuple_SET_ITEM(exc_info, 2, tb);
5825 requires=[get_exception_utility_code])
5827 #------------------------------------------------------------------------------------
5829 reset_exception_utility_code = UtilityCode(
5831 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5832 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5835 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5836 PyThreadState *tstate = PyThreadState_GET();
5837 *type = tstate->exc_type;
5838 *value = tstate->exc_value;
5839 *tb = tstate->exc_traceback;
5845 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5846 PyObject *tmp_type, *tmp_value, *tmp_tb;
5847 PyThreadState *tstate = PyThreadState_GET();
5848 tmp_type = tstate->exc_type;
5849 tmp_value = tstate->exc_value;
5850 tmp_tb = tstate->exc_traceback;
5851 tstate->exc_type = type;
5852 tstate->exc_value = value;
5853 tstate->exc_traceback = tb;
5854 Py_XDECREF(tmp_type);
5855 Py_XDECREF(tmp_value);
5860 #------------------------------------------------------------------------------------
5862 arg_type_test_utility_code = UtilityCode(
5864 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5865 const char *name, int exact); /*proto*/
5868 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5869 const char *name, int exact)
5872 PyErr_Format(PyExc_SystemError, "Missing type object");
5875 if (none_allowed && obj == Py_None) return 1;
5877 if (Py_TYPE(obj) == type) return 1;
5880 if (PyObject_TypeCheck(obj, type)) return 1;
5882 PyErr_Format(PyExc_TypeError,
5883 "Argument '%s' has incorrect type (expected %s, got %s)",
5884 name, type->tp_name, Py_TYPE(obj)->tp_name);
5889 #------------------------------------------------------------------------------------
5891 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5892 # many or too few positional arguments were found. This handles
5893 # Py_ssize_t formatting correctly.
5895 raise_argtuple_invalid_utility_code = UtilityCode(
5897 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5898 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5901 static void __Pyx_RaiseArgtupleInvalid(
5902 const char* func_name,
5906 Py_ssize_t num_found)
5908 Py_ssize_t num_expected;
5909 const char *number, *more_or_less;
5911 if (num_found < num_min) {
5912 num_expected = num_min;
5913 more_or_less = "at least";
5915 num_expected = num_max;
5916 more_or_less = "at most";
5919 more_or_less = "exactly";
5921 number = (num_expected == 1) ? "" : "s";
5922 PyErr_Format(PyExc_TypeError,
5923 #if PY_VERSION_HEX < 0x02050000
5924 "%s() takes %s %d positional argument%s (%d given)",
5926 "%s() takes %s %zd positional argument%s (%zd given)",
5928 func_name, more_or_less, num_expected, number, num_found);
5932 raise_keyword_required_utility_code = UtilityCode(
5934 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5937 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5938 const char* func_name,
5941 PyErr_Format(PyExc_TypeError,
5942 #if PY_MAJOR_VERSION >= 3
5943 "%s() needs keyword-only argument %U", func_name, kw_name);
5945 "%s() needs keyword-only argument %s", func_name,
5946 PyString_AS_STRING(kw_name));
5951 raise_double_keywords_utility_code = UtilityCode(
5953 static void __Pyx_RaiseDoubleKeywordsError(
5954 const char* func_name, PyObject* kw_name); /*proto*/
5957 static void __Pyx_RaiseDoubleKeywordsError(
5958 const char* func_name,
5961 PyErr_Format(PyExc_TypeError,
5962 #if PY_MAJOR_VERSION >= 3
5963 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5965 "%s() got multiple values for keyword argument '%s'", func_name,
5966 PyString_AS_STRING(kw_name));
5971 #------------------------------------------------------------------------------------
5973 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5974 # were passed to a function, or if any keywords were passed to a
5975 # function that does not accept them.
5977 keyword_string_check_utility_code = UtilityCode(
5979 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5980 const char* function_name, int kw_allowed); /*proto*/
5983 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5985 const char* function_name,
5990 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5991 #if PY_MAJOR_VERSION < 3
5992 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5994 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5996 goto invalid_keyword_type;
5998 if ((!kw_allowed) && unlikely(key))
5999 goto invalid_keyword;
6001 invalid_keyword_type:
6002 PyErr_Format(PyExc_TypeError,
6003 "%s() keywords must be strings", function_name);
6006 PyErr_Format(PyExc_TypeError,
6007 #if PY_MAJOR_VERSION < 3
6008 "%s() got an unexpected keyword argument '%s'",
6009 function_name, PyString_AsString(key));
6011 "%s() got an unexpected keyword argument '%U'",
6012 function_name, key);
6018 #------------------------------------------------------------------------------------
6020 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6021 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6022 # keywords will raise an invalid keyword error.
6024 # Three kinds of errors are checked: 1) non-string keywords, 2)
6025 # unexpected keywords and 3) overlap with positional arguments.
6027 # If num_posargs is greater 0, it denotes the number of positional
6028 # arguments that were passed and that must therefore not appear
6029 # amongst the keywords as well.
6031 # This method does not check for required keyword arguments.
6034 parse_keywords_utility_code = UtilityCode(
6036 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6037 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6038 const char* function_name); /*proto*/
6041 static int __Pyx_ParseOptionalKeywords(
6043 PyObject **argnames[],
6046 Py_ssize_t num_pos_args,
6047 const char* function_name)
6049 PyObject *key = 0, *value = 0;
6052 PyObject*** first_kw_arg = argnames + num_pos_args;
6054 while (PyDict_Next(kwds, &pos, &key, &value)) {
6055 name = first_kw_arg;
6056 while (*name && (**name != key)) name++;
6058 values[name-argnames] = value;
6060 #if PY_MAJOR_VERSION < 3
6061 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6063 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6065 goto invalid_keyword_type;
6067 for (name = first_kw_arg; *name; name++) {
6068 #if PY_MAJOR_VERSION >= 3
6069 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6070 PyUnicode_Compare(**name, key) == 0) break;
6072 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6073 _PyString_Eq(**name, key)) break;
6077 values[name-argnames] = value;
6079 /* unexpected keyword found */
6080 for (name=argnames; name != first_kw_arg; name++) {
6081 if (**name == key) goto arg_passed_twice;
6082 #if PY_MAJOR_VERSION >= 3
6083 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6084 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6086 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6087 _PyString_Eq(**name, key)) goto arg_passed_twice;
6091 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6093 goto invalid_keyword;
6101 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6103 invalid_keyword_type:
6104 PyErr_Format(PyExc_TypeError,
6105 "%s() keywords must be strings", function_name);
6108 PyErr_Format(PyExc_TypeError,
6109 #if PY_MAJOR_VERSION < 3
6110 "%s() got an unexpected keyword argument '%s'",
6111 function_name, PyString_AsString(key));
6113 "%s() got an unexpected keyword argument '%U'",
6114 function_name, key);
6120 requires=[raise_double_keywords_utility_code])
6122 #------------------------------------------------------------------------------------
6124 traceback_utility_code = UtilityCode(
6126 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6129 #include "compile.h"
6130 #include "frameobject.h"
6131 #include "traceback.h"
6133 static void __Pyx_AddTraceback(const char *funcname) {
6134 PyObject *py_srcfile = 0;
6135 PyObject *py_funcname = 0;
6136 PyObject *py_globals = 0;
6137 PyCodeObject *py_code = 0;
6138 PyFrameObject *py_frame = 0;
6140 #if PY_MAJOR_VERSION < 3
6141 py_srcfile = PyString_FromString(%(FILENAME)s);
6143 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6145 if (!py_srcfile) goto bad;
6147 #if PY_MAJOR_VERSION < 3
6148 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6150 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6154 #if PY_MAJOR_VERSION < 3
6155 py_funcname = PyString_FromString(funcname);
6157 py_funcname = PyUnicode_FromString(funcname);
6160 if (!py_funcname) goto bad;
6161 py_globals = PyModule_GetDict(%(GLOBALS)s);
6162 if (!py_globals) goto bad;
6163 py_code = PyCode_New(
6164 0, /*int argcount,*/
6165 #if PY_MAJOR_VERSION >= 3
6166 0, /*int kwonlyargcount,*/
6169 0, /*int stacksize,*/
6171 %(EMPTY_BYTES)s, /*PyObject *code,*/
6172 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6173 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6174 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6175 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6176 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6177 py_srcfile, /*PyObject *filename,*/
6178 py_funcname, /*PyObject *name,*/
6179 %(LINENO)s, /*int firstlineno,*/
6180 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6182 if (!py_code) goto bad;
6183 py_frame = PyFrame_New(
6184 PyThreadState_GET(), /*PyThreadState *tstate,*/
6185 py_code, /*PyCodeObject *code,*/
6186 py_globals, /*PyObject *globals,*/
6187 0 /*PyObject *locals*/
6189 if (!py_frame) goto bad;
6190 py_frame->f_lineno = %(LINENO)s;
6191 PyTraceBack_Here(py_frame);
6193 Py_XDECREF(py_srcfile);
6194 Py_XDECREF(py_funcname);
6195 Py_XDECREF(py_code);
6196 Py_XDECREF(py_frame);
6199 'FILENAME': Naming.filename_cname,
6200 'LINENO': Naming.lineno_cname,
6201 'CFILENAME': Naming.cfilenm_cname,
6202 'CLINENO': Naming.clineno_cname,
6203 'GLOBALS': Naming.module_cname,
6204 'EMPTY_TUPLE' : Naming.empty_tuple,
6205 'EMPTY_BYTES' : Naming.empty_bytes,
6208 #------------------------------------------------------------------------------------
6210 unraisable_exception_utility_code = UtilityCode(
6212 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6215 static void __Pyx_WriteUnraisable(const char *name) {
6216 PyObject *old_exc, *old_val, *old_tb;
6218 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6219 #if PY_MAJOR_VERSION < 3
6220 ctx = PyString_FromString(name);
6222 ctx = PyUnicode_FromString(name);
6224 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6226 PyErr_WriteUnraisable(Py_None);
6228 PyErr_WriteUnraisable(ctx);
6233 requires=[restore_exception_utility_code])
6235 #------------------------------------------------------------------------------------
6237 set_vtable_utility_code = UtilityCode(
6239 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6242 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6243 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6244 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6246 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6250 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6260 #------------------------------------------------------------------------------------
6262 get_vtable_utility_code = UtilityCode(
6264 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6267 static void* __Pyx_GetVtable(PyObject *dict) {
6269 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6272 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6273 ptr = PyCapsule_GetPointer(ob, 0);
6275 ptr = PyCObject_AsVoidPtr(ob);
6277 if (!ptr && !PyErr_Occurred())
6278 PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6287 #------------------------------------------------------------------------------------
6289 init_string_tab_utility_code = UtilityCode(
6291 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6294 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6296 #if PY_MAJOR_VERSION < 3
6297 if (t->is_unicode) {
6298 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6299 } else if (t->intern) {
6300 *t->p = PyString_InternFromString(t->s);
6302 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6304 #else /* Python 3+ has unicode identifiers */
6305 if (t->is_unicode | t->is_str) {
6307 *t->p = PyUnicode_InternFromString(t->s);
6308 } else if (t->encoding) {
6309 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6311 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6314 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6325 #------------------------------------------------------------------------------------
6327 force_init_threads_utility_code = UtilityCode(
6329 #ifndef __PYX_FORCE_INIT_THREADS
6330 #if PY_VERSION_HEX < 0x02040200
6331 #define __PYX_FORCE_INIT_THREADS 1
6333 #define __PYX_FORCE_INIT_THREADS 0
6338 #------------------------------------------------------------------------------------
6340 # Note that cPython ignores PyTrace_EXCEPTION,
6341 # but maybe some other profilers don't.
6343 profile_utility_code = UtilityCode(proto="""
6344 #ifndef CYTHON_PROFILE
6345 #define CYTHON_PROFILE 1
6348 #ifndef CYTHON_PROFILE_REUSE_FRAME
6349 #define CYTHON_PROFILE_REUSE_FRAME 0
6354 #include "compile.h"
6355 #include "frameobject.h"
6356 #include "traceback.h"
6358 #if CYTHON_PROFILE_REUSE_FRAME
6359 #define CYTHON_FRAME_MODIFIER static
6360 #define CYTHON_FRAME_DEL
6362 #define CYTHON_FRAME_MODIFIER
6363 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6366 #define __Pyx_TraceDeclarations \\
6367 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6368 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6369 int __Pyx_use_tracing = 0;
6371 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6372 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6373 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6376 #define __Pyx_TraceException() \\
6377 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6378 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6380 PyThreadState_GET()->c_profilefunc( \\
6381 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6382 Py_DECREF(exc_info); \\
6386 #define __Pyx_TraceReturn(result) \\
6387 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6388 PyThreadState_GET()->c_profilefunc( \\
6389 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6390 CYTHON_FRAME_DEL; \\
6393 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6394 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6398 #define __Pyx_TraceDeclarations
6399 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6400 #define __Pyx_TraceException()
6401 #define __Pyx_TraceReturn(result)
6403 #endif /* CYTHON_PROFILE */
6406 "FRAME": Naming.frame_cname,
6407 "FRAME_CODE": Naming.frame_code_cname,
6413 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6414 PyFrameObject** frame,
6415 const char *funcname,
6416 const char *srcfile,
6418 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6419 if (*code == NULL) {
6420 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6421 if (*code == NULL) return 0;
6423 *frame = PyFrame_New(
6424 PyThreadState_GET(), /*PyThreadState *tstate*/
6425 *code, /*PyCodeObject *code*/
6426 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6427 0 /*PyObject *locals*/
6429 if (*frame == NULL) return 0;
6432 (*frame)->f_tstate = PyThreadState_GET();
6434 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6437 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6438 PyObject *py_srcfile = 0;
6439 PyObject *py_funcname = 0;
6440 PyCodeObject *py_code = 0;
6442 #if PY_MAJOR_VERSION < 3
6443 py_funcname = PyString_FromString(funcname);
6444 py_srcfile = PyString_FromString(srcfile);
6446 py_funcname = PyUnicode_FromString(funcname);
6447 py_srcfile = PyUnicode_FromString(srcfile);
6449 if (!py_funcname | !py_srcfile) goto bad;
6451 py_code = PyCode_New(
6452 0, /*int argcount,*/
6453 #if PY_MAJOR_VERSION >= 3
6454 0, /*int kwonlyargcount,*/
6457 0, /*int stacksize,*/
6459 %(EMPTY_BYTES)s, /*PyObject *code,*/
6460 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6461 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6462 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6463 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6464 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6465 py_srcfile, /*PyObject *filename,*/
6466 py_funcname, /*PyObject *name,*/
6467 firstlineno, /*int firstlineno,*/
6468 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6472 Py_XDECREF(py_srcfile);
6473 Py_XDECREF(py_funcname);
6478 #endif /* CYTHON_PROFILE */
6480 'EMPTY_TUPLE' : Naming.empty_tuple,
6481 'EMPTY_BYTES' : Naming.empty_bytes,
6482 "MODULE": Naming.module_cname,