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_cfunction:
612 "Function cannot return a function")
613 func_type = PyrexTypes.CFuncType(
614 return_type, func_type_args, self.has_varargs,
615 optional_arg_count = self.optional_arg_count,
616 exception_value = exc_val, exception_check = exc_check,
617 calling_convention = self.base.calling_convention,
618 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
619 if self.optional_arg_count:
620 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
621 callspec = env.directives['callspec']
623 current = func_type.calling_convention
624 if current and current != callspec:
625 error(self.pos, "cannot have both '%s' and '%s' "
626 "calling conventions" % (current, callspec))
627 func_type.calling_convention = callspec
628 return self.base.analyse(func_type, env)
631 class CArgDeclNode(Node):
632 # Item in a function declaration argument list.
634 # base_type CBaseTypeNode
635 # declarator CDeclaratorNode
636 # not_none boolean Tagged with 'not None'
637 # or_none boolean Tagged with 'or None'
638 # accept_none boolean Resolved boolean for not_none/or_none
639 # default ExprNode or None
640 # default_value PyObjectConst constant for default value
641 # annotation ExprNode or None Py3 function arg annotation
642 # is_self_arg boolean Is the "self" arg of an extension type method
643 # is_type_arg boolean Is the "class" arg of an extension type classmethod
644 # is_kw_only boolean Is a keyword-only argument
646 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 is_basic_c_type = False
743 def analyse(self, env, could_be_name = False):
744 # Return type descriptor.
745 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
747 if self.is_basic_c_type:
748 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
750 error(self.pos, "Unrecognised type modifier combination")
751 elif self.name == "object" and not self.module_path:
752 type = py_object_type
753 elif self.name is None:
754 if self.is_self_arg and env.is_c_class_scope:
755 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
756 type = env.parent_type
757 ## elif self.is_type_arg and env.is_c_class_scope:
758 ## type = Builtin.type_type
760 type = py_object_type
763 scope = env.find_imported_module(self.module_path, self.pos)
767 if scope.is_c_class_scope:
768 scope = scope.global_scope()
769 entry = scope.lookup(self.name)
770 if entry and entry.is_type:
773 if self.is_self_arg and env.is_c_class_scope:
774 type = env.parent_type
775 ## elif self.is_type_arg and env.is_c_class_scope:
776 ## type = Builtin.type_type
778 type = py_object_type
779 self.arg_name = self.name
782 if not self.name in self.templates:
783 error(self.pos, "'%s' is not a type identifier" % self.name)
784 type = PyrexTypes.TemplatePlaceholderType(self.name)
786 error(self.pos, "'%s' is not a type identifier" % self.name)
788 if not type.is_numeric or type.is_complex:
789 error(self.pos, "can only complexify c numeric types")
790 type = PyrexTypes.CComplexType(type)
791 type.create_declaration_utility_code(env)
792 elif type is Builtin.complex_type:
793 # Special case: optimise builtin complex type into C's
794 # double complex. The parser cannot do this (as for the
795 # normal scalar types) as the user may have redeclared the
796 # 'complex' type. Testing for the exact type here works.
797 type = PyrexTypes.c_double_complex_type
798 type.create_declaration_utility_code(env)
803 return PyrexTypes.error_type
805 class CNestedBaseTypeNode(CBaseTypeNode):
806 # For C++ classes that live inside other C++ classes.
809 # base_type CBaseTypeNode
811 child_attrs = ['base_type']
813 def analyse(self, env, could_be_name = None):
814 base_type = self.base_type.analyse(env)
815 if base_type is PyrexTypes.error_type:
816 return PyrexTypes.error_type
817 if not base_type.is_cpp_class:
818 error(self.pos, "'%s' is not a valid type scope" % base_type)
819 return PyrexTypes.error_type
820 type_entry = base_type.scope.lookup_here(self.name)
821 if not type_entry or not type_entry.is_type:
822 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
823 return PyrexTypes.error_type
824 return type_entry.type
826 class TemplatedTypeNode(CBaseTypeNode):
828 # positional_args [ExprNode] List of positional arguments
829 # keyword_args DictNode Keyword arguments
830 # base_type_node CBaseTypeNode
833 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
836 child_attrs = ["base_type_node", "positional_args",
837 "keyword_args", "dtype_node"]
843 def analyse(self, env, could_be_name = False, base_type = None):
844 if base_type is None:
845 base_type = self.base_type_node.analyse(env)
846 if base_type.is_error: return base_type
848 if base_type.is_cpp_class:
850 if self.keyword_args and self.keyword_args.key_value_pairs:
851 error(self.pos, "c++ templates cannot take keyword arguments");
852 self.type = PyrexTypes.error_type
855 for template_node in self.positional_args:
856 type = template_node.analyse_as_type(env)
858 error(template_node.pos, "unknown type in template argument")
860 template_types.append(type)
861 self.type = base_type.specialize_here(self.pos, template_types)
863 elif base_type.is_pyobject:
867 options = Buffer.analyse_buffer_options(
870 self.positional_args,
872 base_type.buffer_defaults)
874 if sys.version_info[0] < 3:
875 # Py 2.x enforces byte strings as keyword arguments ...
876 options = dict([ (name.encode('ASCII'), value)
877 for name, value in options.items() ])
879 self.type = PyrexTypes.BufferType(base_type, **options)
883 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
884 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
885 error(self.pos, "invalid array declaration")
886 self.type = PyrexTypes.error_type
888 # It would be nice to merge this class with CArrayDeclaratorNode,
889 # but arrays are part of the declaration, not the type...
890 if not self.positional_args:
893 dimension = self.positional_args[0]
894 self.array_declarator = CArrayDeclaratorNode(self.pos,
895 base = empty_declarator,
896 dimension = dimension)
897 self.type = self.array_declarator.analyse(base_type, env)[1]
901 class CComplexBaseTypeNode(CBaseTypeNode):
902 # base_type CBaseTypeNode
903 # declarator CDeclaratorNode
905 child_attrs = ["base_type", "declarator"]
907 def analyse(self, env, could_be_name = False):
908 base = self.base_type.analyse(env, could_be_name)
909 _, type = self.declarator.analyse(base, env)
913 class CVarDefNode(StatNode):
914 # C variable definition or forward/extern function declaration.
916 # visibility 'private' or 'public' or 'extern'
917 # base_type CBaseTypeNode
918 # declarators [CDeclaratorNode]
922 # decorators [cython.locals(...)] or None
923 # directive_locals { string : NameNode } locals defined by cython.locals(...)
925 child_attrs = ["base_type", "declarators"]
928 directive_locals = {}
930 def analyse_declarations(self, env, dest_scope = None):
933 self.dest_scope = dest_scope
934 base_type = self.base_type.analyse(env)
936 # If the field is an external typedef, we cannot be sure about the type,
937 # so do conversion ourself rather than rely on the CPython mechanism (through
938 # a property; made in AnalyseDeclarationsTransform).
939 if (dest_scope.is_c_class_scope
940 and self.visibility in ('public', 'readonly')):
943 need_property = False
944 visibility = self.visibility
946 for declarator in self.declarators:
947 name_declarator, type = declarator.analyse(base_type, env)
948 if not type.is_complete():
949 if not (self.visibility == 'extern' and type.is_array):
950 error(declarator.pos,
951 "Variable type '%s' is incomplete" % type)
952 if self.visibility == 'extern' and type.is_pyobject:
953 error(declarator.pos,
954 "Python object cannot be declared extern")
955 name = name_declarator.name
956 cname = name_declarator.cname
958 error(declarator.pos, "Missing name in declaration.")
960 if type.is_cfunction:
961 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
962 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
964 if entry is not None:
965 entry.directive_locals = self.directive_locals
967 if self.directive_locals:
968 error(self.pos, "Decorators can only be followed by functions")
969 if self.in_pxd and self.visibility != 'extern':
971 "Only 'extern' C variable declaration allowed in .pxd file")
972 entry = dest_scope.declare_var(name, type, declarator.pos,
973 cname = cname, visibility = visibility, is_cdef = 1)
974 entry.needs_property = need_property
977 class CStructOrUnionDefNode(StatNode):
979 # cname string or None
980 # kind "struct" or "union"
981 # typedef_flag boolean
982 # visibility "public" or "private"
984 # attributes [CVarDefNode] or None
988 child_attrs = ["attributes"]
990 def analyse_declarations(self, env):
992 if self.visibility == 'extern' and self.packed:
993 error(self.pos, "Cannot declare extern struct as 'packed'")
994 if self.attributes is not None:
995 scope = StructOrUnionScope(self.name)
996 self.entry = env.declare_struct_or_union(
997 self.name, self.kind, scope, self.typedef_flag, self.pos,
998 self.cname, visibility = self.visibility, packed = self.packed)
999 if self.attributes is not None:
1000 if self.in_pxd and not env.in_cinclude:
1001 self.entry.defined_in_pxd = 1
1002 for attr in self.attributes:
1003 attr.analyse_declarations(env, scope)
1004 if self.visibility != 'extern':
1005 need_typedef_indirection = False
1006 for attr in scope.var_entries:
1008 while type.is_array:
1009 type = type.base_type
1010 if type == self.entry.type:
1011 error(attr.pos, "Struct cannot contain itself as a member.")
1012 if self.typedef_flag:
1014 type = type.base_type
1015 if type == self.entry.type:
1016 need_typedef_indirection = True
1017 if need_typedef_indirection:
1018 # C can't handle typedef structs that refer to themselves.
1019 struct_entry = self.entry
1020 self.entry = env.declare_typedef(
1021 self.name, struct_entry.type, self.pos,
1022 cname = self.cname, visibility='ignore')
1023 struct_entry.type.typedef_flag = False
1024 # FIXME: this might be considered a hack ;-)
1025 struct_entry.cname = struct_entry.type.cname = \
1026 '_' + self.entry.type.typedef_cname
1028 def analyse_expressions(self, env):
1031 def generate_execution_code(self, code):
1035 class CppClassNode(CStructOrUnionDefNode):
1038 # cname string or None
1039 # visibility "extern"
1041 # attributes [CVarDefNode] or None
1043 # base_classes [string]
1044 # templates [string] or None
1046 def analyse_declarations(self, env):
1048 if self.attributes is not None:
1049 scope = CppClassScope(self.name, env)
1050 base_class_types = []
1051 for base_class_name in self.base_classes:
1052 base_class_entry = env.lookup(base_class_name)
1053 if base_class_entry is None:
1054 error(self.pos, "'%s' not found" % base_class_name)
1055 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1056 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1058 base_class_types.append(base_class_entry.type)
1059 if self.templates is None:
1060 template_types = None
1062 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1063 self.entry = env.declare_cpp_class(
1064 self.name, scope, self.pos,
1065 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1066 if self.entry is None:
1068 self.entry.is_cpp_class = 1
1069 if self.attributes is not None:
1070 if self.in_pxd and not env.in_cinclude:
1071 self.entry.defined_in_pxd = 1
1072 for attr in self.attributes:
1073 attr.analyse_declarations(scope)
1075 class CEnumDefNode(StatNode):
1076 # name string or None
1077 # cname string or None
1078 # items [CEnumDefItemNode]
1079 # typedef_flag boolean
1080 # visibility "public" or "private"
1084 child_attrs = ["items"]
1086 def analyse_declarations(self, env):
1087 self.entry = env.declare_enum(self.name, self.pos,
1088 cname = self.cname, typedef_flag = self.typedef_flag,
1089 visibility = self.visibility)
1090 if self.items is not None:
1091 if self.in_pxd and not env.in_cinclude:
1092 self.entry.defined_in_pxd = 1
1093 for item in self.items:
1094 item.analyse_declarations(env, self.entry)
1096 def analyse_expressions(self, env):
1099 def generate_execution_code(self, code):
1100 if self.visibility == 'public':
1101 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1102 for item in self.entry.enum_values:
1103 code.putln("%s = PyInt_FromLong(%s); %s" % (
1106 code.error_goto_if_null(temp, item.pos)))
1107 code.put_gotref(temp)
1108 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1109 Naming.module_cname,
1112 code.error_goto(item.pos)))
1113 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1114 code.funcstate.release_temp(temp)
1117 class CEnumDefItemNode(StatNode):
1119 # cname string or None
1120 # value ExprNode or None
1122 child_attrs = ["value"]
1124 def analyse_declarations(self, env, enum_entry):
1126 self.value.analyse_const_expression(env)
1127 if not self.value.type.is_int:
1128 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1129 self.value.analyse_const_expression(env)
1130 entry = env.declare_const(self.name, enum_entry.type,
1131 self.value, self.pos, cname = self.cname,
1132 visibility = enum_entry.visibility)
1133 enum_entry.enum_values.append(entry)
1136 class CTypeDefNode(StatNode):
1137 # base_type CBaseTypeNode
1138 # declarator CDeclaratorNode
1139 # visibility "public" or "private"
1142 child_attrs = ["base_type", "declarator"]
1144 def analyse_declarations(self, env):
1145 base = self.base_type.analyse(env)
1146 name_declarator, type = self.declarator.analyse(base, env)
1147 name = name_declarator.name
1148 cname = name_declarator.cname
1149 entry = env.declare_typedef(name, type, self.pos,
1150 cname = cname, visibility = self.visibility)
1151 if self.in_pxd and not env.in_cinclude:
1152 entry.defined_in_pxd = 1
1154 def analyse_expressions(self, env):
1156 def generate_execution_code(self, code):
1160 class FuncDefNode(StatNode, BlockNode):
1161 # Base class for function definition nodes.
1163 # return_type PyrexType
1164 # #filename string C name of filename string const
1165 # entry Symtab.Entry
1166 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1167 # needs_outer_scope boolean Whether or not this function requires outer scope
1168 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1172 needs_closure = False
1173 needs_outer_scope = False
1176 def analyse_default_values(self, env):
1177 genv = env.global_scope()
1179 for arg in self.args:
1183 arg.default.analyse_types(env)
1184 arg.default = arg.default.coerce_to(arg.type, genv)
1187 "This argument cannot have a default value")
1192 error(arg.pos, "Non-default argument following default argument")
1194 def align_argument_type(self, env, arg):
1195 directive_locals = self.directive_locals
1197 if arg.name in directive_locals:
1198 type_node = directive_locals[arg.name]
1199 other_type = type_node.analyse_as_type(env)
1200 if other_type is None:
1201 error(type_node.pos, "Not a type")
1202 elif (type is not PyrexTypes.py_object_type
1203 and not type.same_as(other_type)):
1204 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1205 error(type_node.pos, "Previous declaration here")
1207 arg.type = other_type
1210 def need_gil_acquisition(self, lenv):
1213 def create_local_scope(self, env):
1215 while genv.is_py_class_scope or genv.is_c_class_scope:
1216 genv = genv.outer_scope
1217 if self.needs_closure:
1218 lenv = ClosureScope(name=self.entry.name,
1220 scope_name=self.entry.cname)
1222 lenv = LocalScope(name=self.entry.name,
1225 lenv.return_type = self.return_type
1226 type = self.entry.type
1227 if type.is_cfunction:
1228 lenv.nogil = type.nogil and not type.with_gil
1229 self.local_scope = lenv
1230 lenv.directives = env.directives
1233 def generate_function_definitions(self, env, code):
1236 lenv = self.local_scope
1237 if lenv.is_closure_scope and not lenv.is_passthrough:
1238 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1239 Naming.outer_scope_cname)
1241 outer_scope_cname = Naming.outer_scope_cname
1242 lenv.mangle_closure_cnames(outer_scope_cname)
1243 # Generate closure function definitions
1244 self.body.generate_function_definitions(lenv, code)
1245 # generate lambda function definitions
1246 self.generate_lambda_definitions(lenv, code)
1248 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1249 self.entry.scope.is_c_class_scope)
1250 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1251 self.entry.scope.is_c_class_scope)
1252 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1254 if 'cython_unused' not in self.modifiers:
1255 self.modifiers = self.modifiers + ['cython_unused']
1257 preprocessor_guard = None
1258 if self.entry.is_special and not is_buffer_slot:
1259 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1261 preprocessor_guard = slot.preprocessor_guard_code()
1262 if (self.entry.name == '__long__' and
1263 not self.entry.scope.lookup_here('__int__')):
1264 preprocessor_guard = None
1266 profile = code.globalstate.directives['profile']
1269 error(self.pos, "Cannot profile nogil function.")
1270 code.globalstate.use_utility_code(profile_utility_code)
1272 # Generate C code for header and body of function
1273 code.enter_cfunc_scope()
1274 code.return_from_error_cleanup_label = code.new_label()
1276 # ----- Top-level constants used by this function
1277 code.mark_pos(self.pos)
1278 self.generate_cached_builtins_decls(lenv, code)
1279 # ----- Function header
1282 if preprocessor_guard:
1283 code.putln(preprocessor_guard)
1285 with_pymethdef = self.needs_assignment_synthesis(env, code)
1287 self.py_func.generate_function_header(code,
1288 with_pymethdef = with_pymethdef,
1290 self.generate_function_header(code,
1291 with_pymethdef = with_pymethdef)
1292 # ----- Local variable declarations
1293 # Find function scope
1295 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1296 cenv = cenv.outer_scope
1297 if self.needs_closure:
1298 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1300 elif self.needs_outer_scope:
1301 if lenv.is_passthrough:
1302 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1304 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1306 self.generate_argument_declarations(lenv, code)
1307 for entry in lenv.var_entries:
1308 if not entry.in_closure:
1309 code.put_var_declaration(entry)
1311 if not self.return_type.is_void:
1312 if self.return_type.is_pyobject:
1316 (self.return_type.declaration_code(Naming.retval_cname),
1318 tempvardecl_code = code.insertion_point()
1319 self.generate_keyword_list(code)
1321 code.put_trace_declarations()
1322 # ----- Extern library function declarations
1323 lenv.generate_library_function_declarations(code)
1324 # ----- GIL acquisition
1325 acquire_gil = self.acquire_gil
1327 env.use_utility_code(force_init_threads_utility_code)
1328 code.putln("#ifdef WITH_THREAD")
1329 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1330 code.putln("#endif")
1331 # ----- set up refnanny
1333 code.put_setup_refcount_context(self.entry.name)
1334 # ----- Automatic lead-ins for certain special functions
1335 if is_getbuffer_slot:
1336 self.getbuffer_init(code)
1337 # ----- Create closure scope object
1338 if self.needs_closure:
1339 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1340 Naming.cur_scope_cname,
1341 lenv.scope_class.type.declaration_code(''),
1342 lenv.scope_class.type.typeptr_cname,
1343 lenv.scope_class.type.typeptr_cname,
1344 Naming.empty_tuple))
1345 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1346 if is_getbuffer_slot:
1347 self.getbuffer_error_cleanup(code)
1349 code.put_finish_refcount_context()
1350 # FIXME: what if the error return value is a Python value?
1351 code.putln("return %s;" % self.error_value())
1353 code.put_gotref(Naming.cur_scope_cname)
1354 # Note that it is unsafe to decref the scope at this point.
1355 if self.needs_outer_scope:
1356 code.putln("%s = (%s)%s;" % (
1358 cenv.scope_class.type.declaration_code(''),
1360 if lenv.is_passthrough:
1361 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1362 elif self.needs_closure:
1363 # inner closures own a reference to their outer parent
1364 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1365 code.put_giveref(outer_scope_cname)
1366 # ----- Trace function call
1368 # this looks a bit late, but if we don't get here due to a
1369 # fatal error before hand, it's not really worth tracing
1370 code.put_trace_call(self.entry.name, self.pos)
1371 # ----- Fetch arguments
1372 self.generate_argument_parsing_code(env, code)
1373 # If an argument is assigned to in the body, we must
1374 # incref it to properly keep track of refcounts.
1375 for entry in lenv.arg_entries:
1376 if entry.type.is_pyobject:
1377 if (acquire_gil or entry.assignments) and not entry.in_closure:
1378 code.put_var_incref(entry)
1379 # ----- Initialise local variables
1380 for entry in lenv.var_entries:
1381 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1382 code.put_init_var_to_py_none(entry)
1383 # ----- Initialise local buffer auxiliary variables
1384 for entry in lenv.var_entries + lenv.arg_entries:
1385 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1386 code.putln("%s.buf = NULL;" %
1387 entry.buffer_aux.buffer_info_var.cname)
1388 # ----- Check and convert arguments
1389 self.generate_argument_type_tests(code)
1390 # ----- Acquire buffer arguments
1391 for entry in lenv.arg_entries:
1392 if entry.type.is_buffer:
1393 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1395 # -------------------------
1396 # ----- Function body -----
1397 # -------------------------
1398 self.body.generate_execution_code(code)
1400 # ----- Default return value
1402 if self.return_type.is_pyobject:
1403 #if self.return_type.is_extension_type:
1404 # lhs = "(PyObject *)%s" % Naming.retval_cname
1406 lhs = Naming.retval_cname
1407 code.put_init_to_py_none(lhs, self.return_type)
1409 val = self.return_type.default_value
1411 code.putln("%s = %s;" % (Naming.retval_cname, val))
1412 # ----- Error cleanup
1413 if code.error_label in code.labels_used:
1414 code.put_goto(code.return_label)
1415 code.put_label(code.error_label)
1416 for cname, type in code.funcstate.all_managed_temps():
1417 code.put_xdecref(cname, type)
1419 # Clean up buffers -- this calls a Python function
1420 # so need to save and restore error state
1421 buffers_present = len(lenv.buffer_entries) > 0
1423 code.globalstate.use_utility_code(restore_exception_utility_code)
1424 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1425 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1426 for entry in lenv.buffer_entries:
1427 Buffer.put_release_buffer_code(code, entry)
1428 #code.putln("%s = 0;" % entry.cname)
1429 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1431 err_val = self.error_value()
1432 exc_check = self.caller_will_check_exceptions()
1433 if err_val is not None or exc_check:
1434 # TODO: Fix exception tracing (though currently unused by cProfile).
1435 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1436 # code.put_trace_exception()
1437 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1439 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1440 % self.entry.qualified_name, 0)
1442 '__Pyx_WriteUnraisable("%s");' %
1443 self.entry.qualified_name)
1444 env.use_utility_code(unraisable_exception_utility_code)
1445 env.use_utility_code(restore_exception_utility_code)
1446 default_retval = self.return_type.default_value
1447 if err_val is None and default_retval:
1448 err_val = default_retval
1449 if err_val is not None:
1450 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1452 if is_getbuffer_slot:
1453 self.getbuffer_error_cleanup(code)
1455 # If we are using the non-error cleanup section we should
1456 # jump past it if we have an error. The if-test below determine
1457 # whether this section is used.
1458 if buffers_present or is_getbuffer_slot:
1459 code.put_goto(code.return_from_error_cleanup_label)
1462 # ----- Non-error return cleanup
1463 code.put_label(code.return_label)
1464 for entry in lenv.buffer_entries:
1466 Buffer.put_release_buffer_code(code, entry)
1467 if is_getbuffer_slot:
1468 self.getbuffer_normal_cleanup(code)
1469 # ----- Return cleanup for both error and no-error return
1470 code.put_label(code.return_from_error_cleanup_label)
1471 if not Options.init_local_none:
1472 for entry in lenv.var_entries:
1473 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1474 entry.xdecref_cleanup = 1
1476 for entry in lenv.var_entries:
1477 if entry.type.is_pyobject:
1478 if entry.used and not entry.in_closure:
1479 code.put_var_decref(entry)
1480 elif entry.in_closure and self.needs_closure:
1481 code.put_giveref(entry.cname)
1482 # Decref any increfed args
1483 for entry in lenv.arg_entries:
1484 if entry.type.is_pyobject:
1485 if entry.in_closure:
1486 code.put_var_giveref(entry)
1487 elif acquire_gil or entry.assignments:
1488 code.put_var_decref(entry)
1489 if self.needs_closure:
1490 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1493 # This code is duplicated in ModuleNode.generate_module_init_func
1495 default_retval = self.return_type.default_value
1496 err_val = self.error_value()
1497 if err_val is None and default_retval:
1498 err_val = default_retval
1499 if self.return_type.is_pyobject:
1500 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1502 if self.entry.is_special and self.entry.name == "__hash__":
1503 # Returning -1 for __hash__ is supposed to signal an error
1504 # We do as Python instances and coerce -1 into -2.
1505 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1506 Naming.retval_cname, Naming.retval_cname))
1509 if self.return_type.is_pyobject:
1510 code.put_trace_return(Naming.retval_cname)
1512 code.put_trace_return("Py_None")
1514 code.put_finish_refcount_context()
1517 code.putln("#ifdef WITH_THREAD")
1518 code.putln("PyGILState_Release(_save);")
1519 code.putln("#endif")
1521 if not self.return_type.is_void:
1522 code.putln("return %s;" % Naming.retval_cname)
1526 if preprocessor_guard:
1527 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1529 # ----- Go back and insert temp variable declarations
1530 tempvardecl_code.put_temp_declarations(code.funcstate)
1531 # ----- Python version
1532 code.exit_cfunc_scope()
1534 self.py_func.generate_function_definitions(env, code)
1535 self.generate_wrapper_functions(code)
1537 def declare_argument(self, env, arg):
1538 if arg.type.is_void:
1539 error(arg.pos, "Invalid use of 'void'")
1540 elif not arg.type.is_complete() and not arg.type.is_array:
1542 "Argument type '%s' is incomplete" % arg.type)
1543 return env.declare_arg(arg.name, arg.type, arg.pos)
1545 def generate_arg_type_test(self, arg, code):
1546 # Generate type test for one argument.
1547 if arg.type.typeobj_is_available():
1548 code.globalstate.use_utility_code(arg_type_test_utility_code)
1549 typeptr_cname = arg.type.typeptr_cname
1550 arg_code = "((PyObject *)%s)" % arg.entry.cname
1552 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1557 arg.type.is_builtin_type,
1558 code.error_goto(arg.pos)))
1560 error(arg.pos, "Cannot test type of extern C class "
1561 "without type object name specification")
1563 def generate_arg_none_check(self, arg, code):
1564 # Generate None check for one argument.
1565 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1566 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1568 code.error_goto(arg.pos)))
1571 def generate_wrapper_functions(self, code):
1574 def generate_execution_code(self, code):
1575 # Evaluate and store argument default values
1576 for arg in self.args:
1577 default = arg.default
1579 if not default.is_literal:
1580 default.generate_evaluation_code(code)
1581 default.make_owned_reference(code)
1582 result = default.result_as(arg.type)
1585 arg.calculate_default_value_code(code),
1587 if arg.type.is_pyobject:
1588 code.put_giveref(default.result())
1589 default.generate_post_assignment_code(code)
1590 default.free_temps(code)
1591 # For Python class methods, create and store function object
1593 self.assmt.generate_execution_code(code)
1596 # Special code for the __getbuffer__ function
1598 def getbuffer_init(self, code):
1599 info = self.local_scope.arg_entries[1].cname
1600 # Python 3.0 betas have a bug in memoryview which makes it call
1601 # getbuffer with a NULL parameter. For now we work around this;
1602 # the following line should be removed when this bug is fixed.
1603 code.putln("if (%s == NULL) return 0;" % info)
1604 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1605 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1607 def getbuffer_error_cleanup(self, code):
1608 info = self.local_scope.arg_entries[1].cname
1609 code.put_gotref("%s->obj" % info)
1610 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1613 def getbuffer_normal_cleanup(self, code):
1614 info = self.local_scope.arg_entries[1].cname
1615 code.putln("if (%s->obj == Py_None) {" % info)
1616 code.put_gotref("Py_None")
1617 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1620 class CFuncDefNode(FuncDefNode):
1621 # C function definition.
1623 # modifiers ['inline']
1624 # visibility 'private' or 'public' or 'extern'
1625 # base_type CBaseTypeNode
1626 # declarator CDeclaratorNode
1629 # decorators [DecoratorNode] list of decorators
1631 # with_gil boolean Acquire GIL around body
1633 # py_func wrapper for calling from Python
1634 # overridable whether or not this is a cpdef function
1635 # inline_in_pxd whether this is an inline function in a pxd file
1637 child_attrs = ["base_type", "declarator", "body", "py_func"]
1639 inline_in_pxd = False
1641 directive_locals = {}
1643 def unqualified_name(self):
1644 return self.entry.name
1646 def analyse_declarations(self, env):
1647 self.directive_locals.update(env.directives['locals'])
1648 base_type = self.base_type.analyse(env)
1649 # The 2 here is because we need both function and argument names.
1650 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1651 if not type.is_cfunction:
1653 "Suite attached to non-function declaration")
1654 # Remember the actual type according to the function header
1655 # written here, because the type in the symbol table entry
1656 # may be different if we're overriding a C method inherited
1657 # from the base type of an extension type.
1659 type.is_overridable = self.overridable
1660 declarator = self.declarator
1661 while not hasattr(declarator, 'args'):
1662 declarator = declarator.base
1663 self.args = declarator.args
1664 for formal_arg, type_arg in zip(self.args, type.args):
1665 self.align_argument_type(env, type_arg)
1666 formal_arg.type = type_arg.type
1667 formal_arg.name = type_arg.name
1668 formal_arg.cname = type_arg.cname
1669 if type_arg.type.is_buffer and 'inline' in self.modifiers:
1670 warning(formal_arg.pos, "Buffer unpacking not optimized away.", 1)
1671 name = name_declarator.name
1672 cname = name_declarator.cname
1673 self.entry = env.declare_cfunction(
1674 name, type, self.pos,
1675 cname = cname, visibility = self.visibility,
1676 defining = self.body is not None,
1677 api = self.api, modifiers = self.modifiers)
1678 self.entry.inline_func_in_pxd = self.inline_in_pxd
1679 self.return_type = type.return_type
1680 if self.return_type.is_array and visibility != 'extern':
1682 "Function cannot return an array")
1684 if self.overridable and not env.is_module_scope:
1685 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1686 # An error will be produced in the cdef function
1687 self.overridable = False
1689 if self.overridable:
1691 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1692 self.py_func = DefNode(pos = self.pos,
1693 name = self.entry.name,
1696 starstar_arg = None,
1698 body = py_func_body,
1700 self.py_func.is_module_scope = env.is_module_scope
1701 self.py_func.analyse_declarations(env)
1702 self.entry.as_variable = self.py_func.entry
1703 # Reset scope entry the above cfunction
1704 env.entries[name] = self.entry
1705 if not env.is_module_scope or Options.lookup_module_cpdef:
1706 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1707 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1708 self.create_local_scope(env)
1710 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1712 args = self.type.args
1713 if omit_optional_args:
1714 args = args[:len(args) - self.type.optional_arg_count]
1715 arg_names = [arg.name for arg in args]
1717 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1719 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1720 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1721 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1722 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)
1723 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1725 def declare_arguments(self, env):
1726 for arg in self.type.args:
1728 error(arg.pos, "Missing argument name")
1729 self.declare_argument(env, arg)
1731 def need_gil_acquisition(self, lenv):
1732 return self.type.with_gil
1734 def nogil_check(self, env):
1736 with_gil = type.with_gil
1737 if type.nogil and not with_gil:
1738 if type.return_type.is_pyobject:
1740 "Function with Python return type cannot be declared nogil")
1741 for entry in self.local_scope.var_entries:
1742 if entry.type.is_pyobject:
1743 error(self.pos, "Function declared nogil has Python locals or temporaries")
1745 def analyse_expressions(self, env):
1746 self.local_scope.directives = env.directives
1747 if self.py_func is not None:
1748 # this will also analyse the default values
1749 self.py_func.analyse_expressions(env)
1751 self.analyse_default_values(env)
1752 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1754 def needs_assignment_synthesis(self, env, code=None):
1757 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1760 visibility = self.entry.visibility
1761 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1762 arg_decls.append(arg.declaration_code())
1763 if with_dispatch and self.overridable:
1764 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1765 if type.optional_arg_count and with_opt_args:
1766 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1767 if type.has_varargs:
1768 arg_decls.append("...")
1770 arg_decls = ["void"]
1772 cname = self.entry.func_cname
1773 entity = type.function_header_code(cname, ', '.join(arg_decls))
1774 if visibility == 'public':
1775 dll_linkage = "DL_EXPORT"
1778 header = self.return_type.declaration_code(entity,
1779 dll_linkage = dll_linkage)
1780 if visibility == 'extern':
1781 storage_class = "%s " % Naming.extern_c_macro
1782 elif visibility == 'public':
1785 storage_class = "static "
1786 if 'inline' in self.modifiers:
1787 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1788 code.putln("%s%s %s {" % (
1790 ' '.join(self.modifiers).upper(), # macro forms
1793 def generate_argument_declarations(self, env, code):
1794 for arg in self.args:
1796 result = arg.calculate_default_value_code(code)
1797 code.putln('%s = %s;' % (
1798 arg.type.declaration_code(arg.cname), result))
1800 def generate_keyword_list(self, code):
1803 def generate_argument_parsing_code(self, env, code):
1805 if self.type.optional_arg_count:
1806 code.putln('if (%s) {' % Naming.optional_args_cname)
1807 for arg in self.args:
1809 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1810 declarator = arg.declarator
1811 while not hasattr(declarator, 'name'):
1812 declarator = declarator.base
1813 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1815 for _ in range(self.type.optional_arg_count):
1819 def generate_argument_conversion_code(self, code):
1822 def generate_argument_type_tests(self, code):
1823 # Generate type tests for args whose type in a parent
1824 # class is a supertype of the declared type.
1825 for arg in self.type.args:
1826 if arg.needs_type_test:
1827 self.generate_arg_type_test(arg, code)
1828 elif arg.type.is_pyobject and not arg.accept_none:
1829 self.generate_arg_none_check(arg, code)
1831 def error_value(self):
1832 if self.return_type.is_pyobject:
1836 return self.entry.type.exception_value
1838 def caller_will_check_exceptions(self):
1839 return self.entry.type.exception_check
1841 def generate_wrapper_functions(self, code):
1842 # If the C signature of a function has changed, we need to generate
1843 # wrappers to put in the slots here.
1846 func_type = entry.type
1847 while entry.prev_entry is not None:
1849 entry = entry.prev_entry
1850 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1852 self.generate_function_header(code,
1854 with_dispatch = entry.type.is_overridable,
1855 with_opt_args = entry.type.optional_arg_count,
1856 cname = entry.func_cname)
1857 if not self.return_type.is_void:
1859 args = self.type.args
1860 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1861 if entry.type.is_overridable:
1862 arglist.append(Naming.skip_dispatch_cname)
1863 elif func_type.is_overridable:
1865 if entry.type.optional_arg_count:
1866 arglist.append(Naming.optional_args_cname)
1867 elif func_type.optional_arg_count:
1868 arglist.append('NULL')
1869 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1873 class PyArgDeclNode(Node):
1874 # Argument which must be a Python object (used
1875 # for * and ** arguments).
1878 # entry Symtab.Entry
1879 # annotation ExprNode or None Py3 argument annotation
1882 def generate_function_definitions(self, env, code):
1883 self.entry.generate_function_definitions(env, code)
1885 class DecoratorNode(Node):
1888 # decorator NameNode or CallNode or AttributeNode
1889 child_attrs = ['decorator']
1892 class DefNode(FuncDefNode):
1893 # A Python function definition.
1895 # name string the Python name of the function
1896 # lambda_name string the internal name of a lambda 'function'
1897 # decorators [DecoratorNode] list of decorators
1898 # args [CArgDeclNode] formal arguments
1899 # star_arg PyArgDeclNode or None * argument
1900 # starstar_arg PyArgDeclNode or None ** argument
1901 # doc EncodedString or None
1903 # return_type_annotation
1904 # ExprNode or None the Py3 return type annotation
1906 # The following subnode is constructed internally
1907 # when the def statement is inside a Python class definition.
1909 # assmt AssignmentNode Function construction/assignment
1911 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1916 num_required_kw_args = 0
1917 reqd_kw_flags_cname = "0"
1920 return_type_annotation = None
1928 def __init__(self, pos, **kwds):
1929 FuncDefNode.__init__(self, pos, **kwds)
1931 for arg in self.args:
1938 self.num_kwonly_args = k
1939 self.num_required_kw_args = rk
1940 self.num_required_args = r
1942 def as_cfunction(self, cfunc=None, scope=None):
1944 error(self.star_arg.pos, "cdef function cannot have star argument")
1945 if self.starstar_arg:
1946 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1949 for formal_arg in self.args:
1950 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1951 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1953 type = py_object_type,
1954 pos = formal_arg.pos))
1955 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1957 has_varargs = False,
1958 exception_value = None,
1959 exception_check = False,
1962 is_overridable = True)
1963 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1967 cfunc_type = cfunc.type
1968 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1969 error(self.pos, "wrong number of arguments")
1970 error(cfunc.pos, "previous declaration here")
1971 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1972 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1973 is_self_arg = (i == 0 and scope.is_c_class_scope))
1974 if type is None or type is PyrexTypes.py_object_type:
1975 formal_arg.type = type_arg.type
1976 formal_arg.name_declarator = name_declarator
1978 if cfunc_type.exception_value is None:
1979 exception_value = None
1981 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1982 declarator = CFuncDeclaratorNode(self.pos,
1983 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1985 has_varargs = False,
1986 exception_check = cfunc_type.exception_check,
1987 exception_value = exception_value,
1988 with_gil = cfunc_type.with_gil,
1989 nogil = cfunc_type.nogil)
1990 return CFuncDefNode(self.pos,
1992 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1993 declarator = declarator,
1996 overridable = cfunc_type.is_overridable,
1998 with_gil = cfunc_type.with_gil,
1999 nogil = cfunc_type.nogil,
2000 visibility = 'private',
2002 directive_locals = getattr(cfunc, 'directive_locals', {}))
2004 def analyse_declarations(self, env):
2005 self.is_classmethod = self.is_staticmethod = False
2007 for decorator in self.decorators:
2008 func = decorator.decorator
2010 self.is_classmethod |= func.name == 'classmethod'
2011 self.is_staticmethod |= func.name == 'staticmethod'
2013 if self.is_classmethod and env.lookup_here('classmethod'):
2014 # classmethod() was overridden - not much we can do here ...
2015 self.is_classmethod = False
2016 if self.is_staticmethod and env.lookup_here('staticmethod'):
2017 # staticmethod() was overridden - not much we can do here ...
2018 self.is_staticmethod = False
2020 if self.name == '__new__' and env.is_py_class_scope:
2021 self.is_staticmethod = 1
2023 self.analyse_argument_types(env)
2024 if self.name == '<lambda>':
2025 self.declare_lambda_function(env)
2027 self.declare_pyfunction(env)
2028 self.analyse_signature(env)
2029 self.return_type = self.entry.signature.return_type()
2030 self.create_local_scope(env)
2032 def analyse_argument_types(self, env):
2033 directive_locals = self.directive_locals = env.directives['locals']
2034 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2035 for arg in self.args:
2036 if hasattr(arg, 'name'):
2037 name_declarator = None
2039 base_type = arg.base_type.analyse(env)
2040 name_declarator, type = \
2041 arg.declarator.analyse(base_type, env)
2042 arg.name = name_declarator.name
2044 self.align_argument_type(env, arg)
2045 if name_declarator and name_declarator.cname:
2047 "Python function argument cannot have C name specification")
2048 arg.type = arg.type.as_argument_type()
2050 arg.needs_conversion = 0
2051 arg.needs_type_test = 0
2053 if arg.type.is_pyobject:
2055 arg.accept_none = True
2057 arg.accept_none = False
2058 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2059 if arg.default and arg.default.constant_result is None:
2060 # special case: def func(MyType obj = None)
2061 arg.accept_none = True
2063 # default depends on compiler directive
2064 arg.accept_none = allow_none_for_extension_args
2066 # probably just a plain 'object'
2067 arg.accept_none = True
2069 arg.accept_none = True # won't be used, but must be there
2071 error(arg.pos, "Only Python type arguments can have 'not None'")
2073 error(arg.pos, "Only Python type arguments can have 'or None'")
2075 def analyse_signature(self, env):
2076 if self.entry.is_special:
2078 error(self.pos, "special functions of cdef classes cannot have decorators")
2079 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2080 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2081 # Use the simpler calling signature for zero- and one-argument functions.
2082 if self.entry.signature is TypeSlots.pyfunction_signature:
2083 if len(self.args) == 0:
2084 self.entry.signature = TypeSlots.pyfunction_noargs
2085 elif len(self.args) == 1:
2086 if self.args[0].default is None and not self.args[0].kw_only:
2087 self.entry.signature = TypeSlots.pyfunction_onearg
2088 elif self.entry.signature is TypeSlots.pymethod_signature:
2089 if len(self.args) == 1:
2090 self.entry.signature = TypeSlots.unaryfunc
2091 elif len(self.args) == 2:
2092 if self.args[1].default is None and not self.args[1].kw_only:
2093 self.entry.signature = TypeSlots.ibinaryfunc
2095 sig = self.entry.signature
2096 nfixed = sig.num_fixed_args()
2097 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2098 and len(self.args) == 0 and self.star_arg:
2099 # this is the only case where a diverging number of
2100 # arguments is not an error - when we have no explicit
2101 # 'self' parameter as in method(*args)
2102 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2103 self.self_in_stararg = 1
2106 for i in range(min(nfixed, len(self.args))):
2109 if sig.is_self_arg(i) and not self.is_staticmethod:
2110 if self.is_classmethod:
2112 arg.hdr_type = arg.type = Builtin.type_type
2115 arg.hdr_type = arg.type = env.parent_type
2116 arg.needs_conversion = 0
2118 arg.hdr_type = sig.fixed_arg_type(i)
2119 if not arg.type.same_as(arg.hdr_type):
2120 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2121 arg.needs_type_test = 1
2123 arg.needs_conversion = 1
2124 if arg.needs_conversion:
2125 arg.hdr_cname = Naming.arg_prefix + arg.name
2127 arg.hdr_cname = Naming.var_prefix + arg.name
2129 if nfixed > len(self.args):
2130 self.bad_signature()
2132 elif nfixed < len(self.args):
2133 if not sig.has_generic_args:
2134 self.bad_signature()
2135 for arg in self.args:
2136 if arg.is_generic and \
2137 (arg.type.is_extension_type or arg.type.is_builtin_type):
2138 arg.needs_type_test = 1
2140 def bad_signature(self):
2141 sig = self.entry.signature
2142 expected_str = "%d" % sig.num_fixed_args()
2143 if sig.has_generic_args:
2144 expected_str = expected_str + " or more"
2146 if name.startswith("__") and name.endswith("__"):
2147 desc = "Special method"
2151 "%s %s has wrong number of arguments "
2152 "(%d declared, %s expected)" % (
2153 desc, self.name, len(self.args), expected_str))
2155 def signature_has_nongeneric_args(self):
2156 argcount = len(self.args)
2157 if argcount == 0 or (
2158 argcount == 1 and (self.args[0].is_self_arg or
2159 self.args[0].is_type_arg)):
2163 def signature_has_generic_args(self):
2164 return self.entry.signature.has_generic_args
2166 def declare_pyfunction(self, env):
2167 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2169 entry = env.lookup_here(name)
2170 if entry and entry.type.is_cfunction and not self.is_wrapper:
2171 warning(self.pos, "Overriding cdef method with def method.", 5)
2172 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2174 prefix = env.next_id(env.scope_prefix)
2176 entry.func_cname = \
2177 Naming.pyfunc_prefix + prefix + name
2178 entry.pymethdef_cname = \
2179 Naming.pymethdef_prefix + prefix + name
2180 if Options.docstrings:
2181 entry.doc = embed_position(self.pos, self.doc)
2183 Naming.funcdoc_prefix + prefix + name
2184 if entry.is_special:
2185 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2186 entry.wrapperbase_cname = None
2188 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2192 def declare_lambda_function(self, env):
2194 prefix = env.scope_prefix
2196 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2197 entry = env.declare_lambda_function(func_cname, self.pos)
2198 entry.pymethdef_cname = \
2199 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2200 entry.qualified_name = env.qualify_name(self.lambda_name)
2204 def declare_arguments(self, env):
2205 for arg in self.args:
2207 error(arg.pos, "Missing argument name")
2209 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2210 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2211 if arg.needs_conversion:
2212 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2213 if arg.type.is_pyobject:
2214 arg.entry.init = "0"
2215 arg.entry.init_to_none = 0
2217 arg.entry = self.declare_argument(env, arg)
2219 arg.entry.is_self_arg = arg.is_self_arg
2221 if arg.is_self_arg or arg.is_type_arg or \
2222 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2223 arg.entry.is_declared_generic = 1
2224 self.declare_python_arg(env, self.star_arg)
2225 self.declare_python_arg(env, self.starstar_arg)
2227 def declare_python_arg(self, env, arg):
2229 if env.directives['infer_types'] != False:
2230 type = PyrexTypes.unspecified_type
2232 type = py_object_type
2233 entry = env.declare_var(arg.name, type, arg.pos)
2236 entry.init_to_none = 0
2237 entry.xdecref_cleanup = 1
2239 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2241 def analyse_expressions(self, env):
2242 self.local_scope.directives = env.directives
2243 self.analyse_default_values(env)
2244 if self.needs_assignment_synthesis(env):
2245 # Shouldn't we be doing this at the module level too?
2246 self.synthesize_assignment_node(env)
2248 def needs_assignment_synthesis(self, env, code=None):
2249 # Should enable for module level as well, that will require more testing...
2250 if self.entry.is_anonymous:
2252 if env.is_module_scope:
2254 return env.directives['binding']
2256 return code.globalstate.directives['binding']
2257 return env.is_py_class_scope or env.is_closure_scope
2259 def synthesize_assignment_node(self, env):
2262 while genv.is_py_class_scope or genv.is_c_class_scope:
2263 genv = genv.outer_scope
2265 if genv.is_closure_scope:
2266 rhs = ExprNodes.InnerFunctionNode(
2267 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2269 rhs = ExprNodes.PyCFunctionNode(
2270 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2272 if env.is_py_class_scope:
2273 if not self.is_staticmethod and not self.is_classmethod:
2276 self.assmt = SingleAssignmentNode(self.pos,
2277 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2279 self.assmt.analyse_declarations(env)
2280 self.assmt.analyse_expressions(env)
2282 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2284 sig = self.entry.signature
2285 if sig.has_dummy_arg or self.self_in_stararg:
2286 arg_code_list.append(
2287 "PyObject *%s" % Naming.self_cname)
2288 for arg in self.args:
2289 if not arg.is_generic:
2290 if arg.is_self_arg or arg.is_type_arg:
2291 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2293 arg_code_list.append(
2294 arg.hdr_type.declaration_code(arg.hdr_cname))
2295 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2296 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2297 if (self.entry.scope.is_c_class_scope and self.entry.name == "__ipow__"):
2298 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2299 if sig.has_generic_args:
2300 arg_code_list.append(
2301 "PyObject *%s, PyObject *%s"
2302 % (Naming.args_cname, Naming.kwds_cname))
2303 arg_code = ", ".join(arg_code_list)
2304 dc = self.return_type.declaration_code(self.entry.func_cname)
2305 mf = " ".join(self.modifiers).upper()
2307 header = "static %s%s(%s)" % (mf, dc, arg_code)
2308 code.putln("%s; /*proto*/" % header)
2311 if (Options.docstrings and self.entry.doc and
2312 not self.entry.scope.is_property_scope and
2313 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2314 docstr = self.entry.doc
2315 if docstr.is_unicode:
2316 docstr = docstr.utf8encode()
2318 'static char %s[] = "%s";' % (
2319 self.entry.doc_cname,
2320 split_string_literal(escape_byte_string(docstr))))
2321 if self.entry.is_special:
2323 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2326 "static PyMethodDef %s = " %
2327 self.entry.pymethdef_cname)
2328 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2329 code.putln("%s {" % header)
2331 def generate_argument_declarations(self, env, code):
2332 for arg in self.args:
2333 if arg.is_generic: # or arg.needs_conversion:
2334 if arg.needs_conversion:
2335 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2336 elif not arg.entry.in_closure:
2337 code.put_var_declaration(arg.entry)
2339 def generate_keyword_list(self, code):
2340 if self.signature_has_generic_args() and \
2341 self.signature_has_nongeneric_args():
2343 "static PyObject **%s[] = {" %
2344 Naming.pykwdlist_cname)
2345 for arg in self.args:
2347 pystring_cname = code.intern_identifier(arg.name)
2348 code.put('&%s,' % pystring_cname)
2351 def generate_argument_parsing_code(self, env, code):
2352 # Generate PyArg_ParseTuple call for generic
2353 # arguments, if any.
2354 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2355 # get rid of unused argument warning
2356 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2358 old_error_label = code.new_error_label()
2359 our_error_label = code.error_label
2360 end_label = code.new_label("argument_unpacking_done")
2362 has_kwonly_args = self.num_kwonly_args > 0
2363 has_star_or_kw_args = self.star_arg is not None \
2364 or self.starstar_arg is not None or has_kwonly_args
2366 for arg in self.args:
2367 if not arg.type.is_pyobject:
2368 done = arg.type.create_from_py_utility_code(env)
2369 if not done: pass # will fail later
2371 if not self.signature_has_generic_args():
2372 if has_star_or_kw_args:
2373 error(self.pos, "This method cannot have * or keyword arguments")
2374 self.generate_argument_conversion_code(code)
2376 elif not self.signature_has_nongeneric_args():
2377 # func(*args) or func(**kw) or func(*args, **kw)
2378 self.generate_stararg_copy_code(code)
2381 positional_args = []
2383 for arg in self.args:
2384 arg_entry = arg.entry
2387 if not arg.is_self_arg and not arg.is_type_arg:
2389 kw_only_args.append(arg)
2391 positional_args.append(arg)
2393 kw_only_args.append(arg)
2394 elif not arg.is_self_arg and not arg.is_type_arg:
2395 positional_args.append(arg)
2397 self.generate_tuple_and_keyword_parsing_code(
2398 positional_args, kw_only_args, end_label, code)
2400 code.error_label = old_error_label
2401 if code.label_used(our_error_label):
2402 if not code.label_used(end_label):
2403 code.put_goto(end_label)
2404 code.put_label(our_error_label)
2405 if has_star_or_kw_args:
2406 self.generate_arg_decref(self.star_arg, code)
2407 if self.starstar_arg:
2408 if self.starstar_arg.entry.xdecref_cleanup:
2409 code.put_var_xdecref_clear(self.starstar_arg.entry)
2411 code.put_var_decref_clear(self.starstar_arg.entry)
2412 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2413 # The arguments are put into the closure one after the
2414 # other, so when type errors are found, all references in
2415 # the closure instance must be properly ref-counted to
2416 # facilitate generic closure instance deallocation. In
2417 # the case of an argument type error, it's best to just
2418 # DECREF+clear the already handled references, as this
2419 # frees their references as early as possible.
2420 for arg in self.args:
2421 if arg.type.is_pyobject and arg.entry.in_closure:
2422 code.put_var_xdecref_clear(arg.entry)
2423 if self.needs_closure:
2424 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2425 code.put_finish_refcount_context()
2426 code.putln("return %s;" % self.error_value())
2427 if code.label_used(end_label):
2428 code.put_label(end_label)
2430 def generate_arg_assignment(self, arg, item, code):
2431 if arg.type.is_pyobject:
2433 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2435 code.putln("%s = %s;" % (entry.cname, item))
2436 if entry.in_closure:
2437 code.put_var_incref(entry)
2439 func = arg.type.from_py_function
2441 code.putln("%s = %s(%s); %s" % (
2445 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2447 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2449 def generate_arg_xdecref(self, arg, code):
2451 code.put_var_xdecref_clear(arg.entry)
2453 def generate_arg_decref(self, arg, code):
2455 code.put_var_decref_clear(arg.entry)
2457 def generate_stararg_copy_code(self, code):
2458 if not self.star_arg:
2459 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2460 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2462 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2463 self.name, Naming.args_cname, self.error_value()))
2466 if self.starstar_arg:
2468 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2470 kwarg_check = "%s" % Naming.kwds_cname
2472 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2473 Naming.kwds_cname, Naming.kwds_cname)
2474 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2476 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2477 kwarg_check, Naming.kwds_cname, self.name,
2478 bool(self.starstar_arg), self.error_value()))
2480 if self.starstar_arg:
2481 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2482 self.starstar_arg.entry.cname,
2485 code.putln("if (unlikely(!%s)) return %s;" % (
2486 self.starstar_arg.entry.cname, self.error_value()))
2487 self.starstar_arg.entry.xdecref_cleanup = 0
2488 code.put_gotref(self.starstar_arg.entry.cname)
2490 if self.self_in_stararg:
2491 # need to create a new tuple with 'self' inserted as first item
2492 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2493 self.star_arg.entry.cname,
2495 self.star_arg.entry.cname))
2496 if self.starstar_arg:
2498 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2499 code.putln("return %s;" % self.error_value())
2502 code.putln("return %s;" % self.error_value())
2503 code.put_gotref(self.star_arg.entry.cname)
2504 code.put_incref(Naming.self_cname, py_object_type)
2505 code.put_giveref(Naming.self_cname)
2506 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2507 self.star_arg.entry.cname, Naming.self_cname))
2508 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2509 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2510 temp, temp, Naming.args_cname, temp))
2511 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2512 Naming.args_cname, temp))
2513 code.put_incref("item", py_object_type)
2514 code.put_giveref("item")
2515 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2516 self.star_arg.entry.cname, temp))
2518 code.funcstate.release_temp(temp)
2519 self.star_arg.entry.xdecref_cleanup = 0
2521 code.put_incref(Naming.args_cname, py_object_type)
2522 code.putln("%s = %s;" % (
2523 self.star_arg.entry.cname,
2525 self.star_arg.entry.xdecref_cleanup = 0
2527 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2528 kw_only_args, success_label, code):
2529 argtuple_error_label = code.new_label("argtuple_error")
2531 min_positional_args = self.num_required_args - self.num_required_kw_args
2532 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2533 min_positional_args -= 1
2534 max_positional_args = len(positional_args)
2535 has_fixed_positional_count = not self.star_arg and \
2536 min_positional_args == max_positional_args
2538 if self.num_required_kw_args:
2539 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2541 if self.starstar_arg or self.star_arg:
2542 self.generate_stararg_init_code(max_positional_args, code)
2544 # --- optimised code when we receive keyword arguments
2545 if self.num_required_kw_args:
2546 likely_hint = "likely"
2548 likely_hint = "unlikely"
2549 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2550 self.generate_keyword_unpacking_code(
2551 min_positional_args, max_positional_args,
2552 has_fixed_positional_count,
2553 positional_args, kw_only_args, argtuple_error_label, code)
2555 # --- optimised code when we do not receive any keyword arguments
2556 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2557 # Python raises arg tuple related errors first, so we must
2558 # check the length here
2559 if min_positional_args == max_positional_args and not self.star_arg:
2563 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2564 Naming.args_cname, compare, min_positional_args))
2565 code.put_goto(argtuple_error_label)
2567 if self.num_required_kw_args:
2568 # pure error case: keywords required but not passed
2569 if max_positional_args > min_positional_args and not self.star_arg:
2570 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2571 Naming.args_cname, max_positional_args))
2572 code.put_goto(argtuple_error_label)
2573 code.putln('} else {')
2574 for i, arg in enumerate(kw_only_args):
2576 pystring_cname = code.intern_identifier(arg.name)
2577 # required keyword-only argument missing
2578 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2581 code.putln(code.error_goto(self.pos))
2584 elif min_positional_args == max_positional_args:
2585 # parse the exact number of positional arguments from the
2587 code.putln('} else {')
2588 for i, arg in enumerate(positional_args):
2589 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2590 self.generate_arg_assignment(arg, item, code)
2591 self.generate_arg_default_assignments(code)
2594 # parse the positional arguments from the variable length
2596 code.putln('} else {')
2597 self.generate_arg_default_assignments(code)
2598 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2600 code.putln('default:')
2601 reversed_args = list(enumerate(positional_args))[::-1]
2602 for i, arg in reversed_args:
2603 if i >= min_positional_args-1:
2604 if min_positional_args > 1:
2605 code.putln('case %2d:' % (i+1)) # pure code beautification
2607 code.put('case %2d: ' % (i+1))
2608 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2609 self.generate_arg_assignment(arg, item, code)
2610 if min_positional_args == 0:
2611 code.put('case 0: ')
2612 code.putln('break;')
2614 if min_positional_args:
2615 for i in range(min_positional_args-1, -1, -1):
2616 code.putln('case %2d:' % i)
2617 code.put_goto(argtuple_error_label)
2619 code.put('default: ')
2620 code.put_goto(argtuple_error_label)
2625 if code.label_used(argtuple_error_label):
2626 code.put_goto(success_label)
2627 code.put_label(argtuple_error_label)
2628 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2629 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2630 self.name, has_fixed_positional_count,
2631 min_positional_args, max_positional_args,
2633 code.putln(code.error_goto(self.pos))
2635 def generate_arg_default_assignments(self, code):
2636 for arg in self.args:
2637 if arg.is_generic and arg.default:
2641 arg.calculate_default_value_code(code)))
2643 def generate_stararg_init_code(self, max_positional_args, code):
2644 if self.starstar_arg:
2645 self.starstar_arg.entry.xdecref_cleanup = 0
2646 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2647 self.starstar_arg.entry.cname,
2648 self.starstar_arg.entry.cname,
2649 self.error_value()))
2650 code.put_gotref(self.starstar_arg.entry.cname)
2652 self.star_arg.entry.xdecref_cleanup = 0
2653 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2655 max_positional_args))
2656 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2657 self.star_arg.entry.cname, Naming.args_cname,
2658 max_positional_args, Naming.args_cname))
2659 code.put_gotref(self.star_arg.entry.cname)
2660 if self.starstar_arg:
2662 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2663 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2664 code.putln('return %s;' % self.error_value())
2667 code.putln("if (unlikely(!%s)) return %s;" % (
2668 self.star_arg.entry.cname, self.error_value()))
2669 code.putln('} else {')
2670 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2671 code.put_incref(Naming.empty_tuple, py_object_type)
2674 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2675 has_fixed_positional_count, positional_args,
2676 kw_only_args, argtuple_error_label, code):
2677 all_args = tuple(positional_args) + tuple(kw_only_args)
2678 max_args = len(all_args)
2680 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2682 # the 'values' array collects borrowed references to arguments
2683 # before doing any type coercion etc.
2684 code.putln("PyObject* values[%d] = {%s};" % (
2685 max_args, ','.join('0'*max_args)))
2687 # assign borrowed Python default values to the values array,
2688 # so that they can be overwritten by received arguments below
2689 for i, arg in enumerate(all_args):
2690 if arg.default and arg.type.is_pyobject:
2691 default_value = arg.calculate_default_value_code(code)
2692 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2694 # parse the args tuple and check that it's not too long
2695 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2697 code.putln('default:')
2698 for i in range(max_positional_args-1, -1, -1):
2699 code.put('case %2d: ' % (i+1))
2700 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2701 i, Naming.args_cname, i))
2702 code.putln('case 0: break;')
2703 if not self.star_arg:
2704 code.put('default: ') # more arguments than allowed
2705 code.put_goto(argtuple_error_label)
2708 # now fill up the positional/required arguments with values
2710 if self.num_required_args or max_positional_args > 0:
2711 last_required_arg = -1
2712 for i, arg in enumerate(all_args):
2714 last_required_arg = i
2715 if last_required_arg < max_positional_args:
2716 last_required_arg = max_positional_args-1
2717 num_required_args = self.num_required_args
2718 if max_positional_args > 0:
2719 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2720 for i, arg in enumerate(all_args[:last_required_arg+1]):
2721 if max_positional_args > 0 and i <= max_positional_args:
2722 if self.star_arg and i == max_positional_args:
2723 code.putln('default:')
2725 code.putln('case %2d:' % i)
2726 pystring_cname = code.intern_identifier(arg.name)
2729 # handled separately below
2731 code.putln('if (kw_args > 0) {')
2732 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2733 Naming.kwds_cname, pystring_cname))
2734 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2737 num_required_args -= 1
2738 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2739 i, Naming.kwds_cname, pystring_cname))
2740 code.putln('if (likely(values[%d])) kw_args--;' % i);
2741 if i < min_positional_args:
2743 # special case: we know arg 0 is missing
2745 code.put_goto(argtuple_error_label)
2747 # print the correct number of values (args or
2748 # kwargs) that were passed into positional
2749 # arguments up to this point
2750 code.putln('else {')
2751 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2752 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2753 self.name, has_fixed_positional_count,
2754 min_positional_args, max_positional_args, i))
2755 code.putln(code.error_goto(self.pos))
2758 code.putln('else {')
2759 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2760 self.name, pystring_cname))
2761 code.putln(code.error_goto(self.pos))
2763 if max_positional_args > 0:
2766 if kw_only_args and not self.starstar_arg:
2767 # unpack optional keyword-only arguments
2768 # checking for interned strings in a dict is faster than iterating
2769 # but it's too likely that we must iterate if we expect **kwargs
2771 for i, arg in enumerate(all_args[max_positional_args:]):
2772 if not arg.kw_only or not arg.default:
2774 optional_args.append((i+max_positional_args, arg))
2776 # this mimics an unrolled loop so that we can "break" out of it
2777 code.putln('while (kw_args > 0) {')
2778 code.putln('PyObject* value;')
2779 for i, arg in optional_args:
2780 pystring_cname = code.intern_identifier(arg.name)
2782 'value = PyDict_GetItem(%s, %s);' % (
2783 Naming.kwds_cname, pystring_cname))
2785 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2786 code.putln('break;')
2789 code.putln('if (unlikely(kw_args > 0)) {')
2790 # non-positional/-required kw args left in dict: default args,
2791 # kw-only args, **kwargs or error
2793 # This is sort of a catch-all: except for checking required
2794 # arguments, this will always do the right thing for unpacking
2795 # keyword arguments, so that we can concentrate on optimising
2796 # common cases above.
2797 if max_positional_args == 0:
2800 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2801 Naming.args_cname, max_positional_args,
2802 Naming.args_cname, max_positional_args))
2803 pos_arg_count = "used_pos_args"
2805 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2806 code.globalstate.use_utility_code(parse_keywords_utility_code)
2808 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2810 Naming.pykwdlist_cname,
2811 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2814 code.putln(code.error_goto(self.pos))
2817 # convert arg values to their final type and assign them
2818 for i, arg in enumerate(all_args):
2819 if arg.default and not arg.type.is_pyobject:
2820 code.putln("if (values[%d]) {" % i)
2821 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2822 if arg.default and not arg.type.is_pyobject:
2823 code.putln('} else {')
2827 arg.calculate_default_value_code(code)))
2830 def generate_argument_conversion_code(self, code):
2831 # Generate code to convert arguments from signature type to
2832 # declared type, if needed. Also copies signature arguments
2833 # into closure fields.
2834 for arg in self.args:
2835 if arg.needs_conversion:
2836 self.generate_arg_conversion(arg, code)
2837 elif arg.entry.in_closure:
2838 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2839 if arg.type.is_pyobject:
2840 code.put_var_incref(arg.entry)
2842 def generate_arg_conversion(self, arg, code):
2843 # Generate conversion code for one argument.
2844 old_type = arg.hdr_type
2846 if old_type.is_pyobject:
2848 code.putln("if (%s) {" % arg.hdr_cname)
2850 code.putln("assert(%s); {" % arg.hdr_cname)
2851 self.generate_arg_conversion_from_pyobject(arg, code)
2853 elif new_type.is_pyobject:
2854 self.generate_arg_conversion_to_pyobject(arg, code)
2856 if new_type.assignable_from(old_type):
2858 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2861 "Cannot convert 1 argument from '%s' to '%s'" %
2862 (old_type, new_type))
2864 def generate_arg_conversion_from_pyobject(self, arg, code):
2866 func = new_type.from_py_function
2867 # copied from CoerceFromPyTypeNode
2869 lhs = arg.entry.cname
2870 rhs = "%s(%s)" % (func, arg.hdr_cname)
2871 if new_type.is_enum:
2872 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2873 code.putln("%s = %s; %s" % (
2876 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2879 "Cannot convert Python object argument to type '%s'"
2882 def generate_arg_conversion_to_pyobject(self, arg, code):
2883 old_type = arg.hdr_type
2884 func = old_type.to_py_function
2886 code.putln("%s = %s(%s); %s" % (
2890 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2891 code.put_var_gotref(arg.entry)
2894 "Cannot convert argument of type '%s' to Python object"
2897 def generate_argument_type_tests(self, code):
2898 # Generate type tests for args whose signature
2899 # type is PyObject * and whose declared type is
2900 # a subtype thereof.
2901 for arg in self.args:
2902 if arg.needs_type_test:
2903 self.generate_arg_type_test(arg, code)
2904 elif not arg.accept_none and arg.type.is_pyobject:
2905 self.generate_arg_none_check(arg, code)
2907 def error_value(self):
2908 return self.entry.signature.error_value
2910 def caller_will_check_exceptions(self):
2913 class OverrideCheckNode(StatNode):
2914 # A Node for dispatching to the def method if it
2923 child_attrs = ['body']
2927 def analyse_expressions(self, env):
2928 self.args = env.arg_entries
2929 if self.py_func.is_module_scope:
2934 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2935 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2936 call_node = ExprNodes.SimpleCallNode(self.pos,
2937 function=self.func_node,
2938 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2939 self.body = ReturnStatNode(self.pos, value=call_node)
2940 self.body.analyse_expressions(env)
2942 def generate_execution_code(self, code):
2943 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2944 # Check to see if we are an extension type
2945 if self.py_func.is_module_scope:
2946 self_arg = "((PyObject *)%s)" % Naming.module_cname
2948 self_arg = "((PyObject *)%s)" % self.args[0].cname
2949 code.putln("/* Check if called by wrapper */")
2950 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2951 code.putln("/* Check if overriden in Python */")
2952 if self.py_func.is_module_scope:
2953 code.putln("else {")
2955 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2956 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2957 self.func_node.set_cname(func_node_temp)
2958 # need to get attribute manually--scope would return cdef method
2959 err = code.error_goto_if_null(func_node_temp, self.pos)
2960 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2961 func_node_temp, self_arg, interned_attr_cname, err))
2962 code.put_gotref(func_node_temp)
2963 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2964 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2965 func_node_temp, self.py_func.entry.func_cname)
2966 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2967 self.body.generate_execution_code(code)
2969 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2970 code.funcstate.release_temp(func_node_temp)
2973 class ClassDefNode(StatNode, BlockNode):
2976 class PyClassDefNode(ClassDefNode):
2977 # A Python class definition.
2979 # name EncodedString Name of the class
2980 # doc string or None
2981 # body StatNode Attribute definition code
2982 # entry Symtab.Entry
2983 # scope PyClassScope
2984 # decorators [DecoratorNode] list of decorators or None
2986 # The following subnodes are constructed internally:
2988 # dict DictNode Class dictionary or Py3 namespace
2989 # classobj ClassNode Class object
2990 # target NameNode Variable to assign class object to
2992 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
2994 py3_style_class = False # Python3 style class (bases+kwargs)
2996 def __init__(self, pos, name, bases, doc, body, decorators = None,
2997 keyword_args = None, starstar_arg = None):
2998 StatNode.__init__(self, pos)
3002 self.decorators = decorators
3004 if self.doc and Options.docstrings:
3005 doc = embed_position(self.pos, self.doc)
3006 doc_node = ExprNodes.StringNode(pos, value = doc)
3009 if keyword_args or starstar_arg:
3010 self.py3_style_class = True
3012 self.metaclass = None
3013 if keyword_args and not starstar_arg:
3014 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3015 if item.key.value == 'metaclass':
3016 if self.metaclass is not None:
3017 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3018 # special case: we already know the metaclass,
3019 # so we don't need to do the "build kwargs,
3020 # find metaclass" dance at runtime
3021 self.metaclass = item.value
3022 del keyword_args.key_value_pairs[i]
3023 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3024 self.mkw = ExprNodes.KeywordArgsNode(
3025 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3027 self.mkw = ExprNodes.NullNode(pos)
3028 if self.metaclass is None:
3029 self.metaclass = ExprNodes.PyClassMetaclassNode(
3030 pos, mkw = self.mkw, bases = self.bases)
3031 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3032 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3034 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3035 bases = self.bases, dict = self.dict, doc = doc_node,
3036 metaclass = self.metaclass, mkw = self.mkw)
3038 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3039 self.metaclass = None
3042 self.classobj = ExprNodes.ClassNode(pos, name = name,
3043 bases = bases, dict = self.dict, doc = doc_node)
3044 self.target = ExprNodes.NameNode(pos, name = name)
3046 def as_cclass(self):
3048 Return this node as if it were declared as an extension class
3050 if self.py3_style_class:
3051 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3053 bases = self.classobj.bases.args
3055 base_class_name = None
3056 base_class_module = None
3057 elif len(bases) == 1:
3060 from ExprNodes import AttributeNode, NameNode
3061 while isinstance(base, AttributeNode):
3062 path.insert(0, base.attribute)
3064 if isinstance(base, NameNode):
3065 path.insert(0, base.name)
3066 base_class_name = path[-1]
3068 base_class_module = u'.'.join(path[:-1])
3070 base_class_module = None
3072 error(self.classobj.bases.args.pos, "Invalid base class")
3074 error(self.classobj.bases.args.pos, "C class may only have one base class")
3077 return CClassDefNode(self.pos,
3078 visibility = 'private',
3080 class_name = self.name,
3081 base_class_module = base_class_module,
3082 base_class_name = base_class_name,
3083 decorators = self.decorators,
3088 def create_scope(self, env):
3090 while genv.is_py_class_scope or genv.is_c_class_scope:
3091 genv = genv.outer_scope
3092 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3095 def analyse_declarations(self, env):
3096 self.target.analyse_target_declaration(env)
3097 cenv = self.create_scope(env)
3098 cenv.directives = env.directives
3099 cenv.class_obj_cname = self.target.entry.cname
3100 self.body.analyse_declarations(cenv)
3102 def analyse_expressions(self, env):
3103 if self.py3_style_class:
3104 self.bases.analyse_expressions(env)
3105 self.metaclass.analyse_expressions(env)
3106 self.mkw.analyse_expressions(env)
3107 self.dict.analyse_expressions(env)
3108 self.classobj.analyse_expressions(env)
3109 genv = env.global_scope()
3111 self.body.analyse_expressions(cenv)
3112 self.target.analyse_target_expression(env, self.classobj)
3114 def generate_function_definitions(self, env, code):
3115 self.generate_lambda_definitions(self.scope, code)
3116 self.body.generate_function_definitions(self.scope, code)
3118 def generate_execution_code(self, code):
3119 code.pyclass_stack.append(self)
3121 if self.py3_style_class:
3122 self.bases.generate_evaluation_code(code)
3123 self.mkw.generate_evaluation_code(code)
3124 self.metaclass.generate_evaluation_code(code)
3125 self.dict.generate_evaluation_code(code)
3126 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3127 self.body.generate_execution_code(code)
3128 self.classobj.generate_evaluation_code(code)
3129 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3130 self.target.generate_assignment_code(self.classobj, code)
3131 self.dict.generate_disposal_code(code)
3132 self.dict.free_temps(code)
3133 if self.py3_style_class:
3134 self.mkw.generate_disposal_code(code)
3135 self.mkw.free_temps(code)
3136 self.metaclass.generate_disposal_code(code)
3137 self.metaclass.free_temps(code)
3138 self.bases.generate_disposal_code(code)
3139 self.bases.free_temps(code)
3140 code.pyclass_stack.pop()
3142 class CClassDefNode(ClassDefNode):
3143 # An extension type definition.
3145 # visibility 'private' or 'public' or 'extern'
3146 # typedef_flag boolean
3148 # module_name string or None For import of extern type objects
3149 # class_name string Unqualified name of class
3150 # as_name string or None Name to declare as in this scope
3151 # base_class_module string or None Module containing the base class
3152 # base_class_name string or None Name of the base class
3153 # objstruct_name string or None Specified C name of object struct
3154 # typeobj_name string or None Specified C name of type object
3155 # in_pxd boolean Is in a .pxd file
3156 # decorators [DecoratorNode] list of decorators or None
3157 # doc string or None
3158 # body StatNode or None
3159 # entry Symtab.Entry
3160 # base_type PyExtensionType or None
3161 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3162 # buffer_defaults_pos
3164 child_attrs = ["body"]
3165 buffer_defaults_node = None
3166 buffer_defaults_pos = None
3167 typedef_flag = False
3169 objstruct_name = None
3174 def analyse_declarations(self, env):
3175 #print "CClassDefNode.analyse_declarations:", self.class_name
3176 #print "...visibility =", self.visibility
3177 #print "...module_name =", self.module_name
3180 if self.buffer_defaults_node:
3181 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3182 env, [], self.buffer_defaults_node,
3183 need_complete=False)
3185 buffer_defaults = None
3187 if env.in_cinclude and not self.objstruct_name:
3188 error(self.pos, "Object struct name specification required for "
3189 "C class defined in 'extern from' block")
3190 self.base_type = None
3191 # Now that module imports are cached, we need to
3192 # import the modules for extern classes.
3193 if self.module_name:
3195 for module in env.cimported_modules:
3196 if module.name == self.module_name:
3197 self.module = module
3198 if self.module is None:
3199 self.module = ModuleScope(self.module_name, None, env.context)
3200 self.module.has_extern_class = 1
3201 env.add_imported_module(self.module)
3203 if self.base_class_name:
3204 if self.base_class_module:
3205 base_class_scope = env.find_module(self.base_class_module, self.pos)
3207 base_class_scope = env
3208 if self.base_class_name == 'object':
3209 # extension classes are special and don't need to inherit from object
3210 if base_class_scope is None or base_class_scope.lookup('object') is None:
3211 self.base_class_name = None
3212 self.base_class_module = None
3213 base_class_scope = None
3214 if base_class_scope:
3215 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3216 if base_class_entry:
3217 if not base_class_entry.is_type:
3218 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3219 elif not base_class_entry.type.is_extension_type and \
3220 not (base_class_entry.type.is_builtin_type and \
3221 base_class_entry.type.objstruct_cname):
3222 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3223 elif not base_class_entry.type.is_complete():
3224 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3225 self.base_class_name, self.class_name))
3226 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3227 base_class_entry.type.scope.directives['final']:
3228 error(self.pos, "Base class '%s' of type '%s' is final" % (
3229 self.base_class_name, self.class_name))
3230 elif base_class_entry.type.is_builtin_type and \
3231 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3232 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3233 % base_class_entry.type.name)
3235 self.base_type = base_class_entry.type
3236 has_body = self.body is not None
3237 if self.module_name and self.visibility != 'extern':
3238 module_path = self.module_name.split(".")
3239 home_scope = env.find_imported_module(module_path, self.pos)
3245 if self.visibility == 'extern':
3246 if (self.module_name == '__builtin__' and
3247 self.class_name in Builtin.builtin_types and
3248 env.qualified_name[:8] != 'cpython.'): # allow overloaded names for cimporting from cpython
3249 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3251 self.entry = home_scope.declare_c_class(
3252 name = self.class_name,
3254 defining = has_body and self.in_pxd,
3255 implementing = has_body and not self.in_pxd,
3256 module_name = self.module_name,
3257 base_type = self.base_type,
3258 objstruct_cname = self.objstruct_name,
3259 typeobj_cname = self.typeobj_name,
3260 visibility = self.visibility,
3261 typedef_flag = self.typedef_flag,
3263 buffer_defaults = buffer_defaults,
3264 shadow = self.shadow)
3266 home_scope.lookup(self.class_name).as_variable = self.entry
3267 if home_scope is not env and self.visibility == 'extern':
3268 env.add_imported_entry(self.class_name, self.entry, self.pos)
3269 self.scope = scope = self.entry.type.scope
3270 if scope is not None:
3271 scope.directives = env.directives
3273 if self.doc and Options.docstrings:
3274 scope.doc = embed_position(self.pos, self.doc)
3277 self.body.analyse_declarations(scope)
3281 scope.implemented = 1
3282 env.allocate_vtable_names(self.entry)
3284 def analyse_expressions(self, env):
3286 scope = self.entry.type.scope
3287 self.body.analyse_expressions(scope)
3289 def generate_function_definitions(self, env, code):
3291 self.generate_lambda_definitions(self.scope, code)
3292 self.body.generate_function_definitions(self.scope, code)
3294 def generate_execution_code(self, code):
3295 # This is needed to generate evaluation code for
3296 # default values of method arguments.
3298 self.body.generate_execution_code(code)
3300 def annotate(self, code):
3302 self.body.annotate(code)
3305 class PropertyNode(StatNode):
3306 # Definition of a property in an extension type.
3309 # doc EncodedString or None Doc string
3312 child_attrs = ["body"]
3314 def analyse_declarations(self, env):
3315 entry = env.declare_property(self.name, self.doc, self.pos)
3317 entry.scope.directives = env.directives
3318 self.body.analyse_declarations(entry.scope)
3320 def analyse_expressions(self, env):
3321 self.body.analyse_expressions(env)
3323 def generate_function_definitions(self, env, code):
3324 self.body.generate_function_definitions(env, code)
3326 def generate_execution_code(self, code):
3329 def annotate(self, code):
3330 self.body.annotate(code)
3333 class GlobalNode(StatNode):
3334 # Global variable declaration.
3340 def analyse_declarations(self, env):
3341 for name in self.names:
3342 env.declare_global(name, self.pos)
3344 def analyse_expressions(self, env):
3347 def generate_execution_code(self, code):
3351 class ExprStatNode(StatNode):
3352 # Expression used as a statement.
3356 child_attrs = ["expr"]
3358 def analyse_declarations(self, env):
3360 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3361 func = self.expr.function.as_cython_attribute()
3362 if func == u'declare':
3363 args, kwds = self.expr.explicit_args_kwds()
3365 error(self.expr.pos, "Variable names must be specified.")
3366 for var, type_node in kwds.key_value_pairs:
3367 type = type_node.analyse_as_type(env)
3369 error(type_node.pos, "Unknown type")
3371 env.declare_var(var.value, type, var.pos, is_cdef = True)
3372 self.__class__ = PassStatNode
3374 def analyse_expressions(self, env):
3375 self.expr.analyse_expressions(env)
3377 def nogil_check(self, env):
3378 if self.expr.type.is_pyobject and self.expr.is_temp:
3381 gil_message = "Discarding owned Python object"
3383 def generate_execution_code(self, code):
3384 self.expr.generate_evaluation_code(code)
3385 if not self.expr.is_temp and self.expr.result():
3386 code.putln("%s;" % self.expr.result())
3387 self.expr.generate_disposal_code(code)
3388 self.expr.free_temps(code)
3390 def generate_function_definitions(self, env, code):
3391 self.expr.generate_function_definitions(env, code)
3393 def annotate(self, code):
3394 self.expr.annotate(code)
3397 class AssignmentNode(StatNode):
3398 # Abstract base class for assignment nodes.
3400 # The analyse_expressions and generate_execution_code
3401 # phases of assignments are split into two sub-phases
3402 # each, to enable all the right hand sides of a
3403 # parallel assignment to be evaluated before assigning
3404 # to any of the left hand sides.
3406 def analyse_expressions(self, env):
3407 self.analyse_types(env)
3409 # def analyse_expressions(self, env):
3410 # self.analyse_expressions_1(env)
3411 # self.analyse_expressions_2(env)
3413 def generate_execution_code(self, code):
3414 self.generate_rhs_evaluation_code(code)
3415 self.generate_assignment_code(code)
3418 class SingleAssignmentNode(AssignmentNode):
3419 # The simplest case:
3423 # lhs ExprNode Left hand side
3424 # rhs ExprNode Right hand side
3425 # first bool Is this guaranteed the first assignment to lhs?
3427 child_attrs = ["lhs", "rhs"]
3429 declaration_only = False
3431 def analyse_declarations(self, env):
3434 # handle declarations of the form x = cython.foo()
3435 if isinstance(self.rhs, ExprNodes.CallNode):
3436 func_name = self.rhs.function.as_cython_attribute()
3438 args, kwds = self.rhs.explicit_args_kwds()
3440 if func_name in ['declare', 'typedef']:
3441 if len(args) > 2 or kwds is not None:
3442 error(self.rhs.pos, "Can only declare one type at a time.")
3444 type = args[0].analyse_as_type(env)
3446 error(args[0].pos, "Unknown type")
3449 if func_name == 'declare':
3450 if isinstance(lhs, ExprNodes.NameNode):
3451 vars = [(lhs.name, lhs.pos)]
3452 elif isinstance(lhs, ExprNodes.TupleNode):
3453 vars = [(var.name, var.pos) for var in lhs.args]
3455 error(lhs.pos, "Invalid declaration")
3457 for var, pos in vars:
3458 env.declare_var(var, type, pos, is_cdef = True)
3463 self.declaration_only = True
3465 self.declaration_only = True
3466 if not isinstance(lhs, ExprNodes.NameNode):
3467 error(lhs.pos, "Invalid declaration.")
3468 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3470 elif func_name in ['struct', 'union']:
3471 self.declaration_only = True
3472 if len(args) > 0 or kwds is None:
3473 error(self.rhs.pos, "Struct or union members must be given by name.")
3476 for member, type_node in kwds.key_value_pairs:
3477 type = type_node.analyse_as_type(env)
3479 error(type_node.pos, "Unknown type")
3481 members.append((member.value, type, member.pos))
3482 if len(members) < len(kwds.key_value_pairs):
3484 if not isinstance(self.lhs, ExprNodes.NameNode):
3485 error(self.lhs.pos, "Invalid declaration.")
3486 name = self.lhs.name
3487 scope = StructOrUnionScope(name)
3488 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3489 for member, type, pos in members:
3490 scope.declare_var(member, type, pos)
3492 if self.declaration_only:
3495 self.lhs.analyse_target_declaration(env)
3497 def analyse_types(self, env, use_temp = 0):
3498 self.rhs.analyse_types(env)
3499 self.lhs.analyse_target_types(env)
3500 self.lhs.gil_assignment_check(env)
3501 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3503 self.rhs = self.rhs.coerce_to_temp(env)
3505 def generate_rhs_evaluation_code(self, code):
3506 self.rhs.generate_evaluation_code(code)
3508 def generate_assignment_code(self, code):
3509 self.lhs.generate_assignment_code(self.rhs, code)
3511 def generate_function_definitions(self, env, code):
3512 self.rhs.generate_function_definitions(env, code)
3514 def annotate(self, code):
3515 self.lhs.annotate(code)
3516 self.rhs.annotate(code)
3519 class CascadedAssignmentNode(AssignmentNode):
3520 # An assignment with multiple left hand sides:
3524 # lhs_list [ExprNode] Left hand sides
3525 # rhs ExprNode Right hand sides
3529 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3531 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3532 coerced_rhs_list = None
3534 def analyse_declarations(self, env):
3535 for lhs in self.lhs_list:
3536 lhs.analyse_target_declaration(env)
3538 def analyse_types(self, env, use_temp = 0):
3539 self.rhs.analyse_types(env)
3540 if not self.rhs.is_simple():
3542 self.rhs = self.rhs.coerce_to_temp(env)
3544 self.rhs = self.rhs.coerce_to_simple(env)
3545 from ExprNodes import CloneNode
3546 self.coerced_rhs_list = []
3547 for lhs in self.lhs_list:
3548 lhs.analyse_target_types(env)
3549 lhs.gil_assignment_check(env)
3550 rhs = CloneNode(self.rhs)
3551 rhs = rhs.coerce_to(lhs.type, env)
3552 self.coerced_rhs_list.append(rhs)
3554 def generate_rhs_evaluation_code(self, code):
3555 self.rhs.generate_evaluation_code(code)
3557 def generate_assignment_code(self, code):
3558 for i in range(len(self.lhs_list)):
3559 lhs = self.lhs_list[i]
3560 rhs = self.coerced_rhs_list[i]
3561 rhs.generate_evaluation_code(code)
3562 lhs.generate_assignment_code(rhs, code)
3563 # Assignment has disposed of the cloned RHS
3564 self.rhs.generate_disposal_code(code)
3565 self.rhs.free_temps(code)
3567 def generate_function_definitions(self, env, code):
3568 self.rhs.generate_function_definitions(env, code)
3570 def annotate(self, code):
3571 for i in range(len(self.lhs_list)):
3572 lhs = self.lhs_list[i].annotate(code)
3573 rhs = self.coerced_rhs_list[i].annotate(code)
3574 self.rhs.annotate(code)
3577 class ParallelAssignmentNode(AssignmentNode):
3578 # A combined packing/unpacking assignment:
3582 # This has been rearranged by the parser into
3584 # a = d ; b = e ; c = f
3586 # but we must evaluate all the right hand sides
3587 # before assigning to any of the left hand sides.
3589 # stats [AssignmentNode] The constituent assignments
3591 child_attrs = ["stats"]
3593 def analyse_declarations(self, env):
3594 for stat in self.stats:
3595 stat.analyse_declarations(env)
3597 def analyse_expressions(self, env):
3598 for stat in self.stats:
3599 stat.analyse_types(env, use_temp = 1)
3601 # def analyse_expressions(self, env):
3602 # for stat in self.stats:
3603 # stat.analyse_expressions_1(env, use_temp = 1)
3604 # for stat in self.stats:
3605 # stat.analyse_expressions_2(env)
3607 def generate_execution_code(self, code):
3608 for stat in self.stats:
3609 stat.generate_rhs_evaluation_code(code)
3610 for stat in self.stats:
3611 stat.generate_assignment_code(code)
3613 def generate_function_definitions(self, env, code):
3614 for stat in self.stats:
3615 stat.generate_function_definitions(env, code)
3617 def annotate(self, code):
3618 for stat in self.stats:
3622 class InPlaceAssignmentNode(AssignmentNode):
3623 # An in place arithmetic operand:
3629 # lhs ExprNode Left hand side
3630 # rhs ExprNode Right hand side
3631 # op char one of "+-*/%^&|"
3632 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3634 # This code is a bit tricky because in order to obey Python
3635 # semantics the sub-expressions (e.g. indices) of the lhs must
3636 # not be evaluated twice. So we must re-use the values calculated
3637 # in evaluation phase for the assignment phase as well.
3638 # Fortunately, the type of the lhs node is fairly constrained
3639 # (it must be a NameNode, AttributeNode, or IndexNode).
3641 child_attrs = ["lhs", "rhs"]
3643 def analyse_declarations(self, env):
3644 self.lhs.analyse_target_declaration(env)
3646 def analyse_types(self, env):
3647 self.rhs.analyse_types(env)
3648 self.lhs.analyse_target_types(env)
3650 def generate_execution_code(self, code):
3652 self.rhs.generate_evaluation_code(code)
3653 self.lhs.generate_subexpr_evaluation_code(code)
3654 c_op = self.operator
3658 error(self.pos, "No C inplace power operator")
3659 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3660 if self.lhs.type.is_pyobject:
3661 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3662 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3663 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3664 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3667 # TODO: make sure overload is declared
3668 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3669 self.lhs.generate_subexpr_disposal_code(code)
3670 self.lhs.free_subexpr_temps(code)
3671 self.rhs.generate_disposal_code(code)
3672 self.rhs.free_temps(code)
3674 def annotate(self, code):
3675 self.lhs.annotate(code)
3676 self.rhs.annotate(code)
3678 def create_binop_node(self):
3680 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3683 class PrintStatNode(StatNode):
3686 # arg_tuple TupleNode
3687 # stream ExprNode or None (stdout)
3688 # append_newline boolean
3690 child_attrs = ["arg_tuple", "stream"]
3692 def analyse_expressions(self, env):
3694 self.stream.analyse_expressions(env)
3695 self.stream = self.stream.coerce_to_pyobject(env)
3696 self.arg_tuple.analyse_expressions(env)
3697 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3698 env.use_utility_code(printing_utility_code)
3699 if len(self.arg_tuple.args) == 1 and self.append_newline:
3700 env.use_utility_code(printing_one_utility_code)
3702 nogil_check = Node.gil_error
3703 gil_message = "Python print statement"
3705 def generate_execution_code(self, code):
3707 self.stream.generate_evaluation_code(code)
3708 stream_result = self.stream.py_result()
3711 if len(self.arg_tuple.args) == 1 and self.append_newline:
3712 arg = self.arg_tuple.args[0]
3713 arg.generate_evaluation_code(code)
3716 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3719 code.error_goto(self.pos)))
3720 arg.generate_disposal_code(code)
3721 arg.free_temps(code)
3723 self.arg_tuple.generate_evaluation_code(code)
3725 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3727 self.arg_tuple.py_result(),
3728 self.append_newline,
3729 code.error_goto(self.pos)))
3730 self.arg_tuple.generate_disposal_code(code)
3731 self.arg_tuple.free_temps(code)
3734 self.stream.generate_disposal_code(code)
3735 self.stream.free_temps(code)
3737 def generate_function_definitions(self, env, code):
3739 self.stream.generate_function_definitions(env, code)
3740 self.arg_tuple.generate_function_definitions(env, code)
3742 def annotate(self, code):
3744 self.stream.annotate(code)
3745 self.arg_tuple.annotate(code)
3748 class ExecStatNode(StatNode):
3753 child_attrs = ["args"]
3755 def analyse_expressions(self, env):
3756 for i, arg in enumerate(self.args):
3757 arg.analyse_expressions(env)
3758 arg = arg.coerce_to_pyobject(env)
3760 env.use_utility_code(Builtin.pyexec_utility_code)
3762 nogil_check = Node.gil_error
3763 gil_message = "Python exec statement"
3765 def generate_execution_code(self, code):
3767 for arg in self.args:
3768 arg.generate_evaluation_code(code)
3769 args.append( arg.py_result() )
3770 args = tuple(args + ['0', '0'][:3-len(args)])
3771 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3772 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3773 (temp_result,) + args))
3774 for arg in self.args:
3775 arg.generate_disposal_code(code)
3776 arg.free_temps(code)
3778 code.error_goto_if_null(temp_result, self.pos))
3779 code.put_gotref(temp_result)
3780 code.put_decref_clear(temp_result, py_object_type)
3781 code.funcstate.release_temp(temp_result)
3783 def annotate(self, code):
3784 for arg in self.args:
3788 class DelStatNode(StatNode):
3793 child_attrs = ["args"]
3795 def analyse_declarations(self, env):
3796 for arg in self.args:
3797 arg.analyse_target_declaration(env)
3799 def analyse_expressions(self, env):
3800 for arg in self.args:
3801 arg.analyse_target_expression(env, None)
3802 if arg.type.is_pyobject:
3804 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3806 elif arg.type.is_cpp_class:
3807 error(arg.pos, "Deletion of non-heap C++ object")
3809 error(arg.pos, "Deletion of non-Python, non-C++ object")
3810 #arg.release_target_temp(env)
3812 def nogil_check(self, env):
3813 for arg in self.args:
3814 if arg.type.is_pyobject:
3817 gil_message = "Deleting Python object"
3819 def generate_execution_code(self, code):
3820 for arg in self.args:
3821 if arg.type.is_pyobject:
3822 arg.generate_deletion_code(code)
3823 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3824 arg.generate_result_code(code)
3825 code.putln("delete %s;" % arg.result())
3826 # else error reported earlier
3828 def annotate(self, code):
3829 for arg in self.args:
3833 class PassStatNode(StatNode):
3838 def analyse_expressions(self, env):
3841 def generate_execution_code(self, code):
3845 class BreakStatNode(StatNode):
3849 def analyse_expressions(self, env):
3852 def generate_execution_code(self, code):
3853 if not code.break_label:
3854 error(self.pos, "break statement not inside loop")
3856 code.put_goto(code.break_label)
3859 class ContinueStatNode(StatNode):
3863 def analyse_expressions(self, env):
3866 def generate_execution_code(self, code):
3867 if code.funcstate.in_try_finally:
3868 error(self.pos, "continue statement inside try of try...finally")
3869 elif not code.continue_label:
3870 error(self.pos, "continue statement not inside loop")
3872 code.put_goto(code.continue_label)
3875 class ReturnStatNode(StatNode):
3878 # value ExprNode or None
3879 # return_type PyrexType
3881 child_attrs = ["value"]
3883 def analyse_expressions(self, env):
3884 return_type = env.return_type
3885 self.return_type = return_type
3887 error(self.pos, "Return not inside a function body")
3890 self.value.analyse_types(env)
3891 if return_type.is_void or return_type.is_returncode:
3892 error(self.value.pos,
3893 "Return with value in void function")
3895 self.value = self.value.coerce_to(env.return_type, env)
3897 if (not return_type.is_void
3898 and not return_type.is_pyobject
3899 and not return_type.is_returncode):
3900 error(self.pos, "Return value required")
3902 def nogil_check(self, env):
3903 if self.return_type.is_pyobject:
3906 gil_message = "Returning Python object"
3908 def generate_execution_code(self, code):
3909 code.mark_pos(self.pos)
3910 if not self.return_type:
3911 # error reported earlier
3913 if self.return_type.is_pyobject:
3914 code.put_xdecref(Naming.retval_cname,
3917 self.value.generate_evaluation_code(code)
3918 self.value.make_owned_reference(code)
3921 Naming.retval_cname,
3922 self.value.result_as(self.return_type)))
3923 self.value.generate_post_assignment_code(code)
3924 self.value.free_temps(code)
3926 if self.return_type.is_pyobject:
3927 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3928 elif self.return_type.is_returncode:
3931 Naming.retval_cname,
3932 self.return_type.default_value))
3933 for cname, type in code.funcstate.temps_holding_reference():
3934 code.put_decref_clear(cname, type)
3935 code.put_goto(code.return_label)
3937 def generate_function_definitions(self, env, code):
3938 if self.value is not None:
3939 self.value.generate_function_definitions(env, code)
3941 def annotate(self, code):
3943 self.value.annotate(code)
3946 class RaiseStatNode(StatNode):
3949 # exc_type ExprNode or None
3950 # exc_value ExprNode or None
3951 # exc_tb ExprNode or None
3953 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3955 def analyse_expressions(self, env):
3957 self.exc_type.analyse_types(env)
3958 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3960 self.exc_value.analyse_types(env)
3961 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3963 self.exc_tb.analyse_types(env)
3964 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3965 # special cases for builtin exceptions
3966 self.builtin_exc_name = None
3967 if self.exc_type and not self.exc_value and not self.exc_tb:
3970 if isinstance(exc, ExprNodes.SimpleCallNode) and not exc.args:
3971 exc = exc.function # extract the exception type
3972 if exc.is_name and exc.entry.is_builtin:
3973 self.builtin_exc_name = exc.name
3974 if self.builtin_exc_name == 'MemoryError':
3975 self.exc_type = None # has a separate implementation
3977 nogil_check = Node.gil_error
3978 gil_message = "Raising exception"
3980 def generate_execution_code(self, code):
3981 if self.builtin_exc_name == 'MemoryError':
3982 code.putln('PyErr_NoMemory(); %s' % code.error_goto(self.pos))
3986 self.exc_type.generate_evaluation_code(code)
3987 type_code = self.exc_type.py_result()
3991 self.exc_value.generate_evaluation_code(code)
3992 value_code = self.exc_value.py_result()
3996 self.exc_tb.generate_evaluation_code(code)
3997 tb_code = self.exc_tb.py_result()
4000 code.globalstate.use_utility_code(raise_utility_code)
4002 "__Pyx_Raise(%s, %s, %s);" % (
4006 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4008 obj.generate_disposal_code(code)
4009 obj.free_temps(code)
4011 code.error_goto(self.pos))
4013 def generate_function_definitions(self, env, code):
4014 if self.exc_type is not None:
4015 self.exc_type.generate_function_definitions(env, code)
4016 if self.exc_value is not None:
4017 self.exc_value.generate_function_definitions(env, code)
4018 if self.exc_tb is not None:
4019 self.exc_tb.generate_function_definitions(env, code)
4021 def annotate(self, code):
4023 self.exc_type.annotate(code)
4025 self.exc_value.annotate(code)
4027 self.exc_tb.annotate(code)
4030 class ReraiseStatNode(StatNode):
4034 def analyse_expressions(self, env):
4035 env.use_utility_code(restore_exception_utility_code)
4037 nogil_check = Node.gil_error
4038 gil_message = "Raising exception"
4040 def generate_execution_code(self, code):
4041 vars = code.funcstate.exc_vars
4043 for varname in vars:
4044 code.put_giveref(varname)
4045 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4046 for varname in vars:
4047 code.put("%s = 0; " % varname)
4049 code.putln(code.error_goto(self.pos))
4051 error(self.pos, "Reraise not inside except clause")
4054 class AssertStatNode(StatNode):
4058 # value ExprNode or None
4060 child_attrs = ["cond", "value"]
4062 def analyse_expressions(self, env):
4063 self.cond = self.cond.analyse_boolean_expression(env)
4065 self.value.analyse_types(env)
4066 self.value = self.value.coerce_to_pyobject(env)
4068 nogil_check = Node.gil_error
4069 gil_message = "Raising exception"
4071 def generate_execution_code(self, code):
4072 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4073 self.cond.generate_evaluation_code(code)
4075 "if (unlikely(!%s)) {" %
4078 self.value.generate_evaluation_code(code)
4080 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4081 self.value.py_result())
4082 self.value.generate_disposal_code(code)
4083 self.value.free_temps(code)
4086 "PyErr_SetNone(PyExc_AssertionError);")
4088 code.error_goto(self.pos))
4091 self.cond.generate_disposal_code(code)
4092 self.cond.free_temps(code)
4093 code.putln("#endif")
4095 def generate_function_definitions(self, env, code):
4096 self.cond.generate_function_definitions(env, code)
4097 if self.value is not None:
4098 self.value.generate_function_definitions(env, code)
4100 def annotate(self, code):
4101 self.cond.annotate(code)
4103 self.value.annotate(code)
4106 class IfStatNode(StatNode):
4109 # if_clauses [IfClauseNode]
4110 # else_clause StatNode or None
4112 child_attrs = ["if_clauses", "else_clause"]
4114 def analyse_control_flow(self, env):
4115 env.start_branching(self.pos)
4116 for if_clause in self.if_clauses:
4117 if_clause.analyse_control_flow(env)
4118 env.next_branch(if_clause.end_pos())
4119 if self.else_clause:
4120 self.else_clause.analyse_control_flow(env)
4121 env.finish_branching(self.end_pos())
4123 def analyse_declarations(self, env):
4124 for if_clause in self.if_clauses:
4125 if_clause.analyse_declarations(env)
4126 if self.else_clause:
4127 self.else_clause.analyse_declarations(env)
4129 def analyse_expressions(self, env):
4130 for if_clause in self.if_clauses:
4131 if_clause.analyse_expressions(env)
4132 if self.else_clause:
4133 self.else_clause.analyse_expressions(env)
4135 def generate_execution_code(self, code):
4136 code.mark_pos(self.pos)
4137 end_label = code.new_label()
4138 for if_clause in self.if_clauses:
4139 if_clause.generate_execution_code(code, end_label)
4140 if self.else_clause:
4141 code.putln("/*else*/ {")
4142 self.else_clause.generate_execution_code(code)
4144 code.put_label(end_label)
4146 def generate_function_definitions(self, env, code):
4147 for clause in self.if_clauses:
4148 clause.generate_function_definitions(env, code)
4149 if self.else_clause is not None:
4150 self.else_clause.generate_function_definitions(env, code)
4152 def annotate(self, code):
4153 for if_clause in self.if_clauses:
4154 if_clause.annotate(code)
4155 if self.else_clause:
4156 self.else_clause.annotate(code)
4159 class IfClauseNode(Node):
4160 # if or elif clause in an if statement
4162 # condition ExprNode
4165 child_attrs = ["condition", "body"]
4167 def analyse_control_flow(self, env):
4168 self.body.analyse_control_flow(env)
4170 def analyse_declarations(self, env):
4171 self.body.analyse_declarations(env)
4173 def analyse_expressions(self, env):
4175 self.condition.analyse_temp_boolean_expression(env)
4176 self.body.analyse_expressions(env)
4178 def get_constant_condition_result(self):
4179 if self.condition.has_constant_result():
4180 return bool(self.condition.constant_result)
4184 def generate_execution_code(self, code, end_label):
4185 self.condition.generate_evaluation_code(code)
4188 self.condition.result())
4189 self.condition.generate_disposal_code(code)
4190 self.condition.free_temps(code)
4191 self.body.generate_execution_code(code)
4192 code.put_goto(end_label)
4195 def generate_function_definitions(self, env, code):
4196 self.condition.generate_function_definitions(env, code)
4197 self.body.generate_function_definitions(env, code)
4199 def annotate(self, code):
4200 self.condition.annotate(code)
4201 self.body.annotate(code)
4204 class SwitchCaseNode(StatNode):
4205 # Generated in the optimization of an if-elif-else node
4207 # conditions [ExprNode]
4210 child_attrs = ['conditions', 'body']
4212 def generate_execution_code(self, code):
4213 for cond in self.conditions:
4214 code.mark_pos(cond.pos)
4215 cond.generate_evaluation_code(code)
4216 code.putln("case %s:" % cond.result())
4217 self.body.generate_execution_code(code)
4218 code.putln("break;")
4220 def generate_function_definitions(self, env, code):
4221 for cond in self.conditions:
4222 cond.generate_function_definitions(env, code)
4223 self.body.generate_function_definitions(env, code)
4225 def annotate(self, code):
4226 for cond in self.conditions:
4228 self.body.annotate(code)
4230 class SwitchStatNode(StatNode):
4231 # Generated in the optimization of an if-elif-else node
4234 # cases [SwitchCaseNode]
4235 # else_clause StatNode or None
4237 child_attrs = ['test', 'cases', 'else_clause']
4239 def generate_execution_code(self, code):
4240 self.test.generate_evaluation_code(code)
4241 code.putln("switch (%s) {" % self.test.result())
4242 for case in self.cases:
4243 case.generate_execution_code(code)
4244 if self.else_clause is not None:
4245 code.putln("default:")
4246 self.else_clause.generate_execution_code(code)
4247 code.putln("break;")
4250 def generate_function_definitions(self, env, code):
4251 self.test.generate_function_definitions(env, code)
4252 for case in self.cases:
4253 case.generate_function_definitions(env, code)
4254 if self.else_clause is not None:
4255 self.else_clause.generate_function_definitions(env, code)
4257 def annotate(self, code):
4258 self.test.annotate(code)
4259 for case in self.cases:
4261 if self.else_clause is not None:
4262 self.else_clause.annotate(code)
4264 class LoopNode(object):
4266 def analyse_control_flow(self, env):
4267 env.start_branching(self.pos)
4268 self.body.analyse_control_flow(env)
4269 env.next_branch(self.body.end_pos())
4270 if self.else_clause:
4271 self.else_clause.analyse_control_flow(env)
4272 env.finish_branching(self.end_pos())
4275 class WhileStatNode(LoopNode, StatNode):
4278 # condition ExprNode
4280 # else_clause StatNode
4282 child_attrs = ["condition", "body", "else_clause"]
4284 def analyse_declarations(self, env):
4285 self.body.analyse_declarations(env)
4286 if self.else_clause:
4287 self.else_clause.analyse_declarations(env)
4289 def analyse_expressions(self, env):
4291 self.condition.analyse_temp_boolean_expression(env)
4292 self.body.analyse_expressions(env)
4293 if self.else_clause:
4294 self.else_clause.analyse_expressions(env)
4296 def generate_execution_code(self, code):
4297 old_loop_labels = code.new_loop_labels()
4300 self.condition.generate_evaluation_code(code)
4301 self.condition.generate_disposal_code(code)
4304 self.condition.result())
4305 self.condition.free_temps(code)
4306 self.body.generate_execution_code(code)
4307 code.put_label(code.continue_label)
4309 break_label = code.break_label
4310 code.set_loop_labels(old_loop_labels)
4311 if self.else_clause:
4312 code.putln("/*else*/ {")
4313 self.else_clause.generate_execution_code(code)
4315 code.put_label(break_label)
4317 def generate_function_definitions(self, env, code):
4318 self.condition.generate_function_definitions(env, code)
4319 self.body.generate_function_definitions(env, code)
4320 if self.else_clause is not None:
4321 self.else_clause.generate_function_definitions(env, code)
4323 def annotate(self, code):
4324 self.condition.annotate(code)
4325 self.body.annotate(code)
4326 if self.else_clause:
4327 self.else_clause.annotate(code)
4330 def ForStatNode(pos, **kw):
4331 if 'iterator' in kw:
4332 return ForInStatNode(pos, **kw)
4334 return ForFromStatNode(pos, **kw)
4336 class ForInStatNode(LoopNode, StatNode):
4340 # iterator IteratorNode
4342 # else_clause StatNode
4343 # item NextNode used internally
4345 child_attrs = ["target", "iterator", "body", "else_clause"]
4348 def analyse_declarations(self, env):
4349 self.target.analyse_target_declaration(env)
4350 self.body.analyse_declarations(env)
4351 if self.else_clause:
4352 self.else_clause.analyse_declarations(env)
4354 def analyse_expressions(self, env):
4356 self.target.analyse_target_types(env)
4357 self.iterator.analyse_expressions(env)
4358 self.item = ExprNodes.NextNode(self.iterator, env)
4359 if (self.iterator.type.is_ptr or self.iterator.type.is_array) and \
4360 self.target.type.assignable_from(self.iterator.type):
4361 # C array slice optimization.
4364 self.item = self.item.coerce_to(self.target.type, env)
4365 self.body.analyse_expressions(env)
4366 if self.else_clause:
4367 self.else_clause.analyse_expressions(env)
4369 def generate_execution_code(self, code):
4370 old_loop_labels = code.new_loop_labels()
4371 self.iterator.allocate_counter_temp(code)
4372 self.iterator.generate_evaluation_code(code)
4375 self.item.generate_evaluation_code(code)
4376 self.target.generate_assignment_code(self.item, code)
4377 self.body.generate_execution_code(code)
4378 code.put_label(code.continue_label)
4381 break_label = code.break_label
4382 code.set_loop_labels(old_loop_labels)
4384 if self.else_clause:
4385 # in nested loops, the 'else' block can contain a
4386 # 'continue' statement for the outer loop, but we may need
4387 # to generate cleanup code before taking that path, so we
4389 orig_continue_label = code.continue_label
4390 code.continue_label = code.new_label('outer_continue')
4392 code.putln("/*else*/ {")
4393 self.else_clause.generate_execution_code(code)
4396 if code.label_used(code.continue_label):
4397 code.put_goto(break_label)
4398 code.put_label(code.continue_label)
4399 self.iterator.generate_disposal_code(code)
4400 code.put_goto(orig_continue_label)
4401 code.set_loop_labels(old_loop_labels)
4403 if code.label_used(break_label):
4404 code.put_label(break_label)
4405 self.iterator.release_counter_temp(code)
4406 self.iterator.generate_disposal_code(code)
4407 self.iterator.free_temps(code)
4409 def generate_function_definitions(self, env, code):
4410 self.target.generate_function_definitions(env, code)
4411 self.iterator.generate_function_definitions(env, code)
4412 self.body.generate_function_definitions(env, code)
4413 if self.else_clause is not None:
4414 self.else_clause.generate_function_definitions(env, code)
4416 def annotate(self, code):
4417 self.target.annotate(code)
4418 self.iterator.annotate(code)
4419 self.body.annotate(code)
4420 if self.else_clause:
4421 self.else_clause.annotate(code)
4422 self.item.annotate(code)
4425 class ForFromStatNode(LoopNode, StatNode):
4426 # for name from expr rel name rel expr
4433 # step ExprNode or None
4435 # else_clause StatNode or None
4441 # loopvar_node ExprNode (usually a NameNode or temp node)
4442 # py_loopvar_node PyTempNode or None
4443 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4445 is_py_target = False
4447 py_loopvar_node = None
4450 gil_message = "For-loop using object bounds or target"
4452 def nogil_check(self, env):
4453 for x in (self.target, self.bound1, self.bound2):
4454 if x.type.is_pyobject:
4457 def analyse_declarations(self, env):
4458 self.target.analyse_target_declaration(env)
4459 self.body.analyse_declarations(env)
4460 if self.else_clause:
4461 self.else_clause.analyse_declarations(env)
4463 def analyse_expressions(self, env):
4465 self.target.analyse_target_types(env)
4466 self.bound1.analyse_types(env)
4467 self.bound2.analyse_types(env)
4468 if self.step is not None:
4469 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4470 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4471 self.step.analyse_types(env)
4473 target_type = self.target.type
4474 if self.target.type.is_numeric:
4475 loop_type = self.target.type
4477 loop_type = PyrexTypes.c_int_type
4478 if not self.bound1.type.is_pyobject:
4479 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4480 if not self.bound2.type.is_pyobject:
4481 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4482 if self.step is not None and not self.step.type.is_pyobject:
4483 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4484 self.bound1 = self.bound1.coerce_to(loop_type, env)
4485 self.bound2 = self.bound2.coerce_to(loop_type, env)
4486 if not self.bound2.is_literal:
4487 self.bound2 = self.bound2.coerce_to_temp(env)
4488 if self.step is not None:
4489 self.step = self.step.coerce_to(loop_type, env)
4490 if not self.step.is_literal:
4491 self.step = self.step.coerce_to_temp(env)
4493 target_type = self.target.type
4494 if not (target_type.is_pyobject or target_type.is_numeric):
4495 error(self.target.pos,
4496 "for-from loop variable must be c numeric type or Python object")
4497 if target_type.is_numeric:
4498 self.is_py_target = False
4499 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4500 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4501 self.loopvar_node = self.target
4502 self.py_loopvar_node = None
4504 self.is_py_target = True
4505 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4506 self.loopvar_node = c_loopvar_node
4507 self.py_loopvar_node = \
4508 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4509 self.body.analyse_expressions(env)
4510 if self.else_clause:
4511 self.else_clause.analyse_expressions(env)
4513 def generate_execution_code(self, code):
4514 old_loop_labels = code.new_loop_labels()
4515 from_range = self.from_range
4516 self.bound1.generate_evaluation_code(code)
4517 self.bound2.generate_evaluation_code(code)
4518 offset, incop = self.relation_table[self.relation1]
4519 if self.step is not None:
4520 self.step.generate_evaluation_code(code)
4521 step = self.step.result()
4522 incop = "%s=%s" % (incop[0], step)
4524 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4525 self.loopvar_node.allocate(code)
4526 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4527 self.py_loopvar_node.allocate(code)
4529 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4531 loopvar_name = self.loopvar_node.result()
4533 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4535 self.bound1.result(), offset,
4536 loopvar_name, self.relation2, self.bound2.result(),
4537 loopvar_name, incop))
4538 if self.py_loopvar_node:
4539 self.py_loopvar_node.generate_evaluation_code(code)
4540 self.target.generate_assignment_code(self.py_loopvar_node, code)
4542 code.putln("%s = %s;" % (
4543 self.target.result(), loopvar_name))
4544 self.body.generate_execution_code(code)
4545 code.put_label(code.continue_label)
4546 if self.py_loopvar_node:
4547 # This mess is to make for..from loops with python targets behave
4548 # exactly like those with C targets with regards to re-assignment
4549 # of the loop variable.
4551 if self.target.entry.is_pyglobal:
4552 # We know target is a NameNode, this is the only ugly case.
4553 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4554 target_node.allocate(code)
4555 interned_cname = code.intern_identifier(self.target.entry.name)
4556 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4557 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4558 target_node.result(),
4559 Naming.module_cname,
4561 code.error_goto_if_null(target_node.result(), self.target.pos)))
4562 code.put_gotref(target_node.result())
4564 target_node = self.target
4565 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4566 from_py_node.temp_code = loopvar_name
4567 from_py_node.generate_result_code(code)
4568 if self.target.entry.is_pyglobal:
4569 code.put_decref(target_node.result(), target_node.type)
4570 target_node.release(code)
4572 if self.py_loopvar_node:
4573 # This is potentially wasteful, but we don't want the semantics to
4574 # depend on whether or not the loop is a python type.
4575 self.py_loopvar_node.generate_evaluation_code(code)
4576 self.target.generate_assignment_code(self.py_loopvar_node, code)
4578 code.funcstate.release_temp(loopvar_name)
4579 break_label = code.break_label
4580 code.set_loop_labels(old_loop_labels)
4581 if self.else_clause:
4582 code.putln("/*else*/ {")
4583 self.else_clause.generate_execution_code(code)
4585 code.put_label(break_label)
4586 self.bound1.generate_disposal_code(code)
4587 self.bound1.free_temps(code)
4588 self.bound2.generate_disposal_code(code)
4589 self.bound2.free_temps(code)
4590 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4591 self.loopvar_node.release(code)
4592 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4593 self.py_loopvar_node.release(code)
4594 if self.step is not None:
4595 self.step.generate_disposal_code(code)
4596 self.step.free_temps(code)
4599 # {relop : (initial offset, increment op)}
4606 def generate_function_definitions(self, env, code):
4607 self.target.generate_function_definitions(env, code)
4608 self.bound1.generate_function_definitions(env, code)
4609 self.bound2.generate_function_definitions(env, code)
4610 if self.step is not None:
4611 self.step.generate_function_definitions(env, code)
4612 self.body.generate_function_definitions(env, code)
4613 if self.else_clause is not None:
4614 self.else_clause.generate_function_definitions(env, code)
4616 def annotate(self, code):
4617 self.target.annotate(code)
4618 self.bound1.annotate(code)
4619 self.bound2.annotate(code)
4621 self.step.annotate(code)
4622 self.body.annotate(code)
4623 if self.else_clause:
4624 self.else_clause.annotate(code)
4627 class WithStatNode(StatNode):
4629 Represents a Python with statement.
4631 This is only used at parse tree level; and is not present in
4632 analysis or generation phases.
4634 # manager The with statement manager object
4635 # target Node (lhs expression)
4637 child_attrs = ["manager", "target", "body"]
4639 class TryExceptStatNode(StatNode):
4640 # try .. except statement
4643 # except_clauses [ExceptClauseNode]
4644 # else_clause StatNode or None
4646 child_attrs = ["body", "except_clauses", "else_clause"]
4648 def analyse_control_flow(self, env):
4649 env.start_branching(self.pos)
4650 self.body.analyse_control_flow(env)
4651 successful_try = env.control_flow # grab this for later
4652 env.next_branch(self.body.end_pos())
4653 env.finish_branching(self.body.end_pos())
4655 env.start_branching(self.except_clauses[0].pos)
4656 for except_clause in self.except_clauses:
4657 except_clause.analyse_control_flow(env)
4658 env.next_branch(except_clause.end_pos())
4660 # the else cause it executed only when the try clause finishes
4661 env.control_flow.incoming = successful_try
4662 if self.else_clause:
4663 self.else_clause.analyse_control_flow(env)
4664 env.finish_branching(self.end_pos())
4666 def analyse_declarations(self, env):
4667 self.body.analyse_declarations(env)
4668 for except_clause in self.except_clauses:
4669 except_clause.analyse_declarations(env)
4670 if self.else_clause:
4671 self.else_clause.analyse_declarations(env)
4672 env.use_utility_code(reset_exception_utility_code)
4674 def analyse_expressions(self, env):
4675 self.body.analyse_expressions(env)
4676 default_clause_seen = 0
4677 for except_clause in self.except_clauses:
4678 except_clause.analyse_expressions(env)
4679 if default_clause_seen:
4680 error(except_clause.pos, "default 'except:' must be last")
4681 if not except_clause.pattern:
4682 default_clause_seen = 1
4683 self.has_default_clause = default_clause_seen
4684 if self.else_clause:
4685 self.else_clause.analyse_expressions(env)
4687 nogil_check = Node.gil_error
4688 gil_message = "Try-except statement"
4690 def generate_execution_code(self, code):
4691 old_return_label = code.return_label
4692 old_break_label = code.break_label
4693 old_continue_label = code.continue_label
4694 old_error_label = code.new_error_label()
4695 our_error_label = code.error_label
4696 except_end_label = code.new_label('exception_handled')
4697 except_error_label = code.new_label('except_error')
4698 except_return_label = code.new_label('except_return')
4699 try_return_label = code.new_label('try_return')
4700 try_break_label = code.new_label('try_break')
4701 try_continue_label = code.new_label('try_continue')
4702 try_end_label = code.new_label('try_end')
4705 code.putln("PyObject %s;" %
4706 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4707 code.putln("__Pyx_ExceptionSave(%s);" %
4708 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4709 for var in Naming.exc_save_vars:
4710 code.put_xgotref(var)
4713 code.return_label = try_return_label
4714 code.break_label = try_break_label
4715 code.continue_label = try_continue_label
4716 self.body.generate_execution_code(code)
4719 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4720 code.error_label = except_error_label
4721 code.return_label = except_return_label
4722 if self.else_clause:
4725 self.else_clause.generate_execution_code(code)
4728 for var in Naming.exc_save_vars:
4729 code.put_xdecref_clear(var, py_object_type)
4730 code.put_goto(try_end_label)
4731 if code.label_used(try_return_label):
4732 code.put_label(try_return_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_goto(old_return_label)
4737 code.put_label(our_error_label)
4738 for temp_name, type in temps_to_clean_up:
4739 code.put_xdecref_clear(temp_name, type)
4740 for except_clause in self.except_clauses:
4741 except_clause.generate_handling_code(code, except_end_label)
4743 error_label_used = code.label_used(except_error_label)
4744 if error_label_used or not self.has_default_clause:
4745 if error_label_used:
4746 code.put_label(except_error_label)
4747 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4748 code.putln("__Pyx_ExceptionReset(%s);" %
4749 ', '.join(Naming.exc_save_vars))
4750 code.put_goto(old_error_label)
4752 for exit_label, old_label in zip(
4753 [try_break_label, try_continue_label, except_return_label],
4754 [old_break_label, old_continue_label, old_return_label]):
4756 if code.label_used(exit_label):
4757 code.put_label(exit_label)
4758 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4759 code.putln("__Pyx_ExceptionReset(%s);" %
4760 ', '.join(Naming.exc_save_vars))
4761 code.put_goto(old_label)
4763 if code.label_used(except_end_label):
4764 code.put_label(except_end_label)
4765 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4766 code.putln("__Pyx_ExceptionReset(%s);" %
4767 ', '.join(Naming.exc_save_vars))
4768 code.put_label(try_end_label)
4771 code.return_label = old_return_label
4772 code.break_label = old_break_label
4773 code.continue_label = old_continue_label
4774 code.error_label = old_error_label
4776 def generate_function_definitions(self, env, code):
4777 self.body.generate_function_definitions(env, code)
4778 for except_clause in self.except_clauses:
4779 except_clause.generate_function_definitions(env, code)
4780 if self.else_clause is not None:
4781 self.else_clause.generate_function_definitions(env, code)
4783 def annotate(self, code):
4784 self.body.annotate(code)
4785 for except_node in self.except_clauses:
4786 except_node.annotate(code)
4787 if self.else_clause:
4788 self.else_clause.annotate(code)
4791 class ExceptClauseNode(Node):
4792 # Part of try ... except statement.
4794 # pattern [ExprNode]
4795 # target ExprNode or None
4797 # excinfo_target NameNode or None optional target for exception info
4798 # match_flag string result of exception match
4799 # exc_value ExcValueNode used internally
4800 # function_name string qualified name of enclosing function
4801 # exc_vars (string * 3) local exception variables
4803 # excinfo_target is never set by the parser, but can be set by a transform
4804 # in order to extract more extensive information about the exception as a
4805 # sys.exc_info()-style tuple into a target variable
4807 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4810 excinfo_target = None
4812 def analyse_declarations(self, env):
4814 self.target.analyse_target_declaration(env)
4815 if self.excinfo_target is not None:
4816 self.excinfo_target.analyse_target_declaration(env)
4817 self.body.analyse_declarations(env)
4819 def analyse_expressions(self, env):
4821 genv = env.global_scope()
4822 self.function_name = env.qualified_name
4824 # normalise/unpack self.pattern into a list
4825 for i, pattern in enumerate(self.pattern):
4826 pattern.analyse_expressions(env)
4827 self.pattern[i] = pattern.coerce_to_pyobject(env)
4830 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4831 self.target.analyse_target_expression(env, self.exc_value)
4832 if self.excinfo_target is not None:
4834 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4835 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4836 self.excinfo_tuple.analyse_expressions(env)
4837 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4839 self.body.analyse_expressions(env)
4841 def generate_handling_code(self, code, end_label):
4842 code.mark_pos(self.pos)
4845 for pattern in self.pattern:
4846 pattern.generate_evaluation_code(code)
4847 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4849 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4851 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4852 for pattern in self.pattern:
4853 pattern.generate_disposal_code(code)
4854 pattern.free_temps(code)
4858 code.funcstate.release_temp(match_flag)
4860 code.putln("/*except:*/ {")
4862 if not getattr(self.body, 'stats', True) and \
4863 self.excinfo_target is None and self.target is None:
4864 # most simple case: no exception variable, empty body (pass)
4865 # => reset the exception state, done
4866 code.putln("PyErr_Restore(0,0,0);")
4867 code.put_goto(end_label)
4871 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4874 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4875 # We always have to fetch the exception value even if
4876 # there is no target, because this also normalises the
4877 # exception and stores it in the thread state.
4878 code.globalstate.use_utility_code(get_exception_utility_code)
4879 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4880 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4881 code.error_goto(self.pos)))
4885 self.exc_value.set_var(exc_vars[1])
4886 self.exc_value.generate_evaluation_code(code)
4887 self.target.generate_assignment_code(self.exc_value, code)
4888 if self.excinfo_target is not None:
4889 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4890 node.set_var(tempvar)
4891 self.excinfo_tuple.generate_evaluation_code(code)
4892 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4894 old_break_label, old_continue_label = code.break_label, code.continue_label
4895 code.break_label = code.new_label('except_break')
4896 code.continue_label = code.new_label('except_continue')
4898 old_exc_vars = code.funcstate.exc_vars
4899 code.funcstate.exc_vars = exc_vars
4900 self.body.generate_execution_code(code)
4901 code.funcstate.exc_vars = old_exc_vars
4902 for var in exc_vars:
4903 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4904 code.put_goto(end_label)
4906 if code.label_used(code.break_label):
4907 code.put_label(code.break_label)
4908 for var in exc_vars:
4909 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4910 code.put_goto(old_break_label)
4911 code.break_label = old_break_label
4913 if code.label_used(code.continue_label):
4914 code.put_label(code.continue_label)
4915 for var in exc_vars:
4916 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4917 code.put_goto(old_continue_label)
4918 code.continue_label = old_continue_label
4920 for temp in exc_vars:
4921 code.funcstate.release_temp(temp)
4926 def generate_function_definitions(self, env, code):
4927 if self.target is not None:
4928 self.target.generate_function_definitions(env, code)
4929 self.body.generate_function_definitions(env, code)
4931 def annotate(self, code):
4933 for pattern in self.pattern:
4934 pattern.annotate(code)
4936 self.target.annotate(code)
4937 self.body.annotate(code)
4940 class TryFinallyStatNode(StatNode):
4941 # try ... finally statement
4944 # finally_clause StatNode
4946 # The plan is that we funnel all continue, break
4947 # return and error gotos into the beginning of the
4948 # finally block, setting a variable to remember which
4949 # one we're doing. At the end of the finally block, we
4950 # switch on the variable to figure out where to go.
4951 # In addition, if we're doing an error, we save the
4952 # exception on entry to the finally block and restore
4955 child_attrs = ["body", "finally_clause"]
4957 preserve_exception = 1
4959 disallow_continue_in_try_finally = 0
4960 # There doesn't seem to be any point in disallowing
4961 # continue in the try block, since we have no problem
4964 def create_analysed(pos, env, body, finally_clause):
4965 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4967 create_analysed = staticmethod(create_analysed)
4969 def analyse_control_flow(self, env):
4970 env.start_branching(self.pos)
4971 self.body.analyse_control_flow(env)
4972 env.next_branch(self.body.end_pos())
4973 env.finish_branching(self.body.end_pos())
4974 self.finally_clause.analyse_control_flow(env)
4976 def analyse_declarations(self, env):
4977 self.body.analyse_declarations(env)
4978 self.finally_clause.analyse_declarations(env)
4980 def analyse_expressions(self, env):
4981 self.body.analyse_expressions(env)
4982 self.finally_clause.analyse_expressions(env)
4984 nogil_check = Node.gil_error
4985 gil_message = "Try-finally statement"
4987 def generate_execution_code(self, code):
4988 old_error_label = code.error_label
4989 old_labels = code.all_new_labels()
4990 new_labels = code.get_all_labels()
4991 new_error_label = code.error_label
4992 catch_label = code.new_label()
4995 if self.disallow_continue_in_try_finally:
4996 was_in_try_finally = code.funcstate.in_try_finally
4997 code.funcstate.in_try_finally = 1
4998 self.body.generate_execution_code(code)
4999 if self.disallow_continue_in_try_finally:
5000 code.funcstate.in_try_finally = was_in_try_finally
5003 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5004 code.mark_pos(self.finally_clause.pos)
5008 error_label_used = 0
5009 for i, new_label in enumerate(new_labels):
5010 if new_label in code.labels_used:
5011 cases_used.append(i)
5012 if new_label == new_error_label:
5013 error_label_used = 1
5014 error_label_case = i
5018 if error_label_used and self.preserve_exception:
5020 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5022 "int %s;" % Naming.exc_lineno_name)
5023 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5024 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5025 code.putln(exc_var_init_zero)
5027 exc_var_init_zero = None
5028 code.use_label(catch_label)
5030 "__pyx_why = 0; goto %s;" % catch_label)
5031 for i in cases_used:
5032 new_label = new_labels[i]
5033 #if new_label and new_label != "<try>":
5034 if new_label == new_error_label and self.preserve_exception:
5035 self.put_error_catcher(code,
5036 new_error_label, i+1, catch_label, temps_to_clean_up)
5038 code.put('%s: ' % new_label)
5039 if exc_var_init_zero:
5040 code.putln(exc_var_init_zero)
5041 code.putln("__pyx_why = %s; goto %s;" % (
5044 code.put_label(catch_label)
5045 code.set_all_labels(old_labels)
5046 if error_label_used:
5047 code.new_error_label()
5048 finally_error_label = code.error_label
5049 self.finally_clause.generate_execution_code(code)
5050 if error_label_used:
5051 if finally_error_label in code.labels_used and self.preserve_exception:
5052 over_label = code.new_label()
5053 code.put_goto(over_label);
5054 code.put_label(finally_error_label)
5055 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5056 for var in Naming.exc_vars:
5057 code.putln("Py_XDECREF(%s);" % var)
5059 code.put_goto(old_error_label)
5060 code.put_label(over_label)
5061 code.error_label = old_error_label
5064 "switch (__pyx_why) {")
5065 for i in cases_used:
5066 old_label = old_labels[i]
5067 if old_label == old_error_label and self.preserve_exception:
5068 self.put_error_uncatcher(code, i+1, old_error_label)
5070 code.use_label(old_label)
5072 "case %s: goto %s;" % (
5080 def generate_function_definitions(self, env, code):
5081 self.body.generate_function_definitions(env, code)
5082 self.finally_clause.generate_function_definitions(env, code)
5084 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5085 code.globalstate.use_utility_code(restore_exception_utility_code)
5092 for temp_name, type in temps_to_clean_up:
5093 code.put_xdecref_clear(temp_name, type)
5095 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5099 Naming.exc_lineno_name, Naming.lineno_cname))
5100 code.put_goto(catch_label)
5103 def put_error_uncatcher(self, code, i, error_label):
5104 code.globalstate.use_utility_code(restore_exception_utility_code)
5109 "__Pyx_ErrRestore(%s, %s, %s);" %
5113 Naming.lineno_cname, Naming.exc_lineno_name))
5114 for var in Naming.exc_vars:
5118 code.put_goto(error_label)
5122 def annotate(self, code):
5123 self.body.annotate(code)
5124 self.finally_clause.annotate(code)
5127 class GILStatNode(TryFinallyStatNode):
5128 # 'with gil' or 'with nogil' statement
5130 # state string 'gil' or 'nogil'
5134 preserve_exception = 0
5136 def __init__(self, pos, state, body):
5138 TryFinallyStatNode.__init__(self, pos,
5140 finally_clause = GILExitNode(pos, state = state))
5142 def analyse_expressions(self, env):
5143 env.use_utility_code(force_init_threads_utility_code)
5144 was_nogil = env.nogil
5146 TryFinallyStatNode.analyse_expressions(self, env)
5147 env.nogil = was_nogil
5151 def generate_execution_code(self, code):
5152 code.mark_pos(self.pos)
5154 if self.state == 'gil':
5155 code.putln("#ifdef WITH_THREAD")
5156 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5157 code.putln("#endif")
5159 code.putln("#ifdef WITH_THREAD")
5160 code.putln("PyThreadState *_save = NULL;")
5161 code.putln("#endif")
5162 code.putln("Py_UNBLOCK_THREADS")
5163 TryFinallyStatNode.generate_execution_code(self, code)
5167 class GILExitNode(StatNode):
5168 # Used as the 'finally' block in a GILStatNode
5170 # state string 'gil' or 'nogil'
5174 def analyse_expressions(self, env):
5177 def generate_execution_code(self, code):
5178 if self.state == 'gil':
5179 code.putln("#ifdef WITH_THREAD")
5180 code.putln("PyGILState_Release(_save);")
5181 code.putln("#endif")
5183 code.putln("Py_BLOCK_THREADS")
5186 class CImportStatNode(StatNode):
5189 # module_name string Qualified name of module being imported
5190 # as_name string or None Name specified in "as" clause, if any
5194 def analyse_declarations(self, env):
5195 if not env.is_module_scope:
5196 error(self.pos, "cimport only allowed at module level")
5198 module_scope = env.find_module(self.module_name, self.pos)
5199 if "." in self.module_name:
5200 names = [EncodedString(name) for name in self.module_name.split(".")]
5202 top_module_scope = env.context.find_submodule(top_name)
5203 module_scope = top_module_scope
5204 for name in names[1:]:
5205 submodule_scope = module_scope.find_submodule(name)
5206 module_scope.declare_module(name, submodule_scope, self.pos)
5207 module_scope = submodule_scope
5209 env.declare_module(self.as_name, module_scope, self.pos)
5211 env.declare_module(top_name, top_module_scope, self.pos)
5213 name = self.as_name or self.module_name
5214 env.declare_module(name, module_scope, self.pos)
5216 def analyse_expressions(self, env):
5219 def generate_execution_code(self, code):
5223 class FromCImportStatNode(StatNode):
5224 # from ... cimport statement
5226 # module_name string Qualified name of module
5227 # imported_names [(pos, name, as_name, kind)] Names to be imported
5231 def analyse_declarations(self, env):
5232 if not env.is_module_scope:
5233 error(self.pos, "cimport only allowed at module level")
5235 module_scope = env.find_module(self.module_name, self.pos)
5236 env.add_imported_module(module_scope)
5237 for pos, name, as_name, kind in self.imported_names:
5239 for local_name, entry in module_scope.entries.items():
5240 env.add_imported_entry(local_name, entry, pos)
5242 entry = module_scope.lookup(name)
5244 if kind and not self.declaration_matches(entry, kind):
5245 entry.redeclared(pos)
5247 if kind == 'struct' or kind == 'union':
5248 entry = module_scope.declare_struct_or_union(name,
5249 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5250 elif kind == 'class':
5251 entry = module_scope.declare_c_class(name, pos = pos,
5252 module_name = self.module_name)
5254 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5255 if submodule_scope.parent_module is module_scope:
5256 env.declare_module(as_name or name, submodule_scope, self.pos)
5258 error(pos, "Name '%s' not declared in module '%s'"
5259 % (name, self.module_name))
5262 local_name = as_name or name
5263 env.add_imported_entry(local_name, entry, pos)
5265 def declaration_matches(self, entry, kind):
5266 if not entry.is_type:
5270 if not type.is_extension_type:
5273 if not type.is_struct_or_union:
5275 if kind != type.kind:
5279 def analyse_expressions(self, env):
5282 def generate_execution_code(self, code):
5286 class FromImportStatNode(StatNode):
5287 # from ... import statement
5290 # items [(string, NameNode)]
5291 # interned_items [(string, NameNode, ExprNode)]
5292 # item PyTempNode used internally
5293 # import_star boolean used internally
5295 child_attrs = ["module"]
5298 def analyse_declarations(self, env):
5299 for name, target in self.items:
5301 if not env.is_module_scope:
5302 error(self.pos, "import * only allowed at module level")
5304 env.has_import_star = 1
5305 self.import_star = 1
5307 target.analyse_target_declaration(env)
5309 def analyse_expressions(self, env):
5311 self.module.analyse_expressions(env)
5312 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5313 self.interned_items = []
5314 for name, target in self.items:
5316 for _, entry in env.entries.items():
5317 if not entry.is_type and entry.type.is_extension_type:
5318 env.use_utility_code(ExprNodes.type_test_utility_code)
5321 entry = env.lookup(target.name)
5322 # check whether or not entry is already cimported
5323 if (entry.is_type and entry.type.name == name
5324 and hasattr(entry.type, 'module_name')):
5325 if entry.type.module_name == self.module.module_name.value:
5326 # cimported with absolute name
5329 # cimported with relative name
5330 module = env.find_module(self.module.module_name.value,
5332 if entry.type.module_name == module.qualified_name:
5334 except AttributeError:
5336 target.analyse_target_expression(env, None)
5337 if target.type is py_object_type:
5340 coerced_item = self.item.coerce_to(target.type, env)
5341 self.interned_items.append((name, target, coerced_item))
5343 def generate_execution_code(self, code):
5344 self.module.generate_evaluation_code(code)
5345 if self.import_star:
5347 'if (%s(%s) < 0) %s;' % (
5349 self.module.py_result(),
5350 code.error_goto(self.pos)))
5351 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5352 self.item.set_cname(item_temp)
5353 for name, target, coerced_item in self.interned_items:
5354 cname = code.intern_identifier(name)
5356 '%s = PyObject_GetAttr(%s, %s); %s' % (
5358 self.module.py_result(),
5360 code.error_goto_if_null(item_temp, self.pos)))
5361 code.put_gotref(item_temp)
5362 if coerced_item is None:
5363 target.generate_assignment_code(self.item, code)
5365 coerced_item.allocate_temp_result(code)
5366 coerced_item.generate_result_code(code)
5367 target.generate_assignment_code(coerced_item, code)
5368 code.put_decref_clear(item_temp, py_object_type)
5369 code.funcstate.release_temp(item_temp)
5370 self.module.generate_disposal_code(code)
5371 self.module.free_temps(code)
5375 #------------------------------------------------------------------------------------
5377 # Runtime support code
5379 #------------------------------------------------------------------------------------
5381 utility_function_predeclarations = \
5383 /* inline attribute */
5384 #ifndef CYTHON_INLINE
5385 #if defined(__GNUC__)
5386 #define CYTHON_INLINE __inline__
5387 #elif defined(_MSC_VER)
5388 #define CYTHON_INLINE __inline
5389 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5390 #define CYTHON_INLINE inline
5392 #define CYTHON_INLINE
5396 /* unused attribute */
5397 #ifndef CYTHON_UNUSED
5398 # if defined(__GNUC__)
5399 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5400 # define CYTHON_UNUSED __attribute__ ((__unused__))
5402 # define CYTHON_UNUSED
5404 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5405 # define CYTHON_UNUSED __attribute__ ((__unused__))
5407 # define CYTHON_UNUSED
5411 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*/
5415 if Options.gcc_branch_hints:
5416 branch_prediction_macros = \
5419 /* Test for GCC > 2.95 */
5420 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5421 #define likely(x) __builtin_expect(!!(x), 1)
5422 #define unlikely(x) __builtin_expect(!!(x), 0)
5423 #else /* __GNUC__ > 2 ... */
5424 #define likely(x) (x)
5425 #define unlikely(x) (x)
5426 #endif /* __GNUC__ > 2 ... */
5427 #else /* __GNUC__ */
5428 #define likely(x) (x)
5429 #define unlikely(x) (x)
5430 #endif /* __GNUC__ */
5433 branch_prediction_macros = \
5435 #define likely(x) (x)
5436 #define unlikely(x) (x)
5439 #get_name_predeclaration = \
5440 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5442 #get_name_interned_predeclaration = \
5443 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5445 #------------------------------------------------------------------------------------
5447 printing_utility_code = UtilityCode(
5449 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5450 #if PY_MAJOR_VERSION >= 3
5451 static PyObject* %s = 0;
5452 static PyObject* %s = 0;
5454 """ % (Naming.print_function, Naming.print_function_kwargs),
5456 #if PY_MAJOR_VERSION >= 3
5460 """ % (Naming.print_function, Naming.print_function_kwargs),
5462 #if PY_MAJOR_VERSION < 3
5463 static PyObject *__Pyx_GetStdout(void) {
5464 PyObject *f = PySys_GetObject((char *)"stdout");
5466 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5471 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5476 if (!(f = __Pyx_GetStdout()))
5479 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5480 if (PyFile_SoftSpace(f, 1)) {
5481 if (PyFile_WriteString(" ", f) < 0)
5484 v = PyTuple_GET_ITEM(arg_tuple, i);
5485 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5487 if (PyString_Check(v)) {
5488 char *s = PyString_AsString(v);
5489 Py_ssize_t len = PyString_Size(v);
5491 isspace(Py_CHARMASK(s[len-1])) &&
5493 PyFile_SoftSpace(f, 0);
5497 if (PyFile_WriteString("\n", f) < 0)
5499 PyFile_SoftSpace(f, 0);
5504 #else /* Python 3 has a print function */
5506 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5507 PyObject* kwargs = 0;
5508 PyObject* result = 0;
5509 PyObject* end_string;
5510 if (unlikely(!%(PRINT_FUNCTION)s)) {
5511 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5512 if (!%(PRINT_FUNCTION)s)
5516 kwargs = PyDict_New();
5517 if (unlikely(!kwargs))
5519 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5522 end_string = PyUnicode_FromStringAndSize(" ", 1);
5523 if (unlikely(!end_string))
5525 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5526 Py_DECREF(end_string);
5529 Py_DECREF(end_string);
5531 } else if (!newline) {
5532 if (unlikely(!%(PRINT_KWARGS)s)) {
5533 %(PRINT_KWARGS)s = PyDict_New();
5534 if (unlikely(!%(PRINT_KWARGS)s))
5536 end_string = PyUnicode_FromStringAndSize(" ", 1);
5537 if (unlikely(!end_string))
5539 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5540 Py_DECREF(end_string);
5543 Py_DECREF(end_string);
5545 kwargs = %(PRINT_KWARGS)s;
5547 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5548 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5555 if (kwargs != %(PRINT_KWARGS)s)
5561 """ % {'BUILTINS' : Naming.builtins_cname,
5562 'PRINT_FUNCTION' : Naming.print_function,
5563 'PRINT_KWARGS' : Naming.print_function_kwargs}
5567 printing_one_utility_code = UtilityCode(
5569 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5572 #if PY_MAJOR_VERSION < 3
5574 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5576 if (!(f = __Pyx_GetStdout()))
5579 if (PyFile_SoftSpace(f, 0)) {
5580 if (PyFile_WriteString(" ", f) < 0)
5583 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5585 if (PyFile_WriteString("\n", f) < 0)
5588 /* the line below is just to avoid compiler
5589 * compiler warnings about unused functions */
5590 return __Pyx_Print(f, NULL, 0);
5593 #else /* Python 3 has a print function */
5595 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5597 PyObject* arg_tuple = PyTuple_New(1);
5598 if (unlikely(!arg_tuple))
5601 PyTuple_SET_ITEM(arg_tuple, 0, o);
5602 res = __Pyx_Print(stream, arg_tuple, 1);
5603 Py_DECREF(arg_tuple);
5609 requires=[printing_utility_code])
5613 #------------------------------------------------------------------------------------
5615 # Exception raising code
5617 # Exceptions are raised by __Pyx_Raise() and stored as plain
5618 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5619 # 'except' statement, curexc_* is moved over to exc_* by
5620 # __Pyx_GetException()
5622 restore_exception_utility_code = UtilityCode(
5624 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5625 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5628 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5629 PyObject *tmp_type, *tmp_value, *tmp_tb;
5630 PyThreadState *tstate = PyThreadState_GET();
5632 tmp_type = tstate->curexc_type;
5633 tmp_value = tstate->curexc_value;
5634 tmp_tb = tstate->curexc_traceback;
5635 tstate->curexc_type = type;
5636 tstate->curexc_value = value;
5637 tstate->curexc_traceback = tb;
5638 Py_XDECREF(tmp_type);
5639 Py_XDECREF(tmp_value);
5643 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5644 PyThreadState *tstate = PyThreadState_GET();
5645 *type = tstate->curexc_type;
5646 *value = tstate->curexc_value;
5647 *tb = tstate->curexc_traceback;
5649 tstate->curexc_type = 0;
5650 tstate->curexc_value = 0;
5651 tstate->curexc_traceback = 0;
5656 # The following function is based on do_raise() from ceval.c. There
5657 # are separate versions for Python2 and Python3 as exception handling
5658 # has changed quite a lot between the two versions.
5660 raise_utility_code = UtilityCode(
5662 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5665 #if PY_MAJOR_VERSION < 3
5666 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5670 /* First, check the traceback argument, replacing None with NULL. */
5671 if (tb == Py_None) {
5675 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5676 PyErr_SetString(PyExc_TypeError,
5677 "raise: arg 3 must be a traceback or None");
5680 /* Next, replace a missing value with None */
5681 if (value == NULL) {
5685 #if PY_VERSION_HEX < 0x02050000
5686 if (!PyClass_Check(type))
5688 if (!PyType_Check(type))
5691 /* Raising an instance. The value should be a dummy. */
5692 if (value != Py_None) {
5693 PyErr_SetString(PyExc_TypeError,
5694 "instance exception may not have a separate value");
5697 /* Normalize to raise <class>, <instance> */
5700 #if PY_VERSION_HEX < 0x02050000
5701 if (PyInstance_Check(type)) {
5702 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5707 PyErr_SetString(PyExc_TypeError,
5708 "raise: exception must be an old-style class or instance");
5712 type = (PyObject*) Py_TYPE(type);
5714 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5715 PyErr_SetString(PyExc_TypeError,
5716 "raise: exception class must be a subclass of BaseException");
5722 __Pyx_ErrRestore(type, value, tb);
5731 #else /* Python 3+ */
5733 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5734 if (tb == Py_None) {
5736 } else if (tb && !PyTraceBack_Check(tb)) {
5737 PyErr_SetString(PyExc_TypeError,
5738 "raise: arg 3 must be a traceback or None");
5741 if (value == Py_None)
5744 if (PyExceptionInstance_Check(type)) {
5746 PyErr_SetString(PyExc_TypeError,
5747 "instance exception may not have a separate value");
5751 type = (PyObject*) Py_TYPE(value);
5752 } else if (!PyExceptionClass_Check(type)) {
5753 PyErr_SetString(PyExc_TypeError,
5754 "raise: exception class must be a subclass of BaseException");
5758 PyErr_SetObject(type, value);
5761 PyThreadState *tstate = PyThreadState_GET();
5762 PyObject* tmp_tb = tstate->curexc_traceback;
5765 tstate->curexc_traceback = tb;
5775 requires=[restore_exception_utility_code])
5777 #------------------------------------------------------------------------------------
5779 get_exception_utility_code = UtilityCode(
5781 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5784 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5785 PyObject *local_type, *local_value, *local_tb;
5786 PyObject *tmp_type, *tmp_value, *tmp_tb;
5787 PyThreadState *tstate = PyThreadState_GET();
5788 local_type = tstate->curexc_type;
5789 local_value = tstate->curexc_value;
5790 local_tb = tstate->curexc_traceback;
5791 tstate->curexc_type = 0;
5792 tstate->curexc_value = 0;
5793 tstate->curexc_traceback = 0;
5794 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5795 if (unlikely(tstate->curexc_type))
5797 #if PY_MAJOR_VERSION >= 3
5798 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5802 *value = local_value;
5804 Py_INCREF(local_type);
5805 Py_INCREF(local_value);
5806 Py_INCREF(local_tb);
5807 tmp_type = tstate->exc_type;
5808 tmp_value = tstate->exc_value;
5809 tmp_tb = tstate->exc_traceback;
5810 tstate->exc_type = local_type;
5811 tstate->exc_value = local_value;
5812 tstate->exc_traceback = local_tb;
5813 /* Make sure tstate is in a consistent state when we XDECREF
5814 these objects (XDECREF may run arbitrary code). */
5815 Py_XDECREF(tmp_type);
5816 Py_XDECREF(tmp_value);
5823 Py_XDECREF(local_type);
5824 Py_XDECREF(local_value);
5825 Py_XDECREF(local_tb);
5831 #------------------------------------------------------------------------------------
5833 get_exception_tuple_utility_code = UtilityCode(proto="""
5834 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5836 # I doubt that calling __Pyx_GetException() here is correct as it moves
5837 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5838 # exception handlers later on from receiving it.
5840 static PyObject *__Pyx_GetExceptionTuple(void) {
5841 PyObject *type = NULL, *value = NULL, *tb = NULL;
5842 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5843 PyObject* exc_info = PyTuple_New(3);
5848 PyTuple_SET_ITEM(exc_info, 0, type);
5849 PyTuple_SET_ITEM(exc_info, 1, value);
5850 PyTuple_SET_ITEM(exc_info, 2, tb);
5857 requires=[get_exception_utility_code])
5859 #------------------------------------------------------------------------------------
5861 reset_exception_utility_code = UtilityCode(
5863 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5864 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5867 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5868 PyThreadState *tstate = PyThreadState_GET();
5869 *type = tstate->exc_type;
5870 *value = tstate->exc_value;
5871 *tb = tstate->exc_traceback;
5877 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5878 PyObject *tmp_type, *tmp_value, *tmp_tb;
5879 PyThreadState *tstate = PyThreadState_GET();
5880 tmp_type = tstate->exc_type;
5881 tmp_value = tstate->exc_value;
5882 tmp_tb = tstate->exc_traceback;
5883 tstate->exc_type = type;
5884 tstate->exc_value = value;
5885 tstate->exc_traceback = tb;
5886 Py_XDECREF(tmp_type);
5887 Py_XDECREF(tmp_value);
5892 #------------------------------------------------------------------------------------
5894 arg_type_test_utility_code = UtilityCode(
5896 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5897 const char *name, int exact); /*proto*/
5900 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5901 const char *name, int exact)
5904 PyErr_Format(PyExc_SystemError, "Missing type object");
5907 if (none_allowed && obj == Py_None) return 1;
5909 if (Py_TYPE(obj) == type) return 1;
5912 if (PyObject_TypeCheck(obj, type)) return 1;
5914 PyErr_Format(PyExc_TypeError,
5915 "Argument '%s' has incorrect type (expected %s, got %s)",
5916 name, type->tp_name, Py_TYPE(obj)->tp_name);
5921 #------------------------------------------------------------------------------------
5923 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5924 # many or too few positional arguments were found. This handles
5925 # Py_ssize_t formatting correctly.
5927 raise_argtuple_invalid_utility_code = UtilityCode(
5929 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5930 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5933 static void __Pyx_RaiseArgtupleInvalid(
5934 const char* func_name,
5938 Py_ssize_t num_found)
5940 Py_ssize_t num_expected;
5941 const char *number, *more_or_less;
5943 if (num_found < num_min) {
5944 num_expected = num_min;
5945 more_or_less = "at least";
5947 num_expected = num_max;
5948 more_or_less = "at most";
5951 more_or_less = "exactly";
5953 number = (num_expected == 1) ? "" : "s";
5954 PyErr_Format(PyExc_TypeError,
5955 #if PY_VERSION_HEX < 0x02050000
5956 "%s() takes %s %d positional argument%s (%d given)",
5958 "%s() takes %s %zd positional argument%s (%zd given)",
5960 func_name, more_or_less, num_expected, number, num_found);
5964 raise_keyword_required_utility_code = UtilityCode(
5966 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5969 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5970 const char* func_name,
5973 PyErr_Format(PyExc_TypeError,
5974 #if PY_MAJOR_VERSION >= 3
5975 "%s() needs keyword-only argument %U", func_name, kw_name);
5977 "%s() needs keyword-only argument %s", func_name,
5978 PyString_AS_STRING(kw_name));
5983 raise_double_keywords_utility_code = UtilityCode(
5985 static void __Pyx_RaiseDoubleKeywordsError(
5986 const char* func_name, PyObject* kw_name); /*proto*/
5989 static void __Pyx_RaiseDoubleKeywordsError(
5990 const char* func_name,
5993 PyErr_Format(PyExc_TypeError,
5994 #if PY_MAJOR_VERSION >= 3
5995 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5997 "%s() got multiple values for keyword argument '%s'", func_name,
5998 PyString_AS_STRING(kw_name));
6003 #------------------------------------------------------------------------------------
6005 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6006 # were passed to a function, or if any keywords were passed to a
6007 # function that does not accept them.
6009 keyword_string_check_utility_code = UtilityCode(
6011 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6012 const char* function_name, int kw_allowed); /*proto*/
6015 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6017 const char* function_name,
6022 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6023 #if PY_MAJOR_VERSION < 3
6024 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6026 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6028 goto invalid_keyword_type;
6030 if ((!kw_allowed) && unlikely(key))
6031 goto invalid_keyword;
6033 invalid_keyword_type:
6034 PyErr_Format(PyExc_TypeError,
6035 "%s() keywords must be strings", function_name);
6038 PyErr_Format(PyExc_TypeError,
6039 #if PY_MAJOR_VERSION < 3
6040 "%s() got an unexpected keyword argument '%s'",
6041 function_name, PyString_AsString(key));
6043 "%s() got an unexpected keyword argument '%U'",
6044 function_name, key);
6050 #------------------------------------------------------------------------------------
6052 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6053 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6054 # keywords will raise an invalid keyword error.
6056 # Three kinds of errors are checked: 1) non-string keywords, 2)
6057 # unexpected keywords and 3) overlap with positional arguments.
6059 # If num_posargs is greater 0, it denotes the number of positional
6060 # arguments that were passed and that must therefore not appear
6061 # amongst the keywords as well.
6063 # This method does not check for required keyword arguments.
6066 parse_keywords_utility_code = UtilityCode(
6068 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6069 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6070 const char* function_name); /*proto*/
6073 static int __Pyx_ParseOptionalKeywords(
6075 PyObject **argnames[],
6078 Py_ssize_t num_pos_args,
6079 const char* function_name)
6081 PyObject *key = 0, *value = 0;
6084 PyObject*** first_kw_arg = argnames + num_pos_args;
6086 while (PyDict_Next(kwds, &pos, &key, &value)) {
6087 name = first_kw_arg;
6088 while (*name && (**name != key)) name++;
6090 values[name-argnames] = value;
6092 #if PY_MAJOR_VERSION < 3
6093 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6095 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6097 goto invalid_keyword_type;
6099 for (name = first_kw_arg; *name; name++) {
6100 #if PY_MAJOR_VERSION >= 3
6101 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6102 PyUnicode_Compare(**name, key) == 0) break;
6104 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6105 _PyString_Eq(**name, key)) break;
6109 values[name-argnames] = value;
6111 /* unexpected keyword found */
6112 for (name=argnames; name != first_kw_arg; name++) {
6113 if (**name == key) goto arg_passed_twice;
6114 #if PY_MAJOR_VERSION >= 3
6115 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6116 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6118 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6119 _PyString_Eq(**name, key)) goto arg_passed_twice;
6123 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6125 goto invalid_keyword;
6133 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6135 invalid_keyword_type:
6136 PyErr_Format(PyExc_TypeError,
6137 "%s() keywords must be strings", function_name);
6140 PyErr_Format(PyExc_TypeError,
6141 #if PY_MAJOR_VERSION < 3
6142 "%s() got an unexpected keyword argument '%s'",
6143 function_name, PyString_AsString(key));
6145 "%s() got an unexpected keyword argument '%U'",
6146 function_name, key);
6152 requires=[raise_double_keywords_utility_code])
6154 #------------------------------------------------------------------------------------
6156 traceback_utility_code = UtilityCode(
6158 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6161 #include "compile.h"
6162 #include "frameobject.h"
6163 #include "traceback.h"
6165 static void __Pyx_AddTraceback(const char *funcname) {
6166 PyObject *py_srcfile = 0;
6167 PyObject *py_funcname = 0;
6168 PyObject *py_globals = 0;
6169 PyCodeObject *py_code = 0;
6170 PyFrameObject *py_frame = 0;
6172 #if PY_MAJOR_VERSION < 3
6173 py_srcfile = PyString_FromString(%(FILENAME)s);
6175 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6177 if (!py_srcfile) goto bad;
6179 #if PY_MAJOR_VERSION < 3
6180 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6182 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6186 #if PY_MAJOR_VERSION < 3
6187 py_funcname = PyString_FromString(funcname);
6189 py_funcname = PyUnicode_FromString(funcname);
6192 if (!py_funcname) goto bad;
6193 py_globals = PyModule_GetDict(%(GLOBALS)s);
6194 if (!py_globals) goto bad;
6195 py_code = PyCode_New(
6196 0, /*int argcount,*/
6197 #if PY_MAJOR_VERSION >= 3
6198 0, /*int kwonlyargcount,*/
6201 0, /*int stacksize,*/
6203 %(EMPTY_BYTES)s, /*PyObject *code,*/
6204 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6205 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6206 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6207 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6208 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6209 py_srcfile, /*PyObject *filename,*/
6210 py_funcname, /*PyObject *name,*/
6211 %(LINENO)s, /*int firstlineno,*/
6212 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6214 if (!py_code) goto bad;
6215 py_frame = PyFrame_New(
6216 PyThreadState_GET(), /*PyThreadState *tstate,*/
6217 py_code, /*PyCodeObject *code,*/
6218 py_globals, /*PyObject *globals,*/
6219 0 /*PyObject *locals*/
6221 if (!py_frame) goto bad;
6222 py_frame->f_lineno = %(LINENO)s;
6223 PyTraceBack_Here(py_frame);
6225 Py_XDECREF(py_srcfile);
6226 Py_XDECREF(py_funcname);
6227 Py_XDECREF(py_code);
6228 Py_XDECREF(py_frame);
6231 'FILENAME': Naming.filename_cname,
6232 'LINENO': Naming.lineno_cname,
6233 'CFILENAME': Naming.cfilenm_cname,
6234 'CLINENO': Naming.clineno_cname,
6235 'GLOBALS': Naming.module_cname,
6236 'EMPTY_TUPLE' : Naming.empty_tuple,
6237 'EMPTY_BYTES' : Naming.empty_bytes,
6240 #------------------------------------------------------------------------------------
6242 unraisable_exception_utility_code = UtilityCode(
6244 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6247 static void __Pyx_WriteUnraisable(const char *name) {
6248 PyObject *old_exc, *old_val, *old_tb;
6250 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6251 #if PY_MAJOR_VERSION < 3
6252 ctx = PyString_FromString(name);
6254 ctx = PyUnicode_FromString(name);
6256 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6258 PyErr_WriteUnraisable(Py_None);
6260 PyErr_WriteUnraisable(ctx);
6265 requires=[restore_exception_utility_code])
6267 #------------------------------------------------------------------------------------
6269 set_vtable_utility_code = UtilityCode(
6271 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6274 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6275 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6276 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6278 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6282 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6292 #------------------------------------------------------------------------------------
6294 get_vtable_utility_code = UtilityCode(
6296 static void* __Pyx_GetVtable(PyObject *dict); /*proto*/
6299 static void* __Pyx_GetVtable(PyObject *dict) {
6301 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6304 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6305 ptr = PyCapsule_GetPointer(ob, 0);
6307 ptr = PyCObject_AsVoidPtr(ob);
6309 if (!ptr && !PyErr_Occurred())
6310 PyErr_SetString(PyExc_RuntimeError, "invalid vtable found for imported type");
6319 #------------------------------------------------------------------------------------
6321 init_string_tab_utility_code = UtilityCode(
6323 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6326 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6328 #if PY_MAJOR_VERSION < 3
6329 if (t->is_unicode) {
6330 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6331 } else if (t->intern) {
6332 *t->p = PyString_InternFromString(t->s);
6334 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6336 #else /* Python 3+ has unicode identifiers */
6337 if (t->is_unicode | t->is_str) {
6339 *t->p = PyUnicode_InternFromString(t->s);
6340 } else if (t->encoding) {
6341 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6343 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6346 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6357 #------------------------------------------------------------------------------------
6359 force_init_threads_utility_code = UtilityCode(
6361 #ifndef __PYX_FORCE_INIT_THREADS
6362 #if PY_VERSION_HEX < 0x02040200
6363 #define __PYX_FORCE_INIT_THREADS 1
6365 #define __PYX_FORCE_INIT_THREADS 0
6370 #------------------------------------------------------------------------------------
6372 # Note that cPython ignores PyTrace_EXCEPTION,
6373 # but maybe some other profilers don't.
6375 profile_utility_code = UtilityCode(proto="""
6376 #ifndef CYTHON_PROFILE
6377 #define CYTHON_PROFILE 1
6380 #ifndef CYTHON_PROFILE_REUSE_FRAME
6381 #define CYTHON_PROFILE_REUSE_FRAME 0
6386 #include "compile.h"
6387 #include "frameobject.h"
6388 #include "traceback.h"
6390 #if CYTHON_PROFILE_REUSE_FRAME
6391 #define CYTHON_FRAME_MODIFIER static
6392 #define CYTHON_FRAME_DEL
6394 #define CYTHON_FRAME_MODIFIER
6395 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6398 #define __Pyx_TraceDeclarations \\
6399 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6400 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6401 int __Pyx_use_tracing = 0;
6403 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6404 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6405 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6408 #define __Pyx_TraceException() \\
6409 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6410 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6412 PyThreadState_GET()->c_profilefunc( \\
6413 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6414 Py_DECREF(exc_info); \\
6418 #define __Pyx_TraceReturn(result) \\
6419 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6420 PyThreadState_GET()->c_profilefunc( \\
6421 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6422 CYTHON_FRAME_DEL; \\
6425 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6426 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6430 #define __Pyx_TraceDeclarations
6431 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6432 #define __Pyx_TraceException()
6433 #define __Pyx_TraceReturn(result)
6435 #endif /* CYTHON_PROFILE */
6438 "FRAME": Naming.frame_cname,
6439 "FRAME_CODE": Naming.frame_code_cname,
6445 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6446 PyFrameObject** frame,
6447 const char *funcname,
6448 const char *srcfile,
6450 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6451 if (*code == NULL) {
6452 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6453 if (*code == NULL) return 0;
6455 *frame = PyFrame_New(
6456 PyThreadState_GET(), /*PyThreadState *tstate*/
6457 *code, /*PyCodeObject *code*/
6458 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6459 0 /*PyObject *locals*/
6461 if (*frame == NULL) return 0;
6464 (*frame)->f_tstate = PyThreadState_GET();
6466 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6469 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6470 PyObject *py_srcfile = 0;
6471 PyObject *py_funcname = 0;
6472 PyCodeObject *py_code = 0;
6474 #if PY_MAJOR_VERSION < 3
6475 py_funcname = PyString_FromString(funcname);
6476 py_srcfile = PyString_FromString(srcfile);
6478 py_funcname = PyUnicode_FromString(funcname);
6479 py_srcfile = PyUnicode_FromString(srcfile);
6481 if (!py_funcname | !py_srcfile) goto bad;
6483 py_code = PyCode_New(
6484 0, /*int argcount,*/
6485 #if PY_MAJOR_VERSION >= 3
6486 0, /*int kwonlyargcount,*/
6489 0, /*int stacksize,*/
6491 %(EMPTY_BYTES)s, /*PyObject *code,*/
6492 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6493 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6494 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6495 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6496 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6497 py_srcfile, /*PyObject *filename,*/
6498 py_funcname, /*PyObject *name,*/
6499 firstlineno, /*int firstlineno,*/
6500 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6504 Py_XDECREF(py_srcfile);
6505 Py_XDECREF(py_funcname);
6510 #endif /* CYTHON_PROFILE */
6512 'EMPTY_TUPLE' : Naming.empty_tuple,
6513 'EMPTY_BYTES' : Naming.empty_bytes,
6514 "MODULE": Naming.module_cname,