3 # Pyrex - Parse tree nodes
8 cython.declare(sys=object, os=object, time=object, copy=object,
9 Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10 py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11 StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12 CppClassScope=object, UtilityCode=object, EncodedString=object,
13 absolute_path_length=cython.Py_ssize_t)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode, ClosureTempAllocator
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
32 absolute_path_length = 0
34 def relative_position(pos):
36 We embed the relative filename in the generated C file, since we
37 don't want to have to regnerate and compile all the source code
38 whenever the Python install directory moves (which could happen,
39 e.g,. when distributing binaries.)
42 a position tuple -- (absolute filename, line number column position)
50 global absolute_path_length
51 if absolute_path_length==0:
52 absolute_path_length = len(os.path.abspath(os.getcwd()))
53 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
63 # make sure we can encode the filename in the docstring encoding
64 # otherwise make the docstring a unicode string
65 encoding = docstring.encoding
66 if encoding is not None:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
86 if len(args) > 1 and isinstance(args[1], CCodeWriter):
87 # here we annotate the code with this function call
88 # but only if new code is generated
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
111 class VerboseCodeWriter(type):
112 # Set this as a metaclass to trace function calls in code.
113 # This slows down code generation and makes much larger files.
114 def __new__(cls, name, bases, attrs):
116 for mname, m in attrs.items():
117 if isinstance(m, FunctionType):
118 attrs[mname] = write_func_call(m)
119 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
134 # All descandants should set child_attrs to a list of the attributes
135 # containing nodes considered "children" in the tree. Each such attribute
136 # can either contain a single node or a list of nodes. See Visitor.py.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
159 def clone_node(self):
160 """Clone the node. This is defined as a shallow copy, except for member lists
161 amongst the child attributes (from get_child_accessors) which are also
162 copied. Lists containing child nodes are thus seen as a way for the node
163 to hold multiple children directly; the list is not treated as a seperate
164 level in the tree."""
165 result = copy.copy(self)
166 for attrname in result.child_attrs:
167 value = getattr(result, attrname)
168 if isinstance(value, list):
169 setattr(result, attrname, [x for x in value])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
181 # (1) analyse_declarations
182 # Make symbol table entries for all declarations at the current
183 # level, both explicit (def, cdef, etc.) and implicit (assignment
184 # to an otherwise undeclared name).
186 # (2) analyse_expressions
187 # Determine the result types of expressions and fill in the
188 # 'type' attribute of each ExprNode. Insert coercion nodes into the
189 # tree where needed to convert to and from Python objects.
190 # Allocate temporary locals for intermediate results. Fill
191 # in the 'result_code' attribute of each ExprNode with a C code
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
249 def dump_child(x, level):
250 if isinstance(x, Node):
251 return x.dump(level, filter_out, cutoff-1, encountered)
252 elif isinstance(x, list):
253 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
263 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264 for key, value in attrs:
265 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
266 res += "%s>" % indent
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
296 def generate_function_definitions(self, env, code):
297 env_old = env.directives
298 code_old = code.globalstate.directives
299 code.globalstate.directives = self.directives
300 self.body.generate_function_definitions(env, code)
301 env.directives = env_old
302 code.globalstate.directives = code_old
304 def generate_execution_code(self, code):
305 old = code.globalstate.directives
306 code.globalstate.directives = self.directives
307 self.body.generate_execution_code(code)
308 code.globalstate.directives = old
310 def annotate(self, code):
311 old = code.globalstate.directives
312 code.globalstate.directives = self.directives
313 self.body.annotate(code)
314 code.globalstate.directives = old
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
319 def generate_cached_builtins_decls(self, env, code):
320 entries = env.global_scope().undeclared_cached_builtins
321 for entry in entries:
322 code.globalstate.add_cached_builtin_decl(entry)
325 def generate_lambda_definitions(self, env, code):
326 for node in env.lambda_defs:
327 node.generate_function_definitions(env, code)
329 class StatListNode(Node):
330 # stats a list of StatNode
332 child_attrs = ["stats"]
334 def create_analysed(pos, env, *args, **kw):
335 node = StatListNode(pos, *args, **kw)
336 return node # No node-specific analysis necesarry
337 create_analysed = staticmethod(create_analysed)
339 def analyse_control_flow(self, env):
340 for stat in self.stats:
341 stat.analyse_control_flow(env)
343 def analyse_declarations(self, env):
344 #print "StatListNode.analyse_declarations" ###
345 for stat in self.stats:
346 stat.analyse_declarations(env)
348 def analyse_expressions(self, env):
349 #print "StatListNode.analyse_expressions" ###
350 for stat in self.stats:
351 stat.analyse_expressions(env)
353 def generate_function_definitions(self, env, code):
354 #print "StatListNode.generate_function_definitions" ###
355 for stat in self.stats:
356 stat.generate_function_definitions(env, code)
358 def generate_execution_code(self, code):
359 #print "StatListNode.generate_execution_code" ###
360 for stat in self.stats:
361 code.mark_pos(stat.pos)
362 stat.generate_execution_code(code)
364 def annotate(self, code):
365 for stat in self.stats:
369 class StatNode(Node):
371 # Code generation for statements is split into the following subphases:
373 # (1) generate_function_definitions
374 # Emit C code for the definitions of any structs,
375 # unions, enums and functions defined in the current
378 # (2) generate_execution_code
379 # Emit C code for executable statements.
382 def generate_function_definitions(self, env, code):
385 def generate_execution_code(self, code):
386 raise InternalError("generate_execution_code not implemented for %s" % \
387 self.__class__.__name__)
390 class CDefExternNode(StatNode):
391 # include_file string or None
394 child_attrs = ["body"]
396 def analyse_declarations(self, env):
397 if self.include_file:
398 env.add_include_file(self.include_file)
399 old_cinclude_flag = env.in_cinclude
401 self.body.analyse_declarations(env)
402 env.in_cinclude = old_cinclude_flag
404 def analyse_expressions(self, env):
407 def generate_execution_code(self, code):
410 def annotate(self, code):
411 self.body.annotate(code)
414 class CDeclaratorNode(Node):
415 # Part of a C declaration.
417 # Processing during analyse_declarations phase:
420 # Returns (name, type) pair where name is the
421 # CNameDeclaratorNode of the name being declared
422 # and type is the type it is being declared as.
424 # calling_convention string Calling convention of CFuncDeclaratorNode
425 # for which this is a base
429 calling_convention = ""
432 class CNameDeclaratorNode(CDeclaratorNode):
433 # name string The Pyrex name being declared
434 # cname string or None C name, if specified
435 # default ExprNode or None the value assigned on declaration
437 child_attrs = ['default']
441 def analyse(self, base_type, env, nonempty = 0):
442 if nonempty and self.name == '':
443 # May have mistaken the name for the type.
444 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
445 error(self.pos, "Missing argument name")
446 elif base_type.is_void:
447 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
449 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
450 base_type = py_object_type
451 self.type = base_type
452 return self, base_type
454 class CPtrDeclaratorNode(CDeclaratorNode):
455 # base CDeclaratorNode
457 child_attrs = ["base"]
459 def analyse(self, base_type, env, nonempty = 0):
460 if base_type.is_pyobject:
462 "Pointer base type cannot be a Python object")
463 ptr_type = PyrexTypes.c_ptr_type(base_type)
464 return self.base.analyse(ptr_type, env, nonempty = nonempty)
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Reference base type cannot be a Python object")
475 ref_type = PyrexTypes.c_ref_type(base_type)
476 return self.base.analyse(ref_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
485 if base_type.is_cpp_class:
486 from ExprNodes import TupleNode
487 if isinstance(self.dimension, TupleNode):
488 args = self.dimension.args
490 args = self.dimension,
491 values = [v.analyse_as_type(env) for v in args]
493 ix = values.index(None)
494 error(args[ix].pos, "Template parameter not a type.")
496 base_type = base_type.specialize_here(self.pos, values)
497 return self.base.analyse(base_type, env, nonempty = nonempty)
499 self.dimension.analyse_const_expression(env)
500 if not self.dimension.type.is_int:
501 error(self.dimension.pos, "Array dimension not integer")
502 size = self.dimension.get_constant_c_result_code()
511 if not base_type.is_complete():
513 "Array element type '%s' is incomplete" % base_type)
514 if base_type.is_pyobject:
516 "Array element cannot be a Python object")
517 if base_type.is_cfunction:
519 "Array element cannot be a function")
520 array_type = PyrexTypes.c_array_type(base_type, size)
521 return self.base.analyse(array_type, env, nonempty = nonempty)
524 class CFuncDeclaratorNode(CDeclaratorNode):
525 # base CDeclaratorNode
526 # args [CArgDeclNode]
527 # has_varargs boolean
528 # exception_value ConstNode
529 # exception_check boolean True if PyErr_Occurred check needed
530 # nogil boolean Can be called without gil
531 # with_gil boolean Acquire gil around function body
533 child_attrs = ["base", "args", "exception_value"]
536 optional_arg_count = 0
538 def analyse(self, return_type, env, nonempty = 0):
542 for i, arg_node in enumerate(self.args):
543 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544 is_self_arg = (i == 0 and env.is_c_class_scope))
545 name = name_declarator.name
546 if name_declarator.cname:
548 "Function argument cannot have C name specification")
549 # Turn *[] argument into **
551 type = PyrexTypes.c_ptr_type(type.base_type)
552 # Catch attempted C-style func(void) decl
554 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
555 func_type_args.append(
556 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
558 self.optional_arg_count += 1
559 elif self.optional_arg_count:
560 error(self.pos, "Non-default argument follows default argument")
562 if self.optional_arg_count:
563 scope = StructOrUnionScope()
564 arg_count_member = '%sn' % Naming.pyrex_prefix
565 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
566 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
567 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
568 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
569 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
574 cname = struct_cname)
575 self.op_args_struct.defined_in_pxd = 1
576 self.op_args_struct.used = 1
580 if self.exception_check == '+':
581 env.add_include_file('stdexcept')
582 if return_type.is_pyobject \
583 and (self.exception_value or self.exception_check) \
584 and self.exception_check != '+':
586 "Exception clause not allowed for function returning Python object")
588 if self.exception_value:
589 self.exception_value.analyse_const_expression(env)
590 if self.exception_check == '+':
591 self.exception_value.analyse_types(env)
592 exc_val_type = self.exception_value.type
593 if not exc_val_type.is_error and \
594 not exc_val_type.is_pyobject and \
595 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
596 error(self.exception_value.pos,
597 "Exception value must be a Python exception or cdef function with no arguments.")
598 exc_val = self.exception_value
600 self.exception_value = self.exception_value.coerce_to(return_type, env)
601 if self.exception_value.analyse_const_expression(env):
602 exc_val = self.exception_value.get_constant_c_result_code()
604 raise InternalError("get_constant_c_result_code not implemented for %s" %
605 self.exception_value.__class__.__name__)
606 if not return_type.assignable_from(self.exception_value.type):
607 error(self.exception_value.pos,
608 "Exception value incompatible with function return type")
609 exc_check = self.exception_check
610 if return_type.is_array:
612 "Function cannot return an array")
613 if return_type.is_cfunction:
615 "Function cannot return a function")
616 func_type = PyrexTypes.CFuncType(
617 return_type, func_type_args, self.has_varargs,
618 optional_arg_count = self.optional_arg_count,
619 exception_value = exc_val, exception_check = exc_check,
620 calling_convention = self.base.calling_convention,
621 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
622 if self.optional_arg_count:
623 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
624 callspec = env.directives['callspec']
626 current = func_type.calling_convention
627 if current and current != callspec:
628 error(self.pos, "cannot have both '%s' and '%s' "
629 "calling conventions" % (current, callspec))
630 func_type.calling_convention = callspec
631 return self.base.analyse(func_type, env)
634 class CArgDeclNode(Node):
635 # Item in a function declaration argument list.
637 # base_type CBaseTypeNode
638 # declarator CDeclaratorNode
639 # not_none boolean Tagged with 'not None'
640 # or_none boolean Tagged with 'or None'
641 # accept_none boolean Resolved boolean for not_none/or_none
642 # default ExprNode or None
643 # default_value PyObjectConst constant for default value
644 # annotation ExprNode or None Py3 function arg annotation
645 # is_self_arg boolean Is the "self" arg of an extension type method
646 # is_type_arg boolean Is the "class" arg of an extension type classmethod
647 # is_kw_only boolean Is a keyword-only argument
649 child_attrs = ["base_type", "declarator", "default"]
655 name_declarator = None
659 def analyse(self, env, nonempty = 0, is_self_arg = False):
661 self.base_type.is_self_arg = self.is_self_arg = True
662 if self.type is None:
663 # The parser may missinterpret names as types...
665 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
667 self.declarator.name = self.base_type.name
668 self.base_type.name = None
669 self.base_type.is_basic_c_type = False
672 could_be_name = False
673 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
674 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
675 self.declarator.name = self.base_type.arg_name
676 # The parser is unable to resolve the ambiguity of [] as part of the
677 # type (e.g. in buffers) or empty declarator (as with arrays).
678 # This is only arises for empty multi-dimensional arrays.
679 if (base_type.is_array
680 and isinstance(self.base_type, TemplatedTypeNode)
681 and isinstance(self.declarator, CArrayDeclaratorNode)):
682 declarator = self.declarator
683 while isinstance(declarator.base, CArrayDeclaratorNode):
684 declarator = declarator.base
685 declarator.base = self.base_type.array_declarator
686 base_type = base_type.base_type
687 return self.declarator.analyse(base_type, env, nonempty = nonempty)
689 return self.name_declarator, self.type
691 def calculate_default_value_code(self, code):
692 if self.default_value is None:
694 if self.default.is_literal:
695 # will not output any code, just assign the result_code
696 self.default.generate_evaluation_code(code)
697 return self.type.cast_code(self.default.result())
698 self.default_value = code.get_argument_default_const(self.type)
699 return self.default_value
701 def annotate(self, code):
703 self.default.annotate(code)
706 class CBaseTypeNode(Node):
707 # Abstract base class for C base type nodes.
709 # Processing during analyse_declarations phase:
716 def analyse_as_type(self, env):
717 return self.analyse(env)
719 class CAnalysedBaseTypeNode(Node):
724 def analyse(self, env, could_be_name = False):
727 class CSimpleBaseTypeNode(CBaseTypeNode):
729 # module_path [string] Qualifying name components
730 # is_basic_c_type boolean
734 # is_self_arg boolean Is self argument of C method
735 # ##is_type_arg boolean Is type argument of class method
738 arg_name = None # in case the argument name was interpreted as a type
740 def analyse(self, env, could_be_name = False):
741 # Return type descriptor.
742 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
744 if self.is_basic_c_type:
745 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
747 error(self.pos, "Unrecognised type modifier combination")
748 elif self.name == "object" and not self.module_path:
749 type = py_object_type
750 elif self.name is None:
751 if self.is_self_arg and env.is_c_class_scope:
752 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
753 type = env.parent_type
754 ## elif self.is_type_arg and env.is_c_class_scope:
755 ## type = Builtin.type_type
757 type = py_object_type
760 scope = env.find_imported_module(self.module_path, self.pos)
764 if scope.is_c_class_scope:
765 scope = scope.global_scope()
766 entry = scope.lookup(self.name)
767 if entry and entry.is_type:
770 if self.is_self_arg and env.is_c_class_scope:
771 type = env.parent_type
772 ## elif self.is_type_arg and env.is_c_class_scope:
773 ## type = Builtin.type_type
775 type = py_object_type
776 self.arg_name = self.name
779 if not self.name in self.templates:
780 error(self.pos, "'%s' is not a type identifier" % self.name)
781 type = PyrexTypes.TemplatePlaceholderType(self.name)
783 error(self.pos, "'%s' is not a type identifier" % self.name)
785 if not type.is_numeric or type.is_complex:
786 error(self.pos, "can only complexify c numeric types")
787 type = PyrexTypes.CComplexType(type)
788 type.create_declaration_utility_code(env)
789 elif type is Builtin.complex_type:
790 # Special case: optimise builtin complex type into C's
791 # double complex. The parser cannot do this (as for the
792 # normal scalar types) as the user may have redeclared the
793 # 'complex' type. Testing for the exact type here works.
794 type = PyrexTypes.c_double_complex_type
795 type.create_declaration_utility_code(env)
800 return PyrexTypes.error_type
802 class CNestedBaseTypeNode(CBaseTypeNode):
803 # For C++ classes that live inside other C++ classes.
806 # base_type CBaseTypeNode
808 child_attrs = ['base_type']
810 def analyse(self, env, could_be_name = None):
811 base_type = self.base_type.analyse(env)
812 if base_type is PyrexTypes.error_type:
813 return PyrexTypes.error_type
814 if not base_type.is_cpp_class:
815 error(self.pos, "'%s' is not a valid type scope" % base_type)
816 return PyrexTypes.error_type
817 type_entry = base_type.scope.lookup_here(self.name)
818 if not type_entry or not type_entry.is_type:
819 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
820 return PyrexTypes.error_type
821 return type_entry.type
823 class TemplatedTypeNode(CBaseTypeNode):
825 # positional_args [ExprNode] List of positional arguments
826 # keyword_args DictNode Keyword arguments
827 # base_type_node CBaseTypeNode
830 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
833 child_attrs = ["base_type_node", "positional_args",
834 "keyword_args", "dtype_node"]
840 def analyse(self, env, could_be_name = False, base_type = None):
841 if base_type is None:
842 base_type = self.base_type_node.analyse(env)
843 if base_type.is_error: return base_type
845 if base_type.is_cpp_class:
847 if self.keyword_args and self.keyword_args.key_value_pairs:
848 error(self.pos, "c++ templates cannot take keyword arguments");
849 self.type = PyrexTypes.error_type
852 for template_node in self.positional_args:
853 type = template_node.analyse_as_type(env)
855 error(template_node.pos, "unknown type in template argument")
857 template_types.append(type)
858 self.type = base_type.specialize_here(self.pos, template_types)
860 elif base_type.is_pyobject:
864 options = Buffer.analyse_buffer_options(
867 self.positional_args,
869 base_type.buffer_defaults)
871 if sys.version_info[0] < 3:
872 # Py 2.x enforces byte strings as keyword arguments ...
873 options = dict([ (name.encode('ASCII'), value)
874 for name, value in options.items() ])
876 self.type = PyrexTypes.BufferType(base_type, **options)
880 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
881 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
882 error(self.pos, "invalid array declaration")
883 self.type = PyrexTypes.error_type
885 # It would be nice to merge this class with CArrayDeclaratorNode,
886 # but arrays are part of the declaration, not the type...
887 if not self.positional_args:
890 dimension = self.positional_args[0]
891 self.array_declarator = CArrayDeclaratorNode(self.pos,
892 base = empty_declarator,
893 dimension = dimension)
894 self.type = self.array_declarator.analyse(base_type, env)[1]
898 class CComplexBaseTypeNode(CBaseTypeNode):
899 # base_type CBaseTypeNode
900 # declarator CDeclaratorNode
902 child_attrs = ["base_type", "declarator"]
904 def analyse(self, env, could_be_name = False):
905 base = self.base_type.analyse(env, could_be_name)
906 _, type = self.declarator.analyse(base, env)
910 class CVarDefNode(StatNode):
911 # C variable definition or forward/extern function declaration.
913 # visibility 'private' or 'public' or 'extern'
914 # base_type CBaseTypeNode
915 # declarators [CDeclaratorNode]
919 # decorators [cython.locals(...)] or None
920 # directive_locals { string : NameNode } locals defined by cython.locals(...)
922 child_attrs = ["base_type", "declarators"]
925 directive_locals = {}
927 def analyse_declarations(self, env, dest_scope = None):
930 self.dest_scope = dest_scope
931 base_type = self.base_type.analyse(env)
933 # If the field is an external typedef, we cannot be sure about the type,
934 # so do conversion ourself rather than rely on the CPython mechanism (through
935 # a property; made in AnalyseDeclarationsTransform).
936 if (dest_scope.is_c_class_scope
937 and self.visibility in ('public', 'readonly')):
940 need_property = False
941 visibility = self.visibility
943 for declarator in self.declarators:
944 name_declarator, type = declarator.analyse(base_type, env)
945 if not type.is_complete():
946 if not (self.visibility == 'extern' and type.is_array):
947 error(declarator.pos,
948 "Variable type '%s' is incomplete" % type)
949 if self.visibility == 'extern' and type.is_pyobject:
950 error(declarator.pos,
951 "Python object cannot be declared extern")
952 name = name_declarator.name
953 cname = name_declarator.cname
955 error(declarator.pos, "Missing name in declaration.")
957 if type.is_cfunction:
958 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
959 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
961 if entry is not None:
962 entry.directive_locals = self.directive_locals
964 if self.directive_locals:
965 error(self.pos, "Decorators can only be followed by functions")
966 if self.in_pxd and self.visibility != 'extern':
968 "Only 'extern' C variable declaration allowed in .pxd file")
969 entry = dest_scope.declare_var(name, type, declarator.pos,
970 cname = cname, visibility = visibility, is_cdef = 1)
971 entry.needs_property = need_property
974 class CStructOrUnionDefNode(StatNode):
976 # cname string or None
977 # kind "struct" or "union"
978 # typedef_flag boolean
979 # visibility "public" or "private"
981 # attributes [CVarDefNode] or None
985 child_attrs = ["attributes"]
987 def analyse_declarations(self, env):
989 if self.visibility == 'extern' and self.packed:
990 error(self.pos, "Cannot declare extern struct as 'packed'")
991 if self.attributes is not None:
992 scope = StructOrUnionScope(self.name)
993 self.entry = env.declare_struct_or_union(
994 self.name, self.kind, scope, self.typedef_flag, self.pos,
995 self.cname, visibility = self.visibility, packed = self.packed)
996 if self.attributes is not None:
997 if self.in_pxd and not env.in_cinclude:
998 self.entry.defined_in_pxd = 1
999 for attr in self.attributes:
1000 attr.analyse_declarations(env, scope)
1001 if self.visibility != 'extern':
1002 need_typedef_indirection = False
1003 for attr in scope.var_entries:
1005 while type.is_array:
1006 type = type.base_type
1007 if type == self.entry.type:
1008 error(attr.pos, "Struct cannot contain itself as a member.")
1009 if self.typedef_flag:
1011 type = type.base_type
1012 if type == self.entry.type:
1013 need_typedef_indirection = True
1014 if need_typedef_indirection:
1015 # C can't handle typedef structs that refer to themselves.
1016 struct_entry = self.entry
1017 self.entry = env.declare_typedef(
1018 self.name, struct_entry.type, self.pos,
1019 cname = self.cname, visibility='ignore')
1020 struct_entry.type.typedef_flag = False
1021 # FIXME: this might be considered a hack ;-)
1022 struct_entry.cname = struct_entry.type.cname = \
1023 '_' + self.entry.type.typedef_cname
1025 def analyse_expressions(self, env):
1028 def generate_execution_code(self, code):
1032 class CppClassNode(CStructOrUnionDefNode):
1035 # cname string or None
1036 # visibility "extern"
1038 # attributes [CVarDefNode] or None
1040 # base_classes [string]
1041 # templates [string] or None
1043 def analyse_declarations(self, env):
1045 if self.attributes is not None:
1046 scope = CppClassScope(self.name, env)
1047 base_class_types = []
1048 for base_class_name in self.base_classes:
1049 base_class_entry = env.lookup(base_class_name)
1050 if base_class_entry is None:
1051 error(self.pos, "'%s' not found" % base_class_name)
1052 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1053 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1055 base_class_types.append(base_class_entry.type)
1056 if self.templates is None:
1057 template_types = None
1059 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1060 self.entry = env.declare_cpp_class(
1061 self.name, scope, self.pos,
1062 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1063 self.entry.is_cpp_class = 1
1064 if self.attributes is not None:
1065 if self.in_pxd and not env.in_cinclude:
1066 self.entry.defined_in_pxd = 1
1067 for attr in self.attributes:
1068 attr.analyse_declarations(scope)
1070 class CEnumDefNode(StatNode):
1071 # name string or None
1072 # cname string or None
1073 # items [CEnumDefItemNode]
1074 # typedef_flag boolean
1075 # visibility "public" or "private"
1079 child_attrs = ["items"]
1081 def analyse_declarations(self, env):
1082 self.entry = env.declare_enum(self.name, self.pos,
1083 cname = self.cname, typedef_flag = self.typedef_flag,
1084 visibility = self.visibility)
1085 if self.items is not None:
1086 if self.in_pxd and not env.in_cinclude:
1087 self.entry.defined_in_pxd = 1
1088 for item in self.items:
1089 item.analyse_declarations(env, self.entry)
1091 def analyse_expressions(self, env):
1094 def generate_execution_code(self, code):
1095 if self.visibility == 'public':
1096 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1097 for item in self.entry.enum_values:
1098 code.putln("%s = PyInt_FromLong(%s); %s" % (
1101 code.error_goto_if_null(temp, item.pos)))
1102 code.put_gotref(temp)
1103 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1104 Naming.module_cname,
1107 code.error_goto(item.pos)))
1108 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1109 code.funcstate.release_temp(temp)
1112 class CEnumDefItemNode(StatNode):
1114 # cname string or None
1115 # value ExprNode or None
1117 child_attrs = ["value"]
1119 def analyse_declarations(self, env, enum_entry):
1121 self.value.analyse_const_expression(env)
1122 if not self.value.type.is_int:
1123 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1124 self.value.analyse_const_expression(env)
1125 entry = env.declare_const(self.name, enum_entry.type,
1126 self.value, self.pos, cname = self.cname,
1127 visibility = enum_entry.visibility)
1128 enum_entry.enum_values.append(entry)
1131 class CTypeDefNode(StatNode):
1132 # base_type CBaseTypeNode
1133 # declarator CDeclaratorNode
1134 # visibility "public" or "private"
1137 child_attrs = ["base_type", "declarator"]
1139 def analyse_declarations(self, env):
1140 base = self.base_type.analyse(env)
1141 name_declarator, type = self.declarator.analyse(base, env)
1142 name = name_declarator.name
1143 cname = name_declarator.cname
1144 entry = env.declare_typedef(name, type, self.pos,
1145 cname = cname, visibility = self.visibility)
1146 if self.in_pxd and not env.in_cinclude:
1147 entry.defined_in_pxd = 1
1149 def analyse_expressions(self, env):
1151 def generate_execution_code(self, code):
1155 class FuncDefNode(StatNode, BlockNode):
1156 # Base class for function definition nodes.
1158 # return_type PyrexType
1159 # #filename string C name of filename string const
1160 # entry Symtab.Entry
1161 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1162 # needs_outer_scope boolean Whether or not this function requires outer scope
1163 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1167 needs_closure = False
1168 needs_outer_scope = False
1169 is_generator = False
1172 def analyse_default_values(self, env):
1173 genv = env.global_scope()
1175 for arg in self.args:
1179 arg.default.analyse_types(env)
1180 arg.default = arg.default.coerce_to(arg.type, genv)
1183 "This argument cannot have a default value")
1188 error(arg.pos, "Non-default argument following default argument")
1190 def need_gil_acquisition(self, lenv):
1193 def create_local_scope(self, env):
1195 while genv.is_py_class_scope or genv.is_c_class_scope:
1196 genv = genv.outer_scope
1197 if self.needs_closure:
1198 lenv = ClosureScope(name=self.entry.name,
1200 scope_name=self.entry.cname)
1202 lenv = LocalScope(name=self.entry.name,
1205 lenv.return_type = self.return_type
1206 type = self.entry.type
1207 if type.is_cfunction:
1208 lenv.nogil = type.nogil and not type.with_gil
1209 self.local_scope = lenv
1210 lenv.directives = env.directives
1213 def generate_function_definitions(self, env, code):
1216 lenv = self.local_scope
1217 if lenv.is_closure_scope and not lenv.is_passthrough:
1218 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1219 Naming.outer_scope_cname)
1221 outer_scope_cname = Naming.outer_scope_cname
1222 lenv.mangle_closure_cnames(outer_scope_cname)
1223 # Generate closure function definitions
1224 self.body.generate_function_definitions(lenv, code)
1225 # generate lambda function definitions
1226 self.generate_lambda_definitions(lenv, code)
1228 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1229 self.entry.scope.is_c_class_scope)
1230 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1231 self.entry.scope.is_c_class_scope)
1232 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1234 if 'cython_unused' not in self.modifiers:
1235 self.modifiers = self.modifiers + ['cython_unused']
1237 preprocessor_guard = None
1238 if self.entry.is_special and not is_buffer_slot:
1239 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1241 preprocessor_guard = slot.preprocessor_guard_code()
1242 if (self.entry.name == '__long__' and
1243 not self.entry.scope.lookup_here('__int__')):
1244 preprocessor_guard = None
1246 profile = code.globalstate.directives['profile']
1249 error(self.pos, "Cannot profile nogil function.")
1250 code.globalstate.use_utility_code(profile_utility_code)
1252 # Generate C code for header and body of function
1253 code.enter_cfunc_scope()
1254 code.return_from_error_cleanup_label = code.new_label()
1256 # ----- Top-level constants used by this function
1257 code.mark_pos(self.pos)
1258 self.generate_cached_builtins_decls(lenv, code)
1259 # ----- Function header
1262 if preprocessor_guard:
1263 code.putln(preprocessor_guard)
1265 with_pymethdef = self.needs_assignment_synthesis(env, code)
1267 self.py_func.generate_function_header(code,
1268 with_pymethdef = with_pymethdef,
1270 self.generate_function_header(code,
1271 with_pymethdef = with_pymethdef)
1272 # ----- Local variable declarations
1273 # Find function scope
1275 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1276 cenv = cenv.outer_scope
1277 if self.needs_closure:
1278 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1280 elif self.needs_outer_scope:
1281 if lenv.is_passthrough:
1282 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1284 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1286 self.generate_argument_declarations(lenv, code)
1287 for entry in lenv.var_entries:
1288 if not entry.in_closure:
1289 code.put_var_declaration(entry)
1291 if not self.return_type.is_void:
1292 if self.return_type.is_pyobject:
1296 (self.return_type.declaration_code(Naming.retval_cname),
1298 tempvardecl_code = code.insertion_point()
1299 code.put_declare_refcount_context()
1300 if not self.is_generator:
1301 self.generate_keyword_list(code)
1303 code.put_trace_declarations()
1304 # ----- Extern library function declarations
1305 lenv.generate_library_function_declarations(code)
1306 # ----- GIL acquisition
1307 acquire_gil = self.acquire_gil
1309 env.use_utility_code(force_init_threads_utility_code)
1310 code.putln("#ifdef WITH_THREAD")
1311 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1312 code.putln("#endif")
1313 # ----- set up refnanny
1315 code.put_setup_refcount_context(self.entry.name)
1316 # ----- Automatic lead-ins for certain special functions
1317 if is_getbuffer_slot:
1318 self.getbuffer_init(code)
1319 # ----- Create closure scope object
1320 if self.is_generator:
1321 code.putln("%s = (%s) %s;" % (
1322 Naming.cur_scope_cname,
1323 lenv.scope_class.type.declaration_code(''),
1325 gotref_code = code.insertion_point()
1327 elif self.needs_closure:
1328 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1329 Naming.cur_scope_cname,
1330 lenv.scope_class.type.declaration_code(''),
1331 lenv.scope_class.type.typeptr_cname,
1332 lenv.scope_class.type.typeptr_cname,
1333 Naming.empty_tuple))
1334 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1335 if is_getbuffer_slot:
1336 self.getbuffer_error_cleanup(code)
1338 code.put_finish_refcount_context()
1339 # FIXME: what if the error return value is a Python value?
1340 code.putln("return %s;" % self.error_value())
1342 code.put_gotref(Naming.cur_scope_cname)
1343 # Note that it is unsafe to decref the scope at this point.
1344 if self.needs_outer_scope and not self.is_generator:
1345 code.putln("%s = (%s)%s;" % (
1347 cenv.scope_class.type.declaration_code(''),
1349 if lenv.is_passthrough:
1350 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1351 elif self.needs_closure:
1352 # inner closures own a reference to their outer parent
1353 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1354 code.put_giveref(outer_scope_cname)
1355 # ----- Trace function call
1357 # this looks a bit late, but if we don't get here due to a
1358 # fatal error before hand, it's not really worth tracing
1359 code.put_trace_call(self.entry.name, self.pos)
1360 # ----- Fetch arguments
1361 if not self.is_generator:
1362 self.generate_preamble(env, code)
1363 if self.is_generator:
1364 code.funcstate.init_closure_temps(lenv.scope_class.type.scope)
1365 resume_code = code.insertion_point()
1366 first_run_label = code.new_label('first_run')
1367 code.use_label(first_run_label)
1368 code.put_label(first_run_label)
1370 (code.error_goto_if_null(Naming.sent_value_cname, self.pos)))
1371 # -------------------------
1372 # ----- Function body -----
1373 # -------------------------
1374 self.body.generate_execution_code(code)
1376 if self.is_generator:
1377 code.putln('PyErr_SetNone(PyExc_StopIteration); %s' % code.error_goto(self.pos))
1379 # ----- Default return value
1381 if self.return_type.is_pyobject:
1382 #if self.return_type.is_extension_type:
1383 # lhs = "(PyObject *)%s" % Naming.retval_cname
1385 lhs = Naming.retval_cname
1386 code.put_init_to_py_none(lhs, self.return_type)
1388 val = self.return_type.default_value
1390 code.putln("%s = %s;" % (Naming.retval_cname, val))
1391 # ----- Error cleanup
1392 if code.error_label in code.labels_used:
1393 code.put_goto(code.return_label)
1394 code.put_label(code.error_label)
1395 for cname, type in code.funcstate.all_managed_temps():
1396 code.put_xdecref(cname, type)
1398 # Clean up buffers -- this calls a Python function
1399 # so need to save and restore error state
1400 buffers_present = len(lenv.buffer_entries) > 0
1402 code.globalstate.use_utility_code(restore_exception_utility_code)
1403 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1404 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1405 for entry in lenv.buffer_entries:
1406 Buffer.put_release_buffer_code(code, entry)
1407 #code.putln("%s = 0;" % entry.cname)
1408 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1410 err_val = self.error_value()
1411 exc_check = self.caller_will_check_exceptions()
1412 if err_val is not None or exc_check:
1413 # TODO: Fix exception tracing (though currently unused by cProfile).
1414 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1415 # code.put_trace_exception()
1416 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1418 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1419 % self.entry.qualified_name, 0)
1421 '__Pyx_WriteUnraisable("%s");' %
1422 self.entry.qualified_name)
1423 env.use_utility_code(unraisable_exception_utility_code)
1424 env.use_utility_code(restore_exception_utility_code)
1425 default_retval = self.return_type.default_value
1426 if err_val is None and default_retval:
1427 err_val = default_retval
1428 if err_val is not None:
1429 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1431 if is_getbuffer_slot:
1432 self.getbuffer_error_cleanup(code)
1434 # If we are using the non-error cleanup section we should
1435 # jump past it if we have an error. The if-test below determine
1436 # whether this section is used.
1437 if buffers_present or is_getbuffer_slot:
1438 code.put_goto(code.return_from_error_cleanup_label)
1441 # ----- Non-error return cleanup
1442 code.put_label(code.return_label)
1443 for entry in lenv.buffer_entries:
1445 Buffer.put_release_buffer_code(code, entry)
1446 if is_getbuffer_slot:
1447 self.getbuffer_normal_cleanup(code)
1448 # ----- Return cleanup for both error and no-error return
1449 code.put_label(code.return_from_error_cleanup_label)
1450 if not Options.init_local_none:
1451 for entry in lenv.var_entries:
1452 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1453 entry.xdecref_cleanup = 1
1455 for entry in lenv.var_entries:
1456 if entry.type.is_pyobject:
1457 if entry.used and not entry.in_closure:
1458 code.put_var_decref(entry)
1459 # Decref any increfed args
1460 for entry in lenv.arg_entries:
1461 if entry.type.is_pyobject:
1462 if (acquire_gil or entry.assignments) and not entry.in_closure:
1463 code.put_var_decref(entry)
1464 if self.needs_closure and not self.is_generator:
1465 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1466 if self.is_generator:
1467 code.putln('%s->%s.resume_label = -1;' % (Naming.cur_scope_cname, Naming.obj_base_cname))
1470 # This code is duplicated in ModuleNode.generate_module_init_func
1472 default_retval = self.return_type.default_value
1473 err_val = self.error_value()
1474 if err_val is None and default_retval:
1475 err_val = default_retval
1476 if self.return_type.is_pyobject:
1477 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1479 if self.entry.is_special and self.entry.name == "__hash__":
1480 # Returning -1 for __hash__ is supposed to signal an error
1481 # We do as Python instances and coerce -1 into -2.
1482 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1483 Naming.retval_cname, Naming.retval_cname))
1486 if self.return_type.is_pyobject:
1487 code.put_trace_return(Naming.retval_cname)
1489 code.put_trace_return("Py_None")
1491 code.put_finish_refcount_context()
1494 code.putln("#ifdef WITH_THREAD")
1495 code.putln("PyGILState_Release(_save);")
1496 code.putln("#endif")
1498 if not self.return_type.is_void:
1499 code.putln("return %s;" % Naming.retval_cname)
1503 if preprocessor_guard:
1504 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1505 # ----- Go back and insert temp variable declarations
1506 tempvardecl_code.put_temp_declarations(code.funcstate)
1507 # ----- Generator resume code
1508 if self.is_generator:
1509 resume_code.putln("switch (%s->%s.resume_label) {" % (Naming.cur_scope_cname, Naming.obj_base_cname));
1510 resume_code.putln("case 0: goto %s;" % first_run_label)
1511 for yield_expr in self.yields:
1512 resume_code.putln("case %d: goto %s;" % (yield_expr.label_num, yield_expr.label_name));
1513 resume_code.putln("default: /* CPython raises the right error here */");
1514 resume_code.putln("return NULL;");
1515 resume_code.putln("}");
1516 # ----- Python version
1517 code.exit_cfunc_scope()
1519 self.py_func.generate_function_definitions(env, code)
1520 self.generate_wrapper_functions(code)
1522 if self.is_generator:
1523 self.generator.generate_function_body(self.local_scope, code)
1525 def generate_preamble(self, env, code):
1526 """Parse arguments and prepare scope"""
1529 lenv = self.local_scope
1530 acquire_gil = self.acquire_gil
1532 self.generate_argument_parsing_code(env, code)
1533 # If an argument is assigned to in the body, we must
1534 # incref it to properly keep track of refcounts.
1535 for entry in lenv.arg_entries:
1536 if entry.type.is_pyobject:
1537 if (acquire_gil or entry.assignments) and not entry.in_closure:
1538 code.put_var_incref(entry)
1539 # ----- Initialise local variables
1540 for entry in lenv.var_entries:
1541 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1542 code.put_init_var_to_py_none(entry)
1543 # ----- Initialise local buffer auxiliary variables
1544 for entry in lenv.var_entries + lenv.arg_entries:
1545 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1546 code.putln("%s.buf = NULL;" %
1547 entry.buffer_aux.buffer_info_var.cname)
1548 # ----- Check and convert arguments
1549 self.generate_argument_type_tests(code)
1550 # ----- Acquire buffer arguments
1551 for entry in lenv.arg_entries:
1552 if entry.type.is_buffer:
1553 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1555 def declare_argument(self, env, arg):
1556 if arg.type.is_void:
1557 error(arg.pos, "Invalid use of 'void'")
1558 elif not arg.type.is_complete() and not arg.type.is_array:
1560 "Argument type '%s' is incomplete" % arg.type)
1561 return env.declare_arg(arg.name, arg.type, arg.pos)
1563 def generate_arg_type_test(self, arg, code):
1564 # Generate type test for one argument.
1565 if arg.type.typeobj_is_available():
1566 code.globalstate.use_utility_code(arg_type_test_utility_code)
1567 typeptr_cname = arg.type.typeptr_cname
1568 arg_code = "((PyObject *)%s)" % arg.entry.cname
1570 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1575 arg.type.is_builtin_type,
1576 code.error_goto(arg.pos)))
1578 error(arg.pos, "Cannot test type of extern C class "
1579 "without type object name specification")
1581 def generate_arg_none_check(self, arg, code):
1582 # Generate None check for one argument.
1583 code.globalstate.use_utility_code(arg_type_test_utility_code)
1584 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1585 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1587 code.error_goto(arg.pos)))
1590 def generate_wrapper_functions(self, code):
1593 def generate_execution_code(self, code):
1594 # Evaluate and store argument default values
1595 for arg in self.args:
1596 default = arg.default
1598 if not default.is_literal:
1599 default.generate_evaluation_code(code)
1600 default.make_owned_reference(code)
1601 result = default.result_as(arg.type)
1604 arg.calculate_default_value_code(code),
1606 if arg.type.is_pyobject:
1607 code.put_giveref(default.result())
1608 default.generate_post_assignment_code(code)
1609 default.free_temps(code)
1610 # For Python class methods, create and store function object
1612 self.assmt.generate_execution_code(code)
1615 # Special code for the __getbuffer__ function
1617 def getbuffer_init(self, code):
1618 info = self.local_scope.arg_entries[1].cname
1619 # Python 3.0 betas have a bug in memoryview which makes it call
1620 # getbuffer with a NULL parameter. For now we work around this;
1621 # the following line should be removed when this bug is fixed.
1622 code.putln("if (%s == NULL) return 0;" % info)
1623 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1624 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1626 def getbuffer_error_cleanup(self, code):
1627 info = self.local_scope.arg_entries[1].cname
1628 code.put_gotref("%s->obj" % info)
1629 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1632 def getbuffer_normal_cleanup(self, code):
1633 info = self.local_scope.arg_entries[1].cname
1634 code.putln("if (%s->obj == Py_None) {" % info)
1635 code.put_gotref("Py_None")
1636 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1639 class CFuncDefNode(FuncDefNode):
1640 # C function definition.
1642 # modifiers ['inline']
1643 # visibility 'private' or 'public' or 'extern'
1644 # base_type CBaseTypeNode
1645 # declarator CDeclaratorNode
1648 # decorators [DecoratorNode] list of decorators
1650 # with_gil boolean Acquire GIL around body
1652 # py_func wrapper for calling from Python
1653 # overridable whether or not this is a cpdef function
1654 # inline_in_pxd whether this is an inline function in a pxd file
1656 child_attrs = ["base_type", "declarator", "body", "py_func"]
1658 inline_in_pxd = False
1660 directive_locals = {}
1662 def unqualified_name(self):
1663 return self.entry.name
1665 def analyse_declarations(self, env):
1666 self.directive_locals.update(env.directives['locals'])
1667 base_type = self.base_type.analyse(env)
1668 # The 2 here is because we need both function and argument names.
1669 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1670 if not type.is_cfunction:
1672 "Suite attached to non-function declaration")
1673 # Remember the actual type according to the function header
1674 # written here, because the type in the symbol table entry
1675 # may be different if we're overriding a C method inherited
1676 # from the base type of an extension type.
1678 type.is_overridable = self.overridable
1679 declarator = self.declarator
1680 while not hasattr(declarator, 'args'):
1681 declarator = declarator.base
1682 self.args = declarator.args
1683 for formal_arg, type_arg in zip(self.args, type.args):
1684 formal_arg.type = type_arg.type
1685 formal_arg.name = type_arg.name
1686 formal_arg.cname = type_arg.cname
1687 name = name_declarator.name
1688 cname = name_declarator.cname
1689 self.entry = env.declare_cfunction(
1690 name, type, self.pos,
1691 cname = cname, visibility = self.visibility,
1692 defining = self.body is not None,
1693 api = self.api, modifiers = self.modifiers)
1694 self.entry.inline_func_in_pxd = self.inline_in_pxd
1695 self.return_type = type.return_type
1697 if self.overridable and not env.is_module_scope:
1698 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1699 # An error will be produced in the cdef function
1700 self.overridable = False
1702 if self.overridable:
1704 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1705 self.py_func = DefNode(pos = self.pos,
1706 name = self.entry.name,
1709 starstar_arg = None,
1711 body = py_func_body,
1713 self.py_func.is_module_scope = env.is_module_scope
1714 self.py_func.analyse_declarations(env)
1715 self.entry.as_variable = self.py_func.entry
1716 # Reset scope entry the above cfunction
1717 env.entries[name] = self.entry
1718 if not env.is_module_scope or Options.lookup_module_cpdef:
1719 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1720 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1721 self.create_local_scope(env)
1723 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1725 args = self.type.args
1726 if omit_optional_args:
1727 args = args[:len(args) - self.type.optional_arg_count]
1728 arg_names = [arg.name for arg in args]
1730 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1732 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1733 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1734 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1735 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)
1736 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1738 def declare_arguments(self, env):
1739 for arg in self.type.args:
1741 error(arg.pos, "Missing argument name")
1742 self.declare_argument(env, arg)
1744 def need_gil_acquisition(self, lenv):
1745 return self.type.with_gil
1747 def nogil_check(self, env):
1749 with_gil = type.with_gil
1750 if type.nogil and not with_gil:
1751 if type.return_type.is_pyobject:
1753 "Function with Python return type cannot be declared nogil")
1754 for entry in self.local_scope.var_entries:
1755 if entry.type.is_pyobject:
1756 error(self.pos, "Function declared nogil has Python locals or temporaries")
1758 def analyse_expressions(self, env):
1759 self.local_scope.directives = env.directives
1760 if self.py_func is not None:
1761 # this will also analyse the default values
1762 self.py_func.analyse_expressions(env)
1764 self.analyse_default_values(env)
1765 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1767 def needs_assignment_synthesis(self, env, code=None):
1770 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1773 visibility = self.entry.visibility
1774 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1775 arg_decls.append(arg.declaration_code())
1776 if with_dispatch and self.overridable:
1777 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1778 if type.optional_arg_count and with_opt_args:
1779 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1780 if type.has_varargs:
1781 arg_decls.append("...")
1783 arg_decls = ["void"]
1785 cname = self.entry.func_cname
1786 entity = type.function_header_code(cname, ', '.join(arg_decls))
1787 if visibility == 'public':
1788 dll_linkage = "DL_EXPORT"
1791 header = self.return_type.declaration_code(entity,
1792 dll_linkage = dll_linkage)
1793 if visibility == 'extern':
1794 storage_class = "%s " % Naming.extern_c_macro
1795 elif visibility == 'public':
1798 storage_class = "static "
1799 if 'inline' in self.modifiers:
1800 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1801 code.putln("%s%s %s {" % (
1803 ' '.join(self.modifiers).upper(), # macro forms
1806 def generate_argument_declarations(self, env, code):
1807 for arg in self.args:
1809 result = arg.calculate_default_value_code(code)
1810 code.putln('%s = %s;' % (
1811 arg.type.declaration_code(arg.cname), result))
1813 def generate_keyword_list(self, code):
1816 def generate_argument_parsing_code(self, env, code):
1818 if self.type.optional_arg_count:
1819 code.putln('if (%s) {' % Naming.optional_args_cname)
1820 for arg in self.args:
1822 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1823 declarator = arg.declarator
1824 while not hasattr(declarator, 'name'):
1825 declarator = declarator.base
1826 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1828 for _ in range(self.type.optional_arg_count):
1832 def generate_argument_conversion_code(self, code):
1835 def generate_argument_type_tests(self, code):
1836 # Generate type tests for args whose type in a parent
1837 # class is a supertype of the declared type.
1838 for arg in self.type.args:
1839 if arg.needs_type_test:
1840 self.generate_arg_type_test(arg, code)
1841 elif arg.type.is_pyobject and not arg.accept_none:
1842 self.generate_arg_none_check(arg, code)
1844 def error_value(self):
1845 if self.return_type.is_pyobject:
1849 return self.entry.type.exception_value
1851 def caller_will_check_exceptions(self):
1852 return self.entry.type.exception_check
1854 def generate_wrapper_functions(self, code):
1855 # If the C signature of a function has changed, we need to generate
1856 # wrappers to put in the slots here.
1859 func_type = entry.type
1860 while entry.prev_entry is not None:
1862 entry = entry.prev_entry
1863 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1865 self.generate_function_header(code,
1867 with_dispatch = entry.type.is_overridable,
1868 with_opt_args = entry.type.optional_arg_count,
1869 cname = entry.func_cname)
1870 if not self.return_type.is_void:
1872 args = self.type.args
1873 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1874 if entry.type.is_overridable:
1875 arglist.append(Naming.skip_dispatch_cname)
1876 elif func_type.is_overridable:
1878 if entry.type.optional_arg_count:
1879 arglist.append(Naming.optional_args_cname)
1880 elif func_type.optional_arg_count:
1881 arglist.append('NULL')
1882 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1886 class PyArgDeclNode(Node):
1887 # Argument which must be a Python object (used
1888 # for * and ** arguments).
1891 # entry Symtab.Entry
1892 # annotation ExprNode or None Py3 argument annotation
1895 def generate_function_definitions(self, env, code):
1896 self.entry.generate_function_definitions(env, code)
1898 class DecoratorNode(Node):
1901 # decorator NameNode or CallNode or AttributeNode
1902 child_attrs = ['decorator']
1905 class GeneratorWrapperNode(object):
1907 def __init__(self, def_node, func_cname=None, body_cname=None, header=None):
1908 self.def_node = def_node
1909 self.func_cname = func_cname
1910 self.body_cname = body_cname
1911 self.header = header
1913 def generate_function_body(self, env, code):
1914 code.mark_pos(self.def_node.pos)
1915 cenv = env.outer_scope # XXX: correct?
1916 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1917 cenv = cenv.outer_scope
1918 lenv = self.def_node.local_scope
1919 code.enter_cfunc_scope()
1921 code.putln('%s {' % self.header)
1922 code.put_declare_refcount_context()
1923 self.def_node.generate_keyword_list(code)
1924 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1926 code.put_setup_refcount_context(self.def_node.entry.name)
1927 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1928 Naming.cur_scope_cname,
1929 lenv.scope_class.type.declaration_code(''),
1930 lenv.scope_class.type.typeptr_cname,
1931 lenv.scope_class.type.typeptr_cname,
1932 Naming.empty_tuple))
1933 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1934 code.put_finish_refcount_context()
1935 code.putln("return NULL;");
1937 code.put_gotref(Naming.cur_scope_cname)
1939 if self.def_node.needs_outer_scope:
1940 outer_scope_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.outer_scope_cname)
1941 code.putln("%s = (%s)%s;" % (
1943 cenv.scope_class.type.declaration_code(''),
1945 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1946 code.put_giveref(outer_scope_cname)
1948 self.def_node.generate_preamble(env, code)
1950 generator_cname = '%s->%s' % (Naming.cur_scope_cname, Naming.obj_base_cname)
1952 code.putln('%s.resume_label = 0;' % generator_cname)
1953 code.putln('%s.body = %s;' % (generator_cname, self.body_cname))
1954 code.put_giveref(Naming.cur_scope_cname)
1955 code.put_finish_refcount_context()
1956 code.putln("return (PyObject *) %s;" % Naming.cur_scope_cname);
1958 code.exit_cfunc_scope()
1960 class DefNode(FuncDefNode):
1961 # A Python function definition.
1963 # name string the Python name of the function
1964 # lambda_name string the internal name of a lambda 'function'
1965 # decorators [DecoratorNode] list of decorators
1966 # args [CArgDeclNode] formal arguments
1967 # star_arg PyArgDeclNode or None * argument
1968 # starstar_arg PyArgDeclNode or None ** argument
1969 # doc EncodedString or None
1971 # return_type_annotation
1972 # ExprNode or None the Py3 return type annotation
1974 # The following subnode is constructed internally
1975 # when the def statement is inside a Python class definition.
1977 # assmt AssignmentNode Function construction/assignment
1979 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1984 num_required_kw_args = 0
1985 reqd_kw_flags_cname = "0"
1988 return_type_annotation = None
1993 def __init__(self, pos, **kwds):
1994 FuncDefNode.__init__(self, pos, **kwds)
1996 for arg in self.args:
2003 self.num_kwonly_args = k
2004 self.num_required_kw_args = rk
2005 self.num_required_args = r
2007 def as_cfunction(self, cfunc=None, scope=None):
2009 error(self.star_arg.pos, "cdef function cannot have star argument")
2010 if self.starstar_arg:
2011 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
2014 for formal_arg in self.args:
2015 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
2016 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
2018 type = py_object_type,
2019 pos = formal_arg.pos))
2020 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
2022 has_varargs = False,
2023 exception_value = None,
2024 exception_check = False,
2027 is_overridable = True)
2028 cfunc = CVarDefNode(self.pos, type=cfunc_type)
2032 cfunc_type = cfunc.type
2033 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
2034 error(self.pos, "wrong number of arguments")
2035 error(cfunc.pos, "previous declaration here")
2036 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
2037 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
2038 is_self_arg = (i == 0 and scope.is_c_class_scope))
2039 if type is None or type is PyrexTypes.py_object_type:
2040 formal_arg.type = type_arg.type
2041 formal_arg.name_declarator = name_declarator
2043 if cfunc_type.exception_value is None:
2044 exception_value = None
2046 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
2047 declarator = CFuncDeclaratorNode(self.pos,
2048 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
2050 has_varargs = False,
2051 exception_check = cfunc_type.exception_check,
2052 exception_value = exception_value,
2053 with_gil = cfunc_type.with_gil,
2054 nogil = cfunc_type.nogil)
2055 return CFuncDefNode(self.pos,
2057 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
2058 declarator = declarator,
2061 overridable = cfunc_type.is_overridable,
2063 with_gil = cfunc_type.with_gil,
2064 nogil = cfunc_type.nogil,
2065 visibility = 'private',
2067 directive_locals = getattr(cfunc, 'directive_locals', {}))
2069 def analyse_declarations(self, env):
2070 self.is_classmethod = self.is_staticmethod = False
2072 for decorator in self.decorators:
2073 func = decorator.decorator
2075 self.is_classmethod |= func.name == 'classmethod'
2076 self.is_staticmethod |= func.name == 'staticmethod'
2078 if self.is_classmethod and env.lookup_here('classmethod'):
2079 # classmethod() was overridden - not much we can do here ...
2080 self.is_classmethod = False
2081 if self.is_staticmethod and env.lookup_here('staticmethod'):
2082 # staticmethod() was overridden - not much we can do here ...
2083 self.is_staticmethod = False
2085 if self.name == '__new__' and env.is_py_class_scope:
2086 self.is_staticmethod = 1
2088 self.analyse_argument_types(env)
2089 if self.name == '<lambda>':
2090 self.declare_lambda_function(env)
2092 self.declare_pyfunction(env)
2093 self.analyse_signature(env)
2094 self.return_type = self.entry.signature.return_type()
2095 self.create_local_scope(env)
2097 def analyse_argument_types(self, env):
2098 directive_locals = self.directive_locals = env.directives['locals']
2099 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2100 for arg in self.args:
2101 if hasattr(arg, 'name'):
2103 name_declarator = None
2105 base_type = arg.base_type.analyse(env)
2106 name_declarator, type = \
2107 arg.declarator.analyse(base_type, env)
2108 arg.name = name_declarator.name
2109 if arg.name in directive_locals:
2110 type_node = directive_locals[arg.name]
2111 other_type = type_node.analyse_as_type(env)
2112 if other_type is None:
2113 error(type_node.pos, "Not a type")
2114 elif (type is not PyrexTypes.py_object_type
2115 and not type.same_as(other_type)):
2116 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2117 error(type_node.pos, "Previous declaration here")
2120 if name_declarator and name_declarator.cname:
2122 "Python function argument cannot have C name specification")
2123 arg.type = type.as_argument_type()
2125 arg.needs_conversion = 0
2126 arg.needs_type_test = 0
2128 if arg.type.is_pyobject:
2130 arg.accept_none = True
2132 arg.accept_none = False
2133 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2134 if arg.default and arg.default.constant_result is None:
2135 # special case: def func(MyType obj = None)
2136 arg.accept_none = True
2138 # default depends on compiler directive
2139 arg.accept_none = allow_none_for_extension_args
2141 # probably just a plain 'object'
2142 arg.accept_none = True
2144 arg.accept_none = True # won't be used, but must be there
2146 error(arg.pos, "Only Python type arguments can have 'not None'")
2148 error(arg.pos, "Only Python type arguments can have 'or None'")
2150 def analyse_signature(self, env):
2151 if self.entry.is_special:
2152 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2153 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2154 # Use the simpler calling signature for zero- and one-argument functions.
2155 if self.entry.signature is TypeSlots.pyfunction_signature:
2156 if len(self.args) == 0:
2157 self.entry.signature = TypeSlots.pyfunction_noargs
2158 elif len(self.args) == 1:
2159 if self.args[0].default is None and not self.args[0].kw_only:
2160 self.entry.signature = TypeSlots.pyfunction_onearg
2161 elif self.entry.signature is TypeSlots.pymethod_signature:
2162 if len(self.args) == 1:
2163 self.entry.signature = TypeSlots.unaryfunc
2164 elif len(self.args) == 2:
2165 if self.args[1].default is None and not self.args[1].kw_only:
2166 self.entry.signature = TypeSlots.ibinaryfunc
2168 sig = self.entry.signature
2169 nfixed = sig.num_fixed_args()
2170 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2171 and len(self.args) == 0 and self.star_arg:
2172 # this is the only case where a diverging number of
2173 # arguments is not an error - when we have no explicit
2174 # 'self' parameter as in method(*args)
2175 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2176 self.self_in_stararg = 1
2179 for i in range(min(nfixed, len(self.args))):
2182 if sig.is_self_arg(i) and not self.is_staticmethod:
2183 if self.is_classmethod:
2185 arg.hdr_type = arg.type = Builtin.type_type
2188 arg.hdr_type = arg.type = env.parent_type
2189 arg.needs_conversion = 0
2191 arg.hdr_type = sig.fixed_arg_type(i)
2192 if not arg.type.same_as(arg.hdr_type):
2193 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2194 arg.needs_type_test = 1
2196 arg.needs_conversion = 1
2197 if arg.needs_conversion:
2198 arg.hdr_cname = Naming.arg_prefix + arg.name
2200 arg.hdr_cname = Naming.var_prefix + arg.name
2202 if nfixed > len(self.args):
2203 self.bad_signature()
2205 elif nfixed < len(self.args):
2206 if not sig.has_generic_args:
2207 self.bad_signature()
2208 for arg in self.args:
2209 if arg.is_generic and \
2210 (arg.type.is_extension_type or arg.type.is_builtin_type):
2211 arg.needs_type_test = 1
2213 def bad_signature(self):
2214 sig = self.entry.signature
2215 expected_str = "%d" % sig.num_fixed_args()
2216 if sig.has_generic_args:
2217 expected_str = expected_str + " or more"
2219 if name.startswith("__") and name.endswith("__"):
2220 desc = "Special method"
2224 "%s %s has wrong number of arguments "
2225 "(%d declared, %s expected)" % (
2226 desc, self.name, len(self.args), expected_str))
2228 def signature_has_nongeneric_args(self):
2229 argcount = len(self.args)
2230 if argcount == 0 or (
2231 argcount == 1 and (self.args[0].is_self_arg or
2232 self.args[0].is_type_arg)):
2236 def signature_has_generic_args(self):
2237 return self.entry.signature.has_generic_args
2239 def declare_pyfunction(self, env):
2240 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2242 entry = env.lookup_here(name)
2243 if entry and entry.type.is_cfunction and not self.is_wrapper:
2244 warning(self.pos, "Overriding cdef method with def method.", 5)
2245 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2247 prefix = env.next_id(env.scope_prefix)
2249 entry.func_cname = \
2250 Naming.pyfunc_prefix + prefix + name
2251 entry.pymethdef_cname = \
2252 Naming.pymethdef_prefix + prefix + name
2254 if self.is_generator:
2255 self.generator_body_cname = Naming.genbody_prefix + env.next_id(env.scope_prefix) + name
2257 if Options.docstrings:
2258 entry.doc = embed_position(self.pos, self.doc)
2260 Naming.funcdoc_prefix + prefix + name
2261 if entry.is_special:
2262 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2263 entry.wrapperbase_cname = None
2265 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2269 def declare_lambda_function(self, env):
2271 prefix = env.scope_prefix
2273 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2274 entry = env.declare_lambda_function(func_cname, self.pos)
2275 entry.pymethdef_cname = \
2276 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2277 entry.qualified_name = env.qualify_name(self.lambda_name)
2281 def declare_arguments(self, env):
2282 for arg in self.args:
2284 error(arg.pos, "Missing argument name")
2286 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2287 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2288 if arg.needs_conversion:
2289 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2290 if arg.type.is_pyobject:
2291 arg.entry.init = "0"
2292 arg.entry.init_to_none = 0
2294 arg.entry = self.declare_argument(env, arg)
2296 arg.entry.is_self_arg = arg.is_self_arg
2298 if arg.is_self_arg or arg.is_type_arg or \
2299 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2300 arg.entry.is_declared_generic = 1
2301 self.declare_python_arg(env, self.star_arg)
2302 self.declare_python_arg(env, self.starstar_arg)
2304 def declare_python_arg(self, env, arg):
2306 if env.directives['infer_types'] != False:
2307 type = PyrexTypes.unspecified_type
2309 type = py_object_type
2310 entry = env.declare_var(arg.name, type, arg.pos)
2313 entry.init_to_none = 0
2314 entry.xdecref_cleanup = 1
2316 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2318 def analyse_expressions(self, env):
2319 self.local_scope.directives = env.directives
2320 self.analyse_default_values(env)
2321 if self.needs_assignment_synthesis(env):
2322 # Shouldn't we be doing this at the module level too?
2323 self.synthesize_assignment_node(env)
2325 def needs_assignment_synthesis(self, env, code=None):
2326 # Should enable for module level as well, that will require more testing...
2327 if self.entry.is_anonymous:
2329 if env.is_module_scope:
2331 return env.directives['binding']
2333 return code.globalstate.directives['binding']
2334 return env.is_py_class_scope or env.is_closure_scope
2336 def synthesize_assignment_node(self, env):
2339 while genv.is_py_class_scope or genv.is_c_class_scope:
2340 genv = genv.outer_scope
2342 if genv.is_closure_scope:
2343 rhs = ExprNodes.InnerFunctionNode(
2344 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2346 rhs = ExprNodes.PyCFunctionNode(
2347 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2349 if env.is_py_class_scope:
2350 if not self.is_staticmethod and not self.is_classmethod:
2353 self.assmt = SingleAssignmentNode(self.pos,
2354 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2356 self.assmt.analyse_declarations(env)
2357 self.assmt.analyse_expressions(env)
2359 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2361 sig = self.entry.signature
2362 if sig.has_dummy_arg or self.self_in_stararg:
2363 arg_code_list.append(
2364 "PyObject *%s" % Naming.self_cname)
2365 for arg in self.args:
2366 if not arg.is_generic:
2367 if arg.is_self_arg or arg.is_type_arg:
2368 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2370 arg_code_list.append(
2371 arg.hdr_type.declaration_code(arg.hdr_cname))
2372 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2373 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2374 if sig.has_generic_args:
2375 arg_code_list.append(
2376 "PyObject *%s, PyObject *%s"
2377 % (Naming.args_cname, Naming.kwds_cname))
2378 arg_code = ", ".join(arg_code_list)
2379 dc = self.return_type.declaration_code(self.entry.func_cname)
2380 mf = " ".join(self.modifiers).upper()
2382 header = "static %s%s(%s)" % (mf, dc, arg_code)
2383 code.putln("%s; /*proto*/" % header)
2386 if (Options.docstrings and self.entry.doc and
2387 not self.entry.scope.is_property_scope and
2388 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2389 docstr = self.entry.doc
2390 if docstr.is_unicode:
2391 docstr = docstr.utf8encode()
2393 'static char %s[] = "%s";' % (
2394 self.entry.doc_cname,
2395 split_string_literal(escape_byte_string(docstr))))
2396 if self.entry.is_special:
2398 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2401 "static PyMethodDef %s = " %
2402 self.entry.pymethdef_cname)
2403 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2404 if self.is_generator:
2405 code.putln("static PyObject *%s(PyObject *%s, PyObject *%s) /* generator body */\n{" %
2406 (self.generator_body_cname, Naming.self_cname, Naming.sent_value_cname))
2407 self.generator = GeneratorWrapperNode(self,
2408 func_cname=self.entry.func_cname,
2409 body_cname=self.generator_body_cname,
2412 code.putln("%s {" % header)
2414 def generate_argument_declarations(self, env, code):
2415 for arg in self.args:
2416 if arg.is_generic: # or arg.needs_conversion:
2417 if arg.needs_conversion:
2418 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2419 elif not arg.entry.in_closure:
2420 code.put_var_declaration(arg.entry)
2422 def generate_keyword_list(self, code):
2423 if self.signature_has_generic_args() and \
2424 self.signature_has_nongeneric_args():
2426 "static PyObject **%s[] = {" %
2427 Naming.pykwdlist_cname)
2428 for arg in self.args:
2430 pystring_cname = code.intern_identifier(arg.name)
2431 code.put('&%s,' % pystring_cname)
2434 def generate_argument_parsing_code(self, env, code):
2435 # Generate fast equivalent of PyArg_ParseTuple call for
2436 # generic arguments, if any, including args/kwargs
2437 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2438 # get rid of unused argument warning
2439 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2441 old_error_label = code.new_error_label()
2442 our_error_label = code.error_label
2443 end_label = code.new_label("argument_unpacking_done")
2445 has_kwonly_args = self.num_kwonly_args > 0
2446 has_star_or_kw_args = self.star_arg is not None \
2447 or self.starstar_arg is not None or has_kwonly_args
2449 for arg in self.args:
2450 if not arg.type.is_pyobject:
2451 done = arg.type.create_from_py_utility_code(env)
2452 if not done: pass # will fail later
2454 if not self.signature_has_generic_args():
2455 if has_star_or_kw_args:
2456 error(self.pos, "This method cannot have * or keyword arguments")
2457 self.generate_argument_conversion_code(code)
2459 elif not self.signature_has_nongeneric_args():
2460 # func(*args) or func(**kw) or func(*args, **kw)
2461 self.generate_stararg_copy_code(code)
2464 positional_args = []
2466 for arg in self.args:
2467 arg_entry = arg.entry
2470 if not arg.is_self_arg and not arg.is_type_arg:
2472 kw_only_args.append(arg)
2474 positional_args.append(arg)
2476 kw_only_args.append(arg)
2477 elif not arg.is_self_arg and not arg.is_type_arg:
2478 positional_args.append(arg)
2480 self.generate_tuple_and_keyword_parsing_code(
2481 positional_args, kw_only_args, end_label, code)
2483 code.error_label = old_error_label
2484 if code.label_used(our_error_label):
2485 if not code.label_used(end_label):
2486 code.put_goto(end_label)
2487 code.put_label(our_error_label)
2488 if has_star_or_kw_args:
2489 self.generate_arg_decref(self.star_arg, code)
2490 if self.starstar_arg:
2491 if self.starstar_arg.entry.xdecref_cleanup:
2492 code.put_var_xdecref_clear(self.starstar_arg.entry)
2494 code.put_var_decref_clear(self.starstar_arg.entry)
2495 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2496 # The arguments are put into the closure one after the
2497 # other, so when type errors are found, all references in
2498 # the closure instance must be properly ref-counted to
2499 # facilitate generic closure instance deallocation. In
2500 # the case of an argument type error, it's best to just
2501 # DECREF+clear the already handled references, as this
2502 # frees their references as early as possible.
2503 for arg in self.args:
2504 if arg.type.is_pyobject and arg.entry.in_closure:
2505 code.put_var_xdecref_clear(arg.entry)
2506 if self.needs_closure:
2507 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2508 code.put_finish_refcount_context()
2509 code.putln("return %s;" % self.error_value())
2510 if code.label_used(end_label):
2511 code.put_label(end_label)
2513 # fix refnanny view on closure variables here, instead of
2514 # doing it separately for each arg parsing special case
2515 if self.star_arg and self.star_arg.entry.in_closure:
2516 code.put_var_giveref(self.star_arg.entry)
2517 if self.starstar_arg and self.starstar_arg.entry.in_closure:
2518 code.put_var_giveref(self.starstar_arg.entry)
2519 for arg in self.args:
2520 if arg.type.is_pyobject and arg.entry.in_closure:
2521 code.put_var_giveref(arg.entry)
2523 def generate_arg_assignment(self, arg, item, code):
2524 if arg.type.is_pyobject:
2526 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2528 if entry.in_closure:
2529 code.put_incref(item, PyrexTypes.py_object_type)
2530 code.putln("%s = %s;" % (entry.cname, item))
2532 func = arg.type.from_py_function
2534 code.putln("%s = %s(%s); %s" % (
2538 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2540 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2542 def generate_arg_xdecref(self, arg, code):
2544 code.put_var_xdecref_clear(arg.entry)
2546 def generate_arg_decref(self, arg, code):
2548 code.put_var_decref_clear(arg.entry)
2550 def generate_stararg_copy_code(self, code):
2551 if not self.star_arg:
2552 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2553 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2555 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2556 self.name, Naming.args_cname, self.error_value()))
2559 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2561 if self.starstar_arg:
2563 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2565 kwarg_check = "%s" % Naming.kwds_cname
2567 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2568 Naming.kwds_cname, Naming.kwds_cname)
2570 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2571 kwarg_check, Naming.kwds_cname, self.name,
2572 bool(self.starstar_arg), self.error_value()))
2574 if self.starstar_arg:
2575 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2576 self.starstar_arg.entry.cname,
2579 code.putln("if (unlikely(!%s)) return %s;" % (
2580 self.starstar_arg.entry.cname, self.error_value()))
2581 self.starstar_arg.entry.xdecref_cleanup = 0
2582 code.put_gotref(self.starstar_arg.entry.cname)
2584 if self.self_in_stararg:
2585 # need to create a new tuple with 'self' inserted as first item
2586 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2587 self.star_arg.entry.cname,
2589 self.star_arg.entry.cname))
2590 if self.starstar_arg:
2592 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2593 code.putln("return %s;" % self.error_value())
2596 code.putln("return %s;" % self.error_value())
2597 code.put_gotref(self.star_arg.entry.cname)
2598 code.put_incref(Naming.self_cname, py_object_type)
2599 code.put_giveref(Naming.self_cname)
2600 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2601 self.star_arg.entry.cname, Naming.self_cname))
2602 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2603 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2604 temp, temp, Naming.args_cname, temp))
2605 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2606 Naming.args_cname, temp))
2607 code.put_incref("item", py_object_type)
2608 code.put_giveref("item")
2609 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2610 self.star_arg.entry.cname, temp))
2612 code.funcstate.release_temp(temp)
2613 self.star_arg.entry.xdecref_cleanup = 0
2615 code.put_incref(Naming.args_cname, py_object_type)
2616 code.putln("%s = %s;" % (
2617 self.star_arg.entry.cname,
2619 self.star_arg.entry.xdecref_cleanup = 0
2621 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2622 kw_only_args, success_label, code):
2623 argtuple_error_label = code.new_label("argtuple_error")
2625 min_positional_args = self.num_required_args - self.num_required_kw_args
2626 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2627 min_positional_args -= 1
2628 max_positional_args = len(positional_args)
2629 has_fixed_positional_count = not self.star_arg and \
2630 min_positional_args == max_positional_args
2632 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2633 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2634 if self.num_required_kw_args:
2635 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2637 if self.starstar_arg or self.star_arg:
2638 self.generate_stararg_init_code(max_positional_args, code)
2640 # --- optimised code when we receive keyword arguments
2641 if self.num_required_kw_args:
2642 likely_hint = "likely"
2644 likely_hint = "unlikely"
2645 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2646 self.generate_keyword_unpacking_code(
2647 min_positional_args, max_positional_args,
2648 has_fixed_positional_count,
2649 positional_args, kw_only_args, argtuple_error_label, code)
2651 # --- optimised code when we do not receive any keyword arguments
2652 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2653 # Python raises arg tuple related errors first, so we must
2654 # check the length here
2655 if min_positional_args == max_positional_args and not self.star_arg:
2659 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2660 Naming.args_cname, compare, min_positional_args))
2661 code.put_goto(argtuple_error_label)
2663 if self.num_required_kw_args:
2664 # pure error case: keywords required but not passed
2665 if max_positional_args > min_positional_args and not self.star_arg:
2666 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2667 Naming.args_cname, max_positional_args))
2668 code.put_goto(argtuple_error_label)
2669 code.putln('} else {')
2670 for i, arg in enumerate(kw_only_args):
2672 pystring_cname = code.intern_identifier(arg.name)
2673 # required keyword-only argument missing
2674 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2677 code.putln(code.error_goto(self.pos))
2680 elif min_positional_args == max_positional_args:
2681 # parse the exact number of positional arguments from the
2683 code.putln('} else {')
2684 for i, arg in enumerate(positional_args):
2685 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2686 self.generate_arg_assignment(arg, item, code)
2687 self.generate_arg_default_assignments(code)
2690 # parse the positional arguments from the variable length
2692 code.putln('} else {')
2693 self.generate_arg_default_assignments(code)
2694 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2696 code.putln('default:')
2697 reversed_args = list(enumerate(positional_args))[::-1]
2698 for i, arg in reversed_args:
2699 if i >= min_positional_args-1:
2700 if min_positional_args > 1:
2701 code.putln('case %2d:' % (i+1)) # pure code beautification
2703 code.put('case %2d: ' % (i+1))
2704 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2705 self.generate_arg_assignment(arg, item, code)
2706 if min_positional_args == 0:
2707 code.put('case 0: ')
2708 code.putln('break;')
2710 if min_positional_args:
2711 for i in range(min_positional_args-1, -1, -1):
2712 code.putln('case %2d:' % i)
2713 code.put_goto(argtuple_error_label)
2715 code.put('default: ')
2716 code.put_goto(argtuple_error_label)
2721 if code.label_used(argtuple_error_label):
2722 code.put_goto(success_label)
2723 code.put_label(argtuple_error_label)
2724 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2725 self.name, has_fixed_positional_count,
2726 min_positional_args, max_positional_args,
2728 code.putln(code.error_goto(self.pos))
2730 def generate_arg_default_assignments(self, code):
2731 for arg in self.args:
2732 if arg.is_generic and arg.default:
2736 arg.calculate_default_value_code(code)))
2738 def generate_stararg_init_code(self, max_positional_args, code):
2739 if self.starstar_arg:
2740 self.starstar_arg.entry.xdecref_cleanup = 0
2741 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2742 self.starstar_arg.entry.cname,
2743 self.starstar_arg.entry.cname,
2744 self.error_value()))
2745 code.put_gotref(self.starstar_arg.entry.cname)
2747 self.star_arg.entry.xdecref_cleanup = 0
2748 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2750 max_positional_args))
2751 code.putln('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s));' % (
2752 self.star_arg.entry.cname, Naming.args_cname,
2753 max_positional_args, Naming.args_cname))
2754 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2755 if self.starstar_arg:
2756 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2757 if self.needs_closure:
2758 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2759 code.put_finish_refcount_context()
2760 code.putln('return %s;' % self.error_value())
2762 code.put_gotref(self.star_arg.entry.cname)
2763 code.putln('} else {')
2764 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2765 code.put_incref(Naming.empty_tuple, py_object_type)
2768 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2769 has_fixed_positional_count, positional_args,
2770 kw_only_args, argtuple_error_label, code):
2771 all_args = tuple(positional_args) + tuple(kw_only_args)
2772 max_args = len(all_args)
2774 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2776 # the 'values' array collects borrowed references to arguments
2777 # before doing any type coercion etc.
2778 code.putln("PyObject* values[%d] = {%s};" % (
2779 max_args, ','.join('0'*max_args)))
2781 # assign borrowed Python default values to the values array,
2782 # so that they can be overwritten by received arguments below
2783 for i, arg in enumerate(all_args):
2784 if arg.default and arg.type.is_pyobject:
2785 default_value = arg.calculate_default_value_code(code)
2786 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2788 # parse the args tuple and check that it's not too long
2789 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2791 code.putln('default:')
2792 for i in range(max_positional_args-1, -1, -1):
2793 code.put('case %2d: ' % (i+1))
2794 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2795 i, Naming.args_cname, i))
2796 code.putln('case 0: break;')
2797 if not self.star_arg:
2798 code.put('default: ') # more arguments than allowed
2799 code.put_goto(argtuple_error_label)
2802 # now fill up the positional/required arguments with values
2804 if self.num_required_args or max_positional_args > 0:
2805 last_required_arg = -1
2806 for i, arg in enumerate(all_args):
2808 last_required_arg = i
2809 if last_required_arg < max_positional_args:
2810 last_required_arg = max_positional_args-1
2811 num_required_args = self.num_required_args
2812 if max_positional_args > 0:
2813 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2814 for i, arg in enumerate(all_args[:last_required_arg+1]):
2815 if max_positional_args > 0 and i <= max_positional_args:
2816 if self.star_arg and i == max_positional_args:
2817 code.putln('default:')
2819 code.putln('case %2d:' % i)
2820 pystring_cname = code.intern_identifier(arg.name)
2823 # handled separately below
2825 code.putln('if (kw_args > 0) {')
2826 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2827 Naming.kwds_cname, pystring_cname))
2828 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2831 num_required_args -= 1
2832 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2833 i, Naming.kwds_cname, pystring_cname))
2834 code.putln('if (likely(values[%d])) kw_args--;' % i);
2835 if i < min_positional_args:
2837 # special case: we know arg 0 is missing
2839 code.put_goto(argtuple_error_label)
2841 # print the correct number of values (args or
2842 # kwargs) that were passed into positional
2843 # arguments up to this point
2844 code.putln('else {')
2845 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2846 self.name, has_fixed_positional_count,
2847 min_positional_args, max_positional_args, i))
2848 code.putln(code.error_goto(self.pos))
2851 code.putln('else {')
2852 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2853 self.name, pystring_cname))
2854 code.putln(code.error_goto(self.pos))
2856 if max_positional_args > 0:
2859 if kw_only_args and not self.starstar_arg:
2860 # unpack optional keyword-only arguments
2861 # checking for interned strings in a dict is faster than iterating
2862 # but it's too likely that we must iterate if we expect **kwargs
2864 for i, arg in enumerate(all_args[max_positional_args:]):
2865 if not arg.kw_only or not arg.default:
2867 optional_args.append((i+max_positional_args, arg))
2869 # this mimics an unrolled loop so that we can "break" out of it
2870 code.putln('while (kw_args > 0) {')
2871 code.putln('PyObject* value;')
2872 for i, arg in optional_args:
2873 pystring_cname = code.intern_identifier(arg.name)
2875 'value = PyDict_GetItem(%s, %s);' % (
2876 Naming.kwds_cname, pystring_cname))
2878 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2879 code.putln('break;')
2882 code.putln('if (unlikely(kw_args > 0)) {')
2883 # non-positional/-required kw args left in dict: default args,
2884 # kw-only args, **kwargs or error
2886 # This is sort of a catch-all: except for checking required
2887 # arguments, this will always do the right thing for unpacking
2888 # keyword arguments, so that we can concentrate on optimising
2889 # common cases above.
2890 if max_positional_args == 0:
2893 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2894 Naming.args_cname, max_positional_args,
2895 Naming.args_cname, max_positional_args))
2896 pos_arg_count = "used_pos_args"
2898 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2899 code.globalstate.use_utility_code(parse_keywords_utility_code)
2901 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2903 Naming.pykwdlist_cname,
2904 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2907 code.putln(code.error_goto(self.pos))
2910 # convert arg values to their final type and assign them
2911 for i, arg in enumerate(all_args):
2912 if arg.default and not arg.type.is_pyobject:
2913 code.putln("if (values[%d]) {" % i)
2914 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2915 if arg.default and not arg.type.is_pyobject:
2916 code.putln('} else {')
2920 arg.calculate_default_value_code(code)))
2923 def generate_argument_conversion_code(self, code):
2924 # Generate code to convert arguments from signature type to
2925 # declared type, if needed. Also copies signature arguments
2926 # into closure fields.
2927 for arg in self.args:
2928 if arg.needs_conversion:
2929 self.generate_arg_conversion(arg, code)
2930 elif arg.entry.in_closure:
2931 if arg.type.is_pyobject:
2932 code.put_incref(arg.hdr_cname, py_object_type)
2933 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2935 def generate_arg_conversion(self, arg, code):
2936 # Generate conversion code for one argument.
2937 old_type = arg.hdr_type
2939 if old_type.is_pyobject:
2941 code.putln("if (%s) {" % arg.hdr_cname)
2943 code.putln("assert(%s); {" % arg.hdr_cname)
2944 self.generate_arg_conversion_from_pyobject(arg, code)
2946 elif new_type.is_pyobject:
2947 self.generate_arg_conversion_to_pyobject(arg, code)
2949 if new_type.assignable_from(old_type):
2951 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2954 "Cannot convert 1 argument from '%s' to '%s'" %
2955 (old_type, new_type))
2957 def generate_arg_conversion_from_pyobject(self, arg, code):
2959 func = new_type.from_py_function
2960 # copied from CoerceFromPyTypeNode
2962 lhs = arg.entry.cname
2963 rhs = "%s(%s)" % (func, arg.hdr_cname)
2964 if new_type.is_enum:
2965 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2966 code.putln("%s = %s; %s" % (
2969 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2972 "Cannot convert Python object argument to type '%s'"
2975 def generate_arg_conversion_to_pyobject(self, arg, code):
2976 old_type = arg.hdr_type
2977 func = old_type.to_py_function
2979 code.putln("%s = %s(%s); %s" % (
2983 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2984 code.put_var_gotref(arg.entry)
2987 "Cannot convert argument of type '%s' to Python object"
2990 def generate_argument_type_tests(self, code):
2991 # Generate type tests for args whose signature
2992 # type is PyObject * and whose declared type is
2993 # a subtype thereof.
2994 for arg in self.args:
2995 if arg.needs_type_test:
2996 self.generate_arg_type_test(arg, code)
2997 elif not arg.accept_none and arg.type.is_pyobject:
2998 self.generate_arg_none_check(arg, code)
3000 def error_value(self):
3001 return self.entry.signature.error_value
3003 def caller_will_check_exceptions(self):
3006 class OverrideCheckNode(StatNode):
3007 # A Node for dispatching to the def method if it
3016 child_attrs = ['body']
3020 def analyse_expressions(self, env):
3021 self.args = env.arg_entries
3022 if self.py_func.is_module_scope:
3027 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
3028 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3029 call_node = ExprNodes.SimpleCallNode(self.pos,
3030 function=self.func_node,
3031 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
3032 self.body = ReturnStatNode(self.pos, value=call_node)
3033 self.body.analyse_expressions(env)
3035 def generate_execution_code(self, code):
3036 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
3037 # Check to see if we are an extension type
3038 if self.py_func.is_module_scope:
3039 self_arg = "((PyObject *)%s)" % Naming.module_cname
3041 self_arg = "((PyObject *)%s)" % self.args[0].cname
3042 code.putln("/* Check if called by wrapper */")
3043 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
3044 code.putln("/* Check if overriden in Python */")
3045 if self.py_func.is_module_scope:
3046 code.putln("else {")
3048 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
3049 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
3050 self.func_node.set_cname(func_node_temp)
3051 # need to get attribute manually--scope would return cdef method
3052 err = code.error_goto_if_null(func_node_temp, self.pos)
3053 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
3054 func_node_temp, self_arg, interned_attr_cname, err))
3055 code.put_gotref(func_node_temp)
3056 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
3057 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
3058 func_node_temp, self.py_func.entry.func_cname)
3059 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
3060 self.body.generate_execution_code(code)
3062 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
3063 code.funcstate.release_temp(func_node_temp)
3066 class ClassDefNode(StatNode, BlockNode):
3069 class PyClassDefNode(ClassDefNode):
3070 # A Python class definition.
3072 # name EncodedString Name of the class
3073 # doc string or None
3074 # body StatNode Attribute definition code
3075 # entry Symtab.Entry
3076 # scope PyClassScope
3077 # decorators [DecoratorNode] list of decorators or None
3079 # The following subnodes are constructed internally:
3081 # dict DictNode Class dictionary or Py3 namespace
3082 # classobj ClassNode Class object
3083 # target NameNode Variable to assign class object to
3085 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "classobj", "target"]
3087 py3_style_class = False # Python3 style class (bases+kwargs)
3089 def __init__(self, pos, name, bases, doc, body, decorators = None,
3090 keyword_args = None, starstar_arg = None):
3091 StatNode.__init__(self, pos)
3095 self.decorators = decorators
3097 if self.doc and Options.docstrings:
3098 doc = embed_position(self.pos, self.doc)
3099 doc_node = ExprNodes.StringNode(pos, value = doc)
3102 if keyword_args or starstar_arg:
3103 self.py3_style_class = True
3105 self.metaclass = None
3106 if keyword_args and not starstar_arg:
3107 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3108 if item.key.value == 'metaclass':
3109 if self.metaclass is not None:
3110 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3111 # special case: we already know the metaclass,
3112 # so we don't need to do the "build kwargs,
3113 # find metaclass" dance at runtime
3114 self.metaclass = item.value
3115 del keyword_args.key_value_pairs[i]
3116 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3117 self.mkw = ExprNodes.KeywordArgsNode(
3118 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3120 self.mkw = ExprNodes.NullNode(pos)
3121 if self.metaclass is None:
3122 self.metaclass = ExprNodes.PyClassMetaclassNode(
3123 pos, mkw = self.mkw, bases = self.bases)
3124 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3125 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3127 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3128 bases = self.bases, dict = self.dict, doc = doc_node,
3129 metaclass = self.metaclass, mkw = self.mkw)
3131 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3132 self.metaclass = None
3135 self.classobj = ExprNodes.ClassNode(pos, name = name,
3136 bases = bases, dict = self.dict, doc = doc_node)
3137 self.target = ExprNodes.NameNode(pos, name = name)
3139 def as_cclass(self):
3141 Return this node as if it were declared as an extension class
3143 if self.py3_style_class:
3144 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3146 bases = self.classobj.bases.args
3148 base_class_name = None
3149 base_class_module = None
3150 elif len(bases) == 1:
3153 from ExprNodes import AttributeNode, NameNode
3154 while isinstance(base, AttributeNode):
3155 path.insert(0, base.attribute)
3157 if isinstance(base, NameNode):
3158 path.insert(0, base.name)
3159 base_class_name = path[-1]
3161 base_class_module = u'.'.join(path[:-1])
3163 base_class_module = None
3165 error(self.classobj.bases.args.pos, "Invalid base class")
3167 error(self.classobj.bases.args.pos, "C class may only have one base class")
3170 return CClassDefNode(self.pos,
3171 visibility = 'private',
3173 class_name = self.name,
3174 base_class_module = base_class_module,
3175 base_class_name = base_class_name,
3176 decorators = self.decorators,
3181 def create_scope(self, env):
3183 while genv.is_py_class_scope or genv.is_c_class_scope:
3184 genv = genv.outer_scope
3185 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3188 def analyse_declarations(self, env):
3189 self.target.analyse_target_declaration(env)
3190 cenv = self.create_scope(env)
3191 cenv.directives = env.directives
3192 cenv.class_obj_cname = self.target.entry.cname
3193 self.body.analyse_declarations(cenv)
3195 def analyse_expressions(self, env):
3196 if self.py3_style_class:
3197 self.bases.analyse_expressions(env)
3198 self.metaclass.analyse_expressions(env)
3199 self.mkw.analyse_expressions(env)
3200 self.dict.analyse_expressions(env)
3201 self.classobj.analyse_expressions(env)
3202 genv = env.global_scope()
3204 self.body.analyse_expressions(cenv)
3205 self.target.analyse_target_expression(env, self.classobj)
3207 def generate_function_definitions(self, env, code):
3208 self.generate_lambda_definitions(self.scope, code)
3209 self.body.generate_function_definitions(self.scope, code)
3211 def generate_execution_code(self, code):
3212 code.pyclass_stack.append(self)
3214 if self.py3_style_class:
3215 self.bases.generate_evaluation_code(code)
3216 self.mkw.generate_evaluation_code(code)
3217 self.metaclass.generate_evaluation_code(code)
3218 self.dict.generate_evaluation_code(code)
3219 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3220 self.body.generate_execution_code(code)
3221 self.classobj.generate_evaluation_code(code)
3222 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3223 self.target.generate_assignment_code(self.classobj, code)
3224 self.dict.generate_disposal_code(code)
3225 self.dict.free_temps(code)
3226 if self.py3_style_class:
3227 self.mkw.generate_disposal_code(code)
3228 self.mkw.free_temps(code)
3229 self.metaclass.generate_disposal_code(code)
3230 self.metaclass.free_temps(code)
3231 self.bases.generate_disposal_code(code)
3232 self.bases.free_temps(code)
3233 code.pyclass_stack.pop()
3235 class CClassDefNode(ClassDefNode):
3236 # An extension type definition.
3238 # visibility 'private' or 'public' or 'extern'
3239 # typedef_flag boolean
3241 # module_name string or None For import of extern type objects
3242 # class_name string Unqualified name of class
3243 # as_name string or None Name to declare as in this scope
3244 # base_class_module string or None Module containing the base class
3245 # base_class_name string or None Name of the base class
3246 # objstruct_name string or None Specified C name of object struct
3247 # typeobj_name string or None Specified C name of type object
3248 # in_pxd boolean Is in a .pxd file
3249 # decorators [DecoratorNode] list of decorators or None
3250 # doc string or None
3251 # body StatNode or None
3252 # entry Symtab.Entry
3253 # base_type PyExtensionType or None
3254 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3255 # buffer_defaults_pos
3257 child_attrs = ["body"]
3258 buffer_defaults_node = None
3259 buffer_defaults_pos = None
3260 typedef_flag = False
3262 objstruct_name = None
3266 def analyse_declarations(self, env):
3267 #print "CClassDefNode.analyse_declarations:", self.class_name
3268 #print "...visibility =", self.visibility
3269 #print "...module_name =", self.module_name
3272 if self.buffer_defaults_node:
3273 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3274 env, [], self.buffer_defaults_node,
3275 need_complete=False)
3277 buffer_defaults = None
3279 if env.in_cinclude and not self.objstruct_name:
3280 error(self.pos, "Object struct name specification required for "
3281 "C class defined in 'extern from' block")
3282 self.base_type = None
3283 # Now that module imports are cached, we need to
3284 # import the modules for extern classes.
3285 if self.module_name:
3287 for module in env.cimported_modules:
3288 if module.name == self.module_name:
3289 self.module = module
3290 if self.module is None:
3291 self.module = ModuleScope(self.module_name, None, env.context)
3292 self.module.has_extern_class = 1
3293 env.add_imported_module(self.module)
3295 if self.base_class_name:
3296 if self.base_class_module:
3297 base_class_scope = env.find_module(self.base_class_module, self.pos)
3299 base_class_scope = env
3300 if self.base_class_name == 'object':
3301 # extension classes are special and don't need to inherit from object
3302 if base_class_scope is None or base_class_scope.lookup('object') is None:
3303 self.base_class_name = None
3304 self.base_class_module = None
3305 base_class_scope = None
3306 if base_class_scope:
3307 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3308 if base_class_entry:
3309 if not base_class_entry.is_type:
3310 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3311 elif not base_class_entry.type.is_extension_type and \
3312 not (base_class_entry.type.is_builtin_type and \
3313 base_class_entry.type.objstruct_cname):
3314 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3315 elif not base_class_entry.type.is_complete():
3316 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3317 self.base_class_name, self.class_name))
3318 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3319 base_class_entry.type.scope.directives['final']:
3320 error(self.pos, "Base class '%s' of type '%s' is final" % (
3321 self.base_class_name, self.class_name))
3322 elif base_class_entry.type.is_builtin_type and \
3323 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3324 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3325 % base_class_entry.type.name)
3327 self.base_type = base_class_entry.type
3328 has_body = self.body is not None
3329 if self.module_name and self.visibility != 'extern':
3330 module_path = self.module_name.split(".")
3331 home_scope = env.find_imported_module(module_path, self.pos)
3337 if self.visibility == 'extern':
3338 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3339 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3341 self.entry = home_scope.declare_c_class(
3342 name = self.class_name,
3344 defining = has_body and self.in_pxd,
3345 implementing = has_body and not self.in_pxd,
3346 module_name = self.module_name,
3347 base_type = self.base_type,
3348 objstruct_cname = self.objstruct_name,
3349 typeobj_cname = self.typeobj_name,
3350 visibility = self.visibility,
3351 typedef_flag = self.typedef_flag,
3353 buffer_defaults = buffer_defaults)
3354 if home_scope is not env and self.visibility == 'extern':
3355 env.add_imported_entry(self.class_name, self.entry, self.pos)
3356 self.scope = scope = self.entry.type.scope
3357 if scope is not None:
3358 scope.directives = env.directives
3360 if self.doc and Options.docstrings:
3361 scope.doc = embed_position(self.pos, self.doc)
3364 self.body.analyse_declarations(scope)
3368 scope.implemented = 1
3369 env.allocate_vtable_names(self.entry)
3371 def analyse_expressions(self, env):
3373 scope = self.entry.type.scope
3374 self.body.analyse_expressions(scope)
3376 def generate_function_definitions(self, env, code):
3378 self.generate_lambda_definitions(self.scope, code)
3379 self.body.generate_function_definitions(self.scope, code)
3381 def generate_execution_code(self, code):
3382 # This is needed to generate evaluation code for
3383 # default values of method arguments.
3385 self.body.generate_execution_code(code)
3387 def annotate(self, code):
3389 self.body.annotate(code)
3392 class PropertyNode(StatNode):
3393 # Definition of a property in an extension type.
3396 # doc EncodedString or None Doc string
3399 child_attrs = ["body"]
3401 def analyse_declarations(self, env):
3402 entry = env.declare_property(self.name, self.doc, self.pos)
3404 entry.scope.directives = env.directives
3405 self.body.analyse_declarations(entry.scope)
3407 def analyse_expressions(self, env):
3408 self.body.analyse_expressions(env)
3410 def generate_function_definitions(self, env, code):
3411 self.body.generate_function_definitions(env, code)
3413 def generate_execution_code(self, code):
3416 def annotate(self, code):
3417 self.body.annotate(code)
3420 class GlobalNode(StatNode):
3421 # Global variable declaration.
3427 def analyse_declarations(self, env):
3428 for name in self.names:
3429 env.declare_global(name, self.pos)
3431 def analyse_expressions(self, env):
3434 def generate_execution_code(self, code):
3438 class NonlocalNode(StatNode):
3439 # Nonlocal variable declaration via the 'nonlocal' keyword.
3445 def analyse_declarations(self, env):
3446 for name in self.names:
3447 env.declare_nonlocal(name, self.pos)
3449 def analyse_expressions(self, env):
3452 def generate_execution_code(self, code):
3456 class ExprStatNode(StatNode):
3457 # Expression used as a statement.
3461 child_attrs = ["expr"]
3463 def analyse_declarations(self, env):
3465 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3466 func = self.expr.function.as_cython_attribute()
3467 if func == u'declare':
3468 args, kwds = self.expr.explicit_args_kwds()
3470 error(self.expr.pos, "Variable names must be specified.")
3471 for var, type_node in kwds.key_value_pairs:
3472 type = type_node.analyse_as_type(env)
3474 error(type_node.pos, "Unknown type")
3476 env.declare_var(var.value, type, var.pos, is_cdef = True)
3477 self.__class__ = PassStatNode
3479 def analyse_expressions(self, env):
3480 self.expr.result_is_used = False # hint that .result() may safely be left empty
3481 self.expr.analyse_expressions(env)
3483 def nogil_check(self, env):
3484 if self.expr.type.is_pyobject and self.expr.is_temp:
3487 gil_message = "Discarding owned Python object"
3489 def generate_execution_code(self, code):
3490 self.expr.generate_evaluation_code(code)
3491 if not self.expr.is_temp and self.expr.result():
3492 code.putln("%s;" % self.expr.result())
3493 self.expr.generate_disposal_code(code)
3494 self.expr.free_temps(code)
3496 def generate_function_definitions(self, env, code):
3497 self.expr.generate_function_definitions(env, code)
3499 def annotate(self, code):
3500 self.expr.annotate(code)
3503 class AssignmentNode(StatNode):
3504 # Abstract base class for assignment nodes.
3506 # The analyse_expressions and generate_execution_code
3507 # phases of assignments are split into two sub-phases
3508 # each, to enable all the right hand sides of a
3509 # parallel assignment to be evaluated before assigning
3510 # to any of the left hand sides.
3512 def analyse_expressions(self, env):
3513 self.analyse_types(env)
3515 # def analyse_expressions(self, env):
3516 # self.analyse_expressions_1(env)
3517 # self.analyse_expressions_2(env)
3519 def generate_execution_code(self, code):
3520 self.generate_rhs_evaluation_code(code)
3521 self.generate_assignment_code(code)
3524 class SingleAssignmentNode(AssignmentNode):
3525 # The simplest case:
3529 # lhs ExprNode Left hand side
3530 # rhs ExprNode Right hand side
3531 # first bool Is this guaranteed the first assignment to lhs?
3533 child_attrs = ["lhs", "rhs"]
3535 declaration_only = False
3537 def analyse_declarations(self, env):
3540 # handle declarations of the form x = cython.foo()
3541 if isinstance(self.rhs, ExprNodes.CallNode):
3542 func_name = self.rhs.function.as_cython_attribute()
3544 args, kwds = self.rhs.explicit_args_kwds()
3546 if func_name in ['declare', 'typedef']:
3547 if len(args) > 2 or kwds is not None:
3548 error(self.rhs.pos, "Can only declare one type at a time.")
3550 type = args[0].analyse_as_type(env)
3552 error(args[0].pos, "Unknown type")
3555 if func_name == 'declare':
3556 if isinstance(lhs, ExprNodes.NameNode):
3557 vars = [(lhs.name, lhs.pos)]
3558 elif isinstance(lhs, ExprNodes.TupleNode):
3559 vars = [(var.name, var.pos) for var in lhs.args]
3561 error(lhs.pos, "Invalid declaration")
3563 for var, pos in vars:
3564 env.declare_var(var, type, pos, is_cdef = True)
3569 self.declaration_only = True
3571 self.declaration_only = True
3572 if not isinstance(lhs, ExprNodes.NameNode):
3573 error(lhs.pos, "Invalid declaration.")
3574 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3576 elif func_name in ['struct', 'union']:
3577 self.declaration_only = True
3578 if len(args) > 0 or kwds is None:
3579 error(self.rhs.pos, "Struct or union members must be given by name.")
3582 for member, type_node in kwds.key_value_pairs:
3583 type = type_node.analyse_as_type(env)
3585 error(type_node.pos, "Unknown type")
3587 members.append((member.value, type, member.pos))
3588 if len(members) < len(kwds.key_value_pairs):
3590 if not isinstance(self.lhs, ExprNodes.NameNode):
3591 error(self.lhs.pos, "Invalid declaration.")
3592 name = self.lhs.name
3593 scope = StructOrUnionScope(name)
3594 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3595 for member, type, pos in members:
3596 scope.declare_var(member, type, pos)
3598 if self.declaration_only:
3601 self.lhs.analyse_target_declaration(env)
3603 def analyse_types(self, env, use_temp = 0):
3604 self.rhs.analyse_types(env)
3605 self.lhs.analyse_target_types(env)
3606 self.lhs.gil_assignment_check(env)
3607 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3609 self.rhs = self.rhs.coerce_to_temp(env)
3611 def generate_rhs_evaluation_code(self, code):
3612 self.rhs.generate_evaluation_code(code)
3614 def generate_assignment_code(self, code):
3615 self.lhs.generate_assignment_code(self.rhs, code)
3617 def generate_function_definitions(self, env, code):
3618 self.rhs.generate_function_definitions(env, code)
3620 def annotate(self, code):
3621 self.lhs.annotate(code)
3622 self.rhs.annotate(code)
3625 class CascadedAssignmentNode(AssignmentNode):
3626 # An assignment with multiple left hand sides:
3630 # lhs_list [ExprNode] Left hand sides
3631 # rhs ExprNode Right hand sides
3635 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3637 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3638 coerced_rhs_list = None
3640 def analyse_declarations(self, env):
3641 for lhs in self.lhs_list:
3642 lhs.analyse_target_declaration(env)
3644 def analyse_types(self, env, use_temp = 0):
3645 self.rhs.analyse_types(env)
3646 if not self.rhs.is_simple():
3648 self.rhs = self.rhs.coerce_to_temp(env)
3650 self.rhs = self.rhs.coerce_to_simple(env)
3651 from ExprNodes import CloneNode
3652 self.coerced_rhs_list = []
3653 for lhs in self.lhs_list:
3654 lhs.analyse_target_types(env)
3655 lhs.gil_assignment_check(env)
3656 rhs = CloneNode(self.rhs)
3657 rhs = rhs.coerce_to(lhs.type, env)
3658 self.coerced_rhs_list.append(rhs)
3660 def generate_rhs_evaluation_code(self, code):
3661 self.rhs.generate_evaluation_code(code)
3663 def generate_assignment_code(self, code):
3664 for i in range(len(self.lhs_list)):
3665 lhs = self.lhs_list[i]
3666 rhs = self.coerced_rhs_list[i]
3667 rhs.generate_evaluation_code(code)
3668 lhs.generate_assignment_code(rhs, code)
3669 # Assignment has disposed of the cloned RHS
3670 self.rhs.generate_disposal_code(code)
3671 self.rhs.free_temps(code)
3673 def generate_function_definitions(self, env, code):
3674 self.rhs.generate_function_definitions(env, code)
3676 def annotate(self, code):
3677 for i in range(len(self.lhs_list)):
3678 lhs = self.lhs_list[i].annotate(code)
3679 rhs = self.coerced_rhs_list[i].annotate(code)
3680 self.rhs.annotate(code)
3683 class ParallelAssignmentNode(AssignmentNode):
3684 # A combined packing/unpacking assignment:
3688 # This has been rearranged by the parser into
3690 # a = d ; b = e ; c = f
3692 # but we must evaluate all the right hand sides
3693 # before assigning to any of the left hand sides.
3695 # stats [AssignmentNode] The constituent assignments
3697 child_attrs = ["stats"]
3699 def analyse_declarations(self, env):
3700 for stat in self.stats:
3701 stat.analyse_declarations(env)
3703 def analyse_expressions(self, env):
3704 for stat in self.stats:
3705 stat.analyse_types(env, use_temp = 1)
3707 # def analyse_expressions(self, env):
3708 # for stat in self.stats:
3709 # stat.analyse_expressions_1(env, use_temp = 1)
3710 # for stat in self.stats:
3711 # stat.analyse_expressions_2(env)
3713 def generate_execution_code(self, code):
3714 for stat in self.stats:
3715 stat.generate_rhs_evaluation_code(code)
3716 for stat in self.stats:
3717 stat.generate_assignment_code(code)
3719 def generate_function_definitions(self, env, code):
3720 for stat in self.stats:
3721 stat.generate_function_definitions(env, code)
3723 def annotate(self, code):
3724 for stat in self.stats:
3728 class InPlaceAssignmentNode(AssignmentNode):
3729 # An in place arithmetic operand:
3735 # lhs ExprNode Left hand side
3736 # rhs ExprNode Right hand side
3737 # op char one of "+-*/%^&|"
3738 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3740 # This code is a bit tricky because in order to obey Python
3741 # semantics the sub-expressions (e.g. indices) of the lhs must
3742 # not be evaluated twice. So we must re-use the values calculated
3743 # in evaluation phase for the assignment phase as well.
3744 # Fortunately, the type of the lhs node is fairly constrained
3745 # (it must be a NameNode, AttributeNode, or IndexNode).
3747 child_attrs = ["lhs", "rhs"]
3749 def analyse_declarations(self, env):
3750 self.lhs.analyse_target_declaration(env)
3752 def analyse_types(self, env):
3753 self.rhs.analyse_types(env)
3754 self.lhs.analyse_target_types(env)
3756 def generate_execution_code(self, code):
3758 self.rhs.generate_evaluation_code(code)
3759 self.lhs.generate_subexpr_evaluation_code(code)
3760 c_op = self.operator
3764 error(self.pos, "No C inplace power operator")
3765 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3766 if self.lhs.type.is_pyobject:
3767 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3768 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3769 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3770 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3773 # TODO: make sure overload is declared
3774 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3775 self.lhs.generate_subexpr_disposal_code(code)
3776 self.lhs.free_subexpr_temps(code)
3777 self.rhs.generate_disposal_code(code)
3778 self.rhs.free_temps(code)
3780 def annotate(self, code):
3781 self.lhs.annotate(code)
3782 self.rhs.annotate(code)
3784 def create_binop_node(self):
3786 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3789 class PrintStatNode(StatNode):
3792 # arg_tuple TupleNode
3793 # stream ExprNode or None (stdout)
3794 # append_newline boolean
3796 child_attrs = ["arg_tuple", "stream"]
3798 def analyse_expressions(self, env):
3800 self.stream.analyse_expressions(env)
3801 self.stream = self.stream.coerce_to_pyobject(env)
3802 self.arg_tuple.analyse_expressions(env)
3803 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3804 env.use_utility_code(printing_utility_code)
3805 if len(self.arg_tuple.args) == 1 and self.append_newline:
3806 env.use_utility_code(printing_one_utility_code)
3808 nogil_check = Node.gil_error
3809 gil_message = "Python print statement"
3811 def generate_execution_code(self, code):
3813 self.stream.generate_evaluation_code(code)
3814 stream_result = self.stream.py_result()
3817 if len(self.arg_tuple.args) == 1 and self.append_newline:
3818 arg = self.arg_tuple.args[0]
3819 arg.generate_evaluation_code(code)
3822 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3825 code.error_goto(self.pos)))
3826 arg.generate_disposal_code(code)
3827 arg.free_temps(code)
3829 self.arg_tuple.generate_evaluation_code(code)
3831 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3833 self.arg_tuple.py_result(),
3834 self.append_newline,
3835 code.error_goto(self.pos)))
3836 self.arg_tuple.generate_disposal_code(code)
3837 self.arg_tuple.free_temps(code)
3840 self.stream.generate_disposal_code(code)
3841 self.stream.free_temps(code)
3843 def generate_function_definitions(self, env, code):
3845 self.stream.generate_function_definitions(env, code)
3846 self.arg_tuple.generate_function_definitions(env, code)
3848 def annotate(self, code):
3850 self.stream.annotate(code)
3851 self.arg_tuple.annotate(code)
3854 class ExecStatNode(StatNode):
3859 child_attrs = ["args"]
3861 def analyse_expressions(self, env):
3862 for i, arg in enumerate(self.args):
3863 arg.analyse_expressions(env)
3864 arg = arg.coerce_to_pyobject(env)
3866 env.use_utility_code(Builtin.pyexec_utility_code)
3868 nogil_check = Node.gil_error
3869 gil_message = "Python exec statement"
3871 def generate_execution_code(self, code):
3873 for arg in self.args:
3874 arg.generate_evaluation_code(code)
3875 args.append( arg.py_result() )
3876 args = tuple(args + ['0', '0'][:3-len(args)])
3877 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3878 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3879 (temp_result,) + args))
3880 for arg in self.args:
3881 arg.generate_disposal_code(code)
3882 arg.free_temps(code)
3884 code.error_goto_if_null(temp_result, self.pos))
3885 code.put_gotref(temp_result)
3886 code.put_decref_clear(temp_result, py_object_type)
3887 code.funcstate.release_temp(temp_result)
3889 def annotate(self, code):
3890 for arg in self.args:
3894 class DelStatNode(StatNode):
3899 child_attrs = ["args"]
3901 def analyse_declarations(self, env):
3902 for arg in self.args:
3903 arg.analyse_target_declaration(env)
3905 def analyse_expressions(self, env):
3906 for arg in self.args:
3907 arg.analyse_target_expression(env, None)
3908 if arg.type.is_pyobject:
3910 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3912 elif arg.type.is_cpp_class:
3913 error(arg.pos, "Deletion of non-heap C++ object")
3915 error(arg.pos, "Deletion of non-Python, non-C++ object")
3916 #arg.release_target_temp(env)
3918 def nogil_check(self, env):
3919 for arg in self.args:
3920 if arg.type.is_pyobject:
3923 gil_message = "Deleting Python object"
3925 def generate_execution_code(self, code):
3926 for arg in self.args:
3927 if arg.type.is_pyobject:
3928 arg.generate_deletion_code(code)
3929 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3930 arg.generate_result_code(code)
3931 code.putln("delete %s;" % arg.result())
3932 # else error reported earlier
3934 def annotate(self, code):
3935 for arg in self.args:
3939 class PassStatNode(StatNode):
3944 def analyse_expressions(self, env):
3947 def generate_execution_code(self, code):
3951 class BreakStatNode(StatNode):
3955 def analyse_expressions(self, env):
3958 def generate_execution_code(self, code):
3959 if not code.break_label:
3960 error(self.pos, "break statement not inside loop")
3962 code.put_goto(code.break_label)
3965 class ContinueStatNode(StatNode):
3969 def analyse_expressions(self, env):
3972 def generate_execution_code(self, code):
3973 if code.funcstate.in_try_finally:
3974 error(self.pos, "continue statement inside try of try...finally")
3975 elif not code.continue_label:
3976 error(self.pos, "continue statement not inside loop")
3978 code.put_goto(code.continue_label)
3981 class ReturnStatNode(StatNode):
3984 # value ExprNode or None
3985 # return_type PyrexType
3987 child_attrs = ["value"]
3989 def analyse_expressions(self, env):
3990 return_type = env.return_type
3991 self.return_type = return_type
3993 error(self.pos, "Return not inside a function body")
3996 self.value.analyse_types(env)
3997 if return_type.is_void or return_type.is_returncode:
3998 error(self.value.pos,
3999 "Return with value in void function")
4001 self.value = self.value.coerce_to(env.return_type, env)
4003 if (not return_type.is_void
4004 and not return_type.is_pyobject
4005 and not return_type.is_returncode):
4006 error(self.pos, "Return value required")
4008 def nogil_check(self, env):
4009 if self.return_type.is_pyobject:
4012 gil_message = "Returning Python object"
4014 def generate_execution_code(self, code):
4015 code.mark_pos(self.pos)
4016 if not self.return_type:
4017 # error reported earlier
4019 if self.return_type.is_pyobject:
4020 code.put_xdecref(Naming.retval_cname,
4023 self.value.generate_evaluation_code(code)
4024 self.value.make_owned_reference(code)
4027 Naming.retval_cname,
4028 self.value.result_as(self.return_type)))
4029 self.value.generate_post_assignment_code(code)
4030 self.value.free_temps(code)
4032 if self.return_type.is_pyobject:
4033 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
4034 elif self.return_type.is_returncode:
4037 Naming.retval_cname,
4038 self.return_type.default_value))
4039 for cname, type in code.funcstate.temps_holding_reference():
4040 code.put_decref_clear(cname, type)
4041 code.put_goto(code.return_label)
4043 def generate_function_definitions(self, env, code):
4044 if self.value is not None:
4045 self.value.generate_function_definitions(env, code)
4047 def annotate(self, code):
4049 self.value.annotate(code)
4052 class RaiseStatNode(StatNode):
4055 # exc_type ExprNode or None
4056 # exc_value ExprNode or None
4057 # exc_tb ExprNode or None
4059 child_attrs = ["exc_type", "exc_value", "exc_tb"]
4061 def analyse_expressions(self, env):
4063 self.exc_type.analyse_types(env)
4064 self.exc_type = self.exc_type.coerce_to_pyobject(env)
4066 self.exc_value.analyse_types(env)
4067 self.exc_value = self.exc_value.coerce_to_pyobject(env)
4069 self.exc_tb.analyse_types(env)
4070 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
4071 env.use_utility_code(raise_utility_code)
4073 nogil_check = Node.gil_error
4074 gil_message = "Raising exception"
4076 def generate_execution_code(self, code):
4078 self.exc_type.generate_evaluation_code(code)
4079 type_code = self.exc_type.py_result()
4083 self.exc_value.generate_evaluation_code(code)
4084 value_code = self.exc_value.py_result()
4088 self.exc_tb.generate_evaluation_code(code)
4089 tb_code = self.exc_tb.py_result()
4093 "__Pyx_Raise(%s, %s, %s);" % (
4097 for obj in (self.exc_type, self.exc_value, self.exc_tb):
4099 obj.generate_disposal_code(code)
4100 obj.free_temps(code)
4102 code.error_goto(self.pos))
4104 def generate_function_definitions(self, env, code):
4105 if self.exc_type is not None:
4106 self.exc_type.generate_function_definitions(env, code)
4107 if self.exc_value is not None:
4108 self.exc_value.generate_function_definitions(env, code)
4109 if self.exc_tb is not None:
4110 self.exc_tb.generate_function_definitions(env, code)
4112 def annotate(self, code):
4114 self.exc_type.annotate(code)
4116 self.exc_value.annotate(code)
4118 self.exc_tb.annotate(code)
4121 class ReraiseStatNode(StatNode):
4125 def analyse_expressions(self, env):
4126 env.use_utility_code(restore_exception_utility_code)
4128 nogil_check = Node.gil_error
4129 gil_message = "Raising exception"
4131 def generate_execution_code(self, code):
4132 vars = code.funcstate.exc_vars
4134 for varname in vars:
4135 code.put_giveref(varname)
4136 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4137 for varname in vars:
4138 code.put("%s = 0; " % varname)
4140 code.putln(code.error_goto(self.pos))
4142 error(self.pos, "Reraise not inside except clause")
4145 class AssertStatNode(StatNode):
4149 # value ExprNode or None
4151 child_attrs = ["cond", "value"]
4153 def analyse_expressions(self, env):
4154 self.cond = self.cond.analyse_boolean_expression(env)
4156 self.value.analyse_types(env)
4157 self.value = self.value.coerce_to_pyobject(env)
4159 nogil_check = Node.gil_error
4160 gil_message = "Raising exception"
4162 def generate_execution_code(self, code):
4163 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4164 self.cond.generate_evaluation_code(code)
4166 "if (unlikely(!%s)) {" %
4169 self.value.generate_evaluation_code(code)
4171 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4172 self.value.py_result())
4173 self.value.generate_disposal_code(code)
4174 self.value.free_temps(code)
4177 "PyErr_SetNone(PyExc_AssertionError);")
4179 code.error_goto(self.pos))
4182 self.cond.generate_disposal_code(code)
4183 self.cond.free_temps(code)
4184 code.putln("#endif")
4186 def generate_function_definitions(self, env, code):
4187 self.cond.generate_function_definitions(env, code)
4188 if self.value is not None:
4189 self.value.generate_function_definitions(env, code)
4191 def annotate(self, code):
4192 self.cond.annotate(code)
4194 self.value.annotate(code)
4197 class IfStatNode(StatNode):
4200 # if_clauses [IfClauseNode]
4201 # else_clause StatNode or None
4203 child_attrs = ["if_clauses", "else_clause"]
4205 def analyse_control_flow(self, env):
4206 env.start_branching(self.pos)
4207 for if_clause in self.if_clauses:
4208 if_clause.analyse_control_flow(env)
4209 env.next_branch(if_clause.end_pos())
4210 if self.else_clause:
4211 self.else_clause.analyse_control_flow(env)
4212 env.finish_branching(self.end_pos())
4214 def analyse_declarations(self, env):
4215 for if_clause in self.if_clauses:
4216 if_clause.analyse_declarations(env)
4217 if self.else_clause:
4218 self.else_clause.analyse_declarations(env)
4220 def analyse_expressions(self, env):
4221 for if_clause in self.if_clauses:
4222 if_clause.analyse_expressions(env)
4223 if self.else_clause:
4224 self.else_clause.analyse_expressions(env)
4226 def generate_execution_code(self, code):
4227 code.mark_pos(self.pos)
4228 end_label = code.new_label()
4229 for if_clause in self.if_clauses:
4230 if_clause.generate_execution_code(code, end_label)
4231 if self.else_clause:
4232 code.putln("/*else*/ {")
4233 self.else_clause.generate_execution_code(code)
4235 code.put_label(end_label)
4237 def generate_function_definitions(self, env, code):
4238 for clause in self.if_clauses:
4239 clause.generate_function_definitions(env, code)
4240 if self.else_clause is not None:
4241 self.else_clause.generate_function_definitions(env, code)
4243 def annotate(self, code):
4244 for if_clause in self.if_clauses:
4245 if_clause.annotate(code)
4246 if self.else_clause:
4247 self.else_clause.annotate(code)
4250 class IfClauseNode(Node):
4251 # if or elif clause in an if statement
4253 # condition ExprNode
4256 child_attrs = ["condition", "body"]
4258 def analyse_control_flow(self, env):
4259 self.body.analyse_control_flow(env)
4261 def analyse_declarations(self, env):
4262 self.body.analyse_declarations(env)
4264 def analyse_expressions(self, env):
4266 self.condition.analyse_temp_boolean_expression(env)
4267 self.body.analyse_expressions(env)
4269 def get_constant_condition_result(self):
4270 if self.condition.has_constant_result():
4271 return bool(self.condition.constant_result)
4275 def generate_execution_code(self, code, end_label):
4276 self.condition.generate_evaluation_code(code)
4279 self.condition.result())
4280 self.condition.generate_disposal_code(code)
4281 self.condition.free_temps(code)
4282 self.body.generate_execution_code(code)
4283 code.put_goto(end_label)
4286 def generate_function_definitions(self, env, code):
4287 self.condition.generate_function_definitions(env, code)
4288 self.body.generate_function_definitions(env, code)
4290 def annotate(self, code):
4291 self.condition.annotate(code)
4292 self.body.annotate(code)
4295 class SwitchCaseNode(StatNode):
4296 # Generated in the optimization of an if-elif-else node
4298 # conditions [ExprNode]
4301 child_attrs = ['conditions', 'body']
4303 def generate_execution_code(self, code):
4304 for cond in self.conditions:
4305 code.mark_pos(cond.pos)
4306 cond.generate_evaluation_code(code)
4307 code.putln("case %s:" % cond.result())
4308 self.body.generate_execution_code(code)
4309 code.putln("break;")
4311 def generate_function_definitions(self, env, code):
4312 for cond in self.conditions:
4313 cond.generate_function_definitions(env, code)
4314 self.body.generate_function_definitions(env, code)
4316 def annotate(self, code):
4317 for cond in self.conditions:
4319 self.body.annotate(code)
4321 class SwitchStatNode(StatNode):
4322 # Generated in the optimization of an if-elif-else node
4325 # cases [SwitchCaseNode]
4326 # else_clause StatNode or None
4328 child_attrs = ['test', 'cases', 'else_clause']
4330 def generate_execution_code(self, code):
4331 self.test.generate_evaluation_code(code)
4332 code.putln("switch (%s) {" % self.test.result())
4333 for case in self.cases:
4334 case.generate_execution_code(code)
4335 if self.else_clause is not None:
4336 code.putln("default:")
4337 self.else_clause.generate_execution_code(code)
4338 code.putln("break;")
4341 def generate_function_definitions(self, env, code):
4342 self.test.generate_function_definitions(env, code)
4343 for case in self.cases:
4344 case.generate_function_definitions(env, code)
4345 if self.else_clause is not None:
4346 self.else_clause.generate_function_definitions(env, code)
4348 def annotate(self, code):
4349 self.test.annotate(code)
4350 for case in self.cases:
4352 if self.else_clause is not None:
4353 self.else_clause.annotate(code)
4355 class LoopNode(object):
4357 def analyse_control_flow(self, env):
4358 env.start_branching(self.pos)
4359 self.body.analyse_control_flow(env)
4360 env.next_branch(self.body.end_pos())
4361 if self.else_clause:
4362 self.else_clause.analyse_control_flow(env)
4363 env.finish_branching(self.end_pos())
4366 class WhileStatNode(LoopNode, StatNode):
4369 # condition ExprNode
4371 # else_clause StatNode
4373 child_attrs = ["condition", "body", "else_clause"]
4375 def analyse_declarations(self, env):
4376 self.body.analyse_declarations(env)
4377 if self.else_clause:
4378 self.else_clause.analyse_declarations(env)
4380 def analyse_expressions(self, env):
4382 self.condition.analyse_temp_boolean_expression(env)
4383 self.body.analyse_expressions(env)
4384 if self.else_clause:
4385 self.else_clause.analyse_expressions(env)
4387 def generate_execution_code(self, code):
4388 old_loop_labels = code.new_loop_labels()
4391 self.condition.generate_evaluation_code(code)
4392 self.condition.generate_disposal_code(code)
4395 self.condition.result())
4396 self.condition.free_temps(code)
4397 self.body.generate_execution_code(code)
4398 code.put_label(code.continue_label)
4400 break_label = code.break_label
4401 code.set_loop_labels(old_loop_labels)
4402 if self.else_clause:
4403 code.putln("/*else*/ {")
4404 self.else_clause.generate_execution_code(code)
4406 code.put_label(break_label)
4408 def generate_function_definitions(self, env, code):
4409 self.condition.generate_function_definitions(env, code)
4410 self.body.generate_function_definitions(env, code)
4411 if self.else_clause is not None:
4412 self.else_clause.generate_function_definitions(env, code)
4414 def annotate(self, code):
4415 self.condition.annotate(code)
4416 self.body.annotate(code)
4417 if self.else_clause:
4418 self.else_clause.annotate(code)
4421 def ForStatNode(pos, **kw):
4422 if 'iterator' in kw:
4423 return ForInStatNode(pos, **kw)
4425 return ForFromStatNode(pos, **kw)
4427 class ForInStatNode(LoopNode, StatNode):
4431 # iterator IteratorNode
4433 # else_clause StatNode
4434 # item NextNode used internally
4436 child_attrs = ["target", "iterator", "body", "else_clause"]
4439 def analyse_declarations(self, env):
4440 self.target.analyse_target_declaration(env)
4441 self.body.analyse_declarations(env)
4442 if self.else_clause:
4443 self.else_clause.analyse_declarations(env)
4445 def analyse_expressions(self, env):
4447 self.target.analyse_target_types(env)
4448 self.iterator.analyse_expressions(env)
4449 self.item = ExprNodes.NextNode(self.iterator, env)
4450 self.item = self.item.coerce_to(self.target.type, env)
4451 self.body.analyse_expressions(env)
4452 if self.else_clause:
4453 self.else_clause.analyse_expressions(env)
4455 def generate_execution_code(self, code):
4456 old_loop_labels = code.new_loop_labels()
4457 self.iterator.allocate_counter_temp(code)
4458 self.iterator.generate_evaluation_code(code)
4461 self.item.generate_evaluation_code(code)
4462 self.target.generate_assignment_code(self.item, code)
4463 self.body.generate_execution_code(code)
4464 code.put_label(code.continue_label)
4467 break_label = code.break_label
4468 code.set_loop_labels(old_loop_labels)
4470 if self.else_clause:
4471 # in nested loops, the 'else' block can contain a
4472 # 'continue' statement for the outer loop, but we may need
4473 # to generate cleanup code before taking that path, so we
4475 orig_continue_label = code.continue_label
4476 code.continue_label = code.new_label('outer_continue')
4478 code.putln("/*else*/ {")
4479 self.else_clause.generate_execution_code(code)
4482 if code.label_used(code.continue_label):
4483 code.put_goto(break_label)
4484 code.put_label(code.continue_label)
4485 self.iterator.generate_disposal_code(code)
4486 code.put_goto(orig_continue_label)
4487 code.set_loop_labels(old_loop_labels)
4489 if code.label_used(break_label):
4490 code.put_label(break_label)
4491 self.iterator.release_counter_temp(code)
4492 self.iterator.generate_disposal_code(code)
4493 self.iterator.free_temps(code)
4495 def generate_function_definitions(self, env, code):
4496 self.target.generate_function_definitions(env, code)
4497 self.iterator.generate_function_definitions(env, code)
4498 self.body.generate_function_definitions(env, code)
4499 if self.else_clause is not None:
4500 self.else_clause.generate_function_definitions(env, code)
4502 def annotate(self, code):
4503 self.target.annotate(code)
4504 self.iterator.annotate(code)
4505 self.body.annotate(code)
4506 if self.else_clause:
4507 self.else_clause.annotate(code)
4508 self.item.annotate(code)
4511 class ForFromStatNode(LoopNode, StatNode):
4512 # for name from expr rel name rel expr
4519 # step ExprNode or None
4521 # else_clause StatNode or None
4527 # loopvar_node ExprNode (usually a NameNode or temp node)
4528 # py_loopvar_node PyTempNode or None
4529 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4531 is_py_target = False
4533 py_loopvar_node = None
4536 gil_message = "For-loop using object bounds or target"
4538 def nogil_check(self, env):
4539 for x in (self.target, self.bound1, self.bound2):
4540 if x.type.is_pyobject:
4543 def analyse_declarations(self, env):
4544 self.target.analyse_target_declaration(env)
4545 self.body.analyse_declarations(env)
4546 if self.else_clause:
4547 self.else_clause.analyse_declarations(env)
4549 def analyse_expressions(self, env):
4551 self.target.analyse_target_types(env)
4552 self.bound1.analyse_types(env)
4553 self.bound2.analyse_types(env)
4554 if self.step is not None:
4555 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4556 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4557 self.step.analyse_types(env)
4559 target_type = self.target.type
4560 if self.target.type.is_numeric:
4561 loop_type = self.target.type
4563 loop_type = PyrexTypes.c_int_type
4564 if not self.bound1.type.is_pyobject:
4565 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4566 if not self.bound2.type.is_pyobject:
4567 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4568 if self.step is not None and not self.step.type.is_pyobject:
4569 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4570 self.bound1 = self.bound1.coerce_to(loop_type, env)
4571 self.bound2 = self.bound2.coerce_to(loop_type, env)
4572 if not self.bound2.is_literal:
4573 self.bound2 = self.bound2.coerce_to_temp(env)
4574 if self.step is not None:
4575 self.step = self.step.coerce_to(loop_type, env)
4576 if not self.step.is_literal:
4577 self.step = self.step.coerce_to_temp(env)
4579 target_type = self.target.type
4580 if not (target_type.is_pyobject or target_type.is_numeric):
4581 error(self.target.pos,
4582 "for-from loop variable must be c numeric type or Python object")
4583 if target_type.is_numeric:
4584 self.is_py_target = False
4585 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4586 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4587 self.loopvar_node = self.target
4588 self.py_loopvar_node = None
4590 self.is_py_target = True
4591 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4592 self.loopvar_node = c_loopvar_node
4593 self.py_loopvar_node = \
4594 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4595 self.body.analyse_expressions(env)
4596 if self.else_clause:
4597 self.else_clause.analyse_expressions(env)
4599 def generate_execution_code(self, code):
4600 old_loop_labels = code.new_loop_labels()
4601 from_range = self.from_range
4602 self.bound1.generate_evaluation_code(code)
4603 self.bound2.generate_evaluation_code(code)
4604 offset, incop = self.relation_table[self.relation1]
4605 if self.step is not None:
4606 self.step.generate_evaluation_code(code)
4607 step = self.step.result()
4608 incop = "%s=%s" % (incop[0], step)
4610 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4611 self.loopvar_node.allocate(code)
4612 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4613 self.py_loopvar_node.allocate(code)
4615 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4617 loopvar_name = self.loopvar_node.result()
4619 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4621 self.bound1.result(), offset,
4622 loopvar_name, self.relation2, self.bound2.result(),
4623 loopvar_name, incop))
4624 if self.py_loopvar_node:
4625 self.py_loopvar_node.generate_evaluation_code(code)
4626 self.target.generate_assignment_code(self.py_loopvar_node, code)
4628 code.putln("%s = %s;" % (
4629 self.target.result(), loopvar_name))
4630 self.body.generate_execution_code(code)
4631 code.put_label(code.continue_label)
4632 if self.py_loopvar_node:
4633 # This mess is to make for..from loops with python targets behave
4634 # exactly like those with C targets with regards to re-assignment
4635 # of the loop variable.
4637 if self.target.entry.is_pyglobal:
4638 # We know target is a NameNode, this is the only ugly case.
4639 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4640 target_node.allocate(code)
4641 interned_cname = code.intern_identifier(self.target.entry.name)
4642 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4643 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4644 target_node.result(),
4645 Naming.module_cname,
4647 code.error_goto_if_null(target_node.result(), self.target.pos)))
4648 code.put_gotref(target_node.result())
4650 target_node = self.target
4651 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4652 from_py_node.temp_code = loopvar_name
4653 from_py_node.generate_result_code(code)
4654 if self.target.entry.is_pyglobal:
4655 code.put_decref(target_node.result(), target_node.type)
4656 target_node.release(code)
4658 if self.py_loopvar_node:
4659 # This is potentially wasteful, but we don't want the semantics to
4660 # depend on whether or not the loop is a python type.
4661 self.py_loopvar_node.generate_evaluation_code(code)
4662 self.target.generate_assignment_code(self.py_loopvar_node, code)
4664 code.funcstate.release_temp(loopvar_name)
4665 break_label = code.break_label
4666 code.set_loop_labels(old_loop_labels)
4667 if self.else_clause:
4668 code.putln("/*else*/ {")
4669 self.else_clause.generate_execution_code(code)
4671 code.put_label(break_label)
4672 self.bound1.generate_disposal_code(code)
4673 self.bound1.free_temps(code)
4674 self.bound2.generate_disposal_code(code)
4675 self.bound2.free_temps(code)
4676 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4677 self.loopvar_node.release(code)
4678 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4679 self.py_loopvar_node.release(code)
4680 if self.step is not None:
4681 self.step.generate_disposal_code(code)
4682 self.step.free_temps(code)
4685 # {relop : (initial offset, increment op)}
4692 def generate_function_definitions(self, env, code):
4693 self.target.generate_function_definitions(env, code)
4694 self.bound1.generate_function_definitions(env, code)
4695 self.bound2.generate_function_definitions(env, code)
4696 if self.step is not None:
4697 self.step.generate_function_definitions(env, code)
4698 self.body.generate_function_definitions(env, code)
4699 if self.else_clause is not None:
4700 self.else_clause.generate_function_definitions(env, code)
4702 def annotate(self, code):
4703 self.target.annotate(code)
4704 self.bound1.annotate(code)
4705 self.bound2.annotate(code)
4707 self.step.annotate(code)
4708 self.body.annotate(code)
4709 if self.else_clause:
4710 self.else_clause.annotate(code)
4713 class WithStatNode(StatNode):
4715 Represents a Python with statement.
4717 This is only used at parse tree level; and is not present in
4718 analysis or generation phases.
4720 # manager The with statement manager object
4721 # target Node (lhs expression)
4723 child_attrs = ["manager", "target", "body"]
4725 class TryExceptStatNode(StatNode):
4726 # try .. except statement
4729 # except_clauses [ExceptClauseNode]
4730 # else_clause StatNode or None
4732 child_attrs = ["body", "except_clauses", "else_clause"]
4734 def analyse_control_flow(self, env):
4735 env.start_branching(self.pos)
4736 self.body.analyse_control_flow(env)
4737 successful_try = env.control_flow # grab this for later
4738 env.next_branch(self.body.end_pos())
4739 env.finish_branching(self.body.end_pos())
4741 env.start_branching(self.except_clauses[0].pos)
4742 for except_clause in self.except_clauses:
4743 except_clause.analyse_control_flow(env)
4744 env.next_branch(except_clause.end_pos())
4746 # the else cause it executed only when the try clause finishes
4747 env.control_flow.incoming = successful_try
4748 if self.else_clause:
4749 self.else_clause.analyse_control_flow(env)
4750 env.finish_branching(self.end_pos())
4752 def analyse_declarations(self, env):
4753 self.body.analyse_declarations(env)
4754 for except_clause in self.except_clauses:
4755 except_clause.analyse_declarations(env)
4756 if self.else_clause:
4757 self.else_clause.analyse_declarations(env)
4758 env.use_utility_code(reset_exception_utility_code)
4760 def analyse_expressions(self, env):
4761 self.body.analyse_expressions(env)
4762 default_clause_seen = 0
4763 for except_clause in self.except_clauses:
4764 except_clause.analyse_expressions(env)
4765 if default_clause_seen:
4766 error(except_clause.pos, "default 'except:' must be last")
4767 if not except_clause.pattern:
4768 default_clause_seen = 1
4769 self.has_default_clause = default_clause_seen
4770 if self.else_clause:
4771 self.else_clause.analyse_expressions(env)
4773 nogil_check = Node.gil_error
4774 gil_message = "Try-except statement"
4776 def generate_execution_code(self, code):
4777 old_return_label = code.return_label
4778 old_break_label = code.break_label
4779 old_continue_label = code.continue_label
4780 old_error_label = code.new_error_label()
4781 our_error_label = code.error_label
4782 except_end_label = code.new_label('exception_handled')
4783 except_error_label = code.new_label('except_error')
4784 except_return_label = code.new_label('except_return')
4785 try_return_label = code.new_label('try_return')
4786 try_break_label = code.new_label('try_break')
4787 try_continue_label = code.new_label('try_continue')
4788 try_end_label = code.new_label('try_end')
4790 exc_save_vars = [code.funcstate.allocate_temp(py_object_type, False)
4793 code.putln("__Pyx_ExceptionSave(%s);" %
4794 ', '.join(['&%s' % var for var in exc_save_vars]))
4795 for var in exc_save_vars:
4796 code.put_xgotref(var)
4799 code.return_label = try_return_label
4800 code.break_label = try_break_label
4801 code.continue_label = try_continue_label
4802 self.body.generate_execution_code(code)
4805 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4806 code.error_label = except_error_label
4807 code.return_label = except_return_label
4808 if self.else_clause:
4811 self.else_clause.generate_execution_code(code)
4814 for var in exc_save_vars:
4815 code.put_xdecref_clear(var, py_object_type)
4816 code.put_goto(try_end_label)
4817 if code.label_used(try_return_label):
4818 code.put_label(try_return_label)
4819 for var in exc_save_vars: code.put_xgiveref(var)
4820 code.putln("__Pyx_ExceptionReset(%s);" %
4821 ', '.join(exc_save_vars))
4822 code.put_goto(old_return_label)
4823 code.put_label(our_error_label)
4824 for temp_name, type in temps_to_clean_up:
4825 code.put_xdecref_clear(temp_name, type)
4826 for except_clause in self.except_clauses:
4827 except_clause.generate_handling_code(code, except_end_label)
4829 error_label_used = code.label_used(except_error_label)
4830 if error_label_used or not self.has_default_clause:
4831 if error_label_used:
4832 code.put_label(except_error_label)
4833 for var in exc_save_vars: code.put_xgiveref(var)
4834 code.putln("__Pyx_ExceptionReset(%s);" %
4835 ', '.join(exc_save_vars))
4836 code.put_goto(old_error_label)
4838 for exit_label, old_label in zip(
4839 [try_break_label, try_continue_label, except_return_label],
4840 [old_break_label, old_continue_label, old_return_label]):
4842 if code.label_used(exit_label):
4843 code.put_label(exit_label)
4844 for var in exc_save_vars: code.put_xgiveref(var)
4845 code.putln("__Pyx_ExceptionReset(%s);" %
4846 ', '.join(exc_save_vars))
4847 code.put_goto(old_label)
4849 if code.label_used(except_end_label):
4850 code.put_label(except_end_label)
4851 for var in exc_save_vars: code.put_xgiveref(var)
4852 code.putln("__Pyx_ExceptionReset(%s);" %
4853 ', '.join(exc_save_vars))
4854 code.put_label(try_end_label)
4857 for cname in exc_save_vars:
4858 code.funcstate.release_temp(cname)
4860 code.return_label = old_return_label
4861 code.break_label = old_break_label
4862 code.continue_label = old_continue_label
4863 code.error_label = old_error_label
4865 def generate_function_definitions(self, env, code):
4866 self.body.generate_function_definitions(env, code)
4867 for except_clause in self.except_clauses:
4868 except_clause.generate_function_definitions(env, code)
4869 if self.else_clause is not None:
4870 self.else_clause.generate_function_definitions(env, code)
4872 def annotate(self, code):
4873 self.body.annotate(code)
4874 for except_node in self.except_clauses:
4875 except_node.annotate(code)
4876 if self.else_clause:
4877 self.else_clause.annotate(code)
4880 class ExceptClauseNode(Node):
4881 # Part of try ... except statement.
4883 # pattern [ExprNode]
4884 # target ExprNode or None
4886 # excinfo_target NameNode or None optional target for exception info
4887 # match_flag string result of exception match
4888 # exc_value ExcValueNode used internally
4889 # function_name string qualified name of enclosing function
4890 # exc_vars (string * 3) local exception variables
4892 # excinfo_target is never set by the parser, but can be set by a transform
4893 # in order to extract more extensive information about the exception as a
4894 # sys.exc_info()-style tuple into a target variable
4896 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4899 excinfo_target = None
4901 def analyse_declarations(self, env):
4903 self.target.analyse_target_declaration(env)
4904 if self.excinfo_target is not None:
4905 self.excinfo_target.analyse_target_declaration(env)
4906 self.body.analyse_declarations(env)
4908 def analyse_expressions(self, env):
4910 genv = env.global_scope()
4911 self.function_name = env.qualified_name
4913 # normalise/unpack self.pattern into a list
4914 for i, pattern in enumerate(self.pattern):
4915 pattern.analyse_expressions(env)
4916 self.pattern[i] = pattern.coerce_to_pyobject(env)
4919 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4920 self.target.analyse_target_expression(env, self.exc_value)
4921 if self.excinfo_target is not None:
4923 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4924 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4925 self.excinfo_tuple.analyse_expressions(env)
4926 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4928 self.body.analyse_expressions(env)
4930 def generate_handling_code(self, code, end_label):
4931 code.mark_pos(self.pos)
4934 for pattern in self.pattern:
4935 pattern.generate_evaluation_code(code)
4936 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4938 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4940 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4941 for pattern in self.pattern:
4942 pattern.generate_disposal_code(code)
4943 pattern.free_temps(code)
4947 code.funcstate.release_temp(match_flag)
4949 code.putln("/*except:*/ {")
4951 if not getattr(self.body, 'stats', True) and \
4952 self.excinfo_target is None and self.target is None:
4953 # most simple case: no exception variable, empty body (pass)
4954 # => reset the exception state, done
4955 code.putln("PyErr_Restore(0,0,0);")
4956 code.put_goto(end_label)
4960 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4963 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4964 # We always have to fetch the exception value even if
4965 # there is no target, because this also normalises the
4966 # exception and stores it in the thread state.
4967 code.globalstate.use_utility_code(get_exception_utility_code)
4968 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4969 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4970 code.error_goto(self.pos)))
4974 self.exc_value.set_var(exc_vars[1])
4975 self.exc_value.generate_evaluation_code(code)
4976 self.target.generate_assignment_code(self.exc_value, code)
4977 if self.excinfo_target is not None:
4978 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4979 node.set_var(tempvar)
4980 self.excinfo_tuple.generate_evaluation_code(code)
4981 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4983 old_break_label, old_continue_label = code.break_label, code.continue_label
4984 code.break_label = code.new_label('except_break')
4985 code.continue_label = code.new_label('except_continue')
4987 old_exc_vars = code.funcstate.exc_vars
4988 code.funcstate.exc_vars = exc_vars
4989 self.body.generate_execution_code(code)
4990 code.funcstate.exc_vars = old_exc_vars
4991 for var in exc_vars:
4992 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4993 code.put_goto(end_label)
4995 if code.label_used(code.break_label):
4996 code.put_label(code.break_label)
4997 for var in exc_vars:
4998 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4999 code.put_goto(old_break_label)
5000 code.break_label = old_break_label
5002 if code.label_used(code.continue_label):
5003 code.put_label(code.continue_label)
5004 for var in exc_vars:
5005 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
5006 code.put_goto(old_continue_label)
5007 code.continue_label = old_continue_label
5009 for temp in exc_vars:
5010 code.funcstate.release_temp(temp)
5015 def generate_function_definitions(self, env, code):
5016 if self.target is not None:
5017 self.target.generate_function_definitions(env, code)
5018 self.body.generate_function_definitions(env, code)
5020 def annotate(self, code):
5022 for pattern in self.pattern:
5023 pattern.annotate(code)
5025 self.target.annotate(code)
5026 self.body.annotate(code)
5029 class TryFinallyStatNode(StatNode):
5030 # try ... finally statement
5033 # finally_clause StatNode
5035 # The plan is that we funnel all continue, break
5036 # return and error gotos into the beginning of the
5037 # finally block, setting a variable to remember which
5038 # one we're doing. At the end of the finally block, we
5039 # switch on the variable to figure out where to go.
5040 # In addition, if we're doing an error, we save the
5041 # exception on entry to the finally block and restore
5044 child_attrs = ["body", "finally_clause"]
5046 preserve_exception = 1
5048 disallow_continue_in_try_finally = 0
5049 # There doesn't seem to be any point in disallowing
5050 # continue in the try block, since we have no problem
5053 def create_analysed(pos, env, body, finally_clause):
5054 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
5056 create_analysed = staticmethod(create_analysed)
5058 def analyse_control_flow(self, env):
5059 env.start_branching(self.pos)
5060 self.body.analyse_control_flow(env)
5061 env.next_branch(self.body.end_pos())
5062 env.finish_branching(self.body.end_pos())
5063 self.finally_clause.analyse_control_flow(env)
5065 def analyse_declarations(self, env):
5066 self.body.analyse_declarations(env)
5067 self.finally_clause.analyse_declarations(env)
5069 def analyse_expressions(self, env):
5070 self.body.analyse_expressions(env)
5071 self.finally_clause.analyse_expressions(env)
5073 nogil_check = Node.gil_error
5074 gil_message = "Try-finally statement"
5076 def generate_execution_code(self, code):
5077 old_error_label = code.error_label
5078 old_labels = code.all_new_labels()
5079 new_labels = code.get_all_labels()
5080 new_error_label = code.error_label
5081 catch_label = code.new_label()
5084 if self.disallow_continue_in_try_finally:
5085 was_in_try_finally = code.funcstate.in_try_finally
5086 code.funcstate.in_try_finally = 1
5087 self.body.generate_execution_code(code)
5088 if self.disallow_continue_in_try_finally:
5089 code.funcstate.in_try_finally = was_in_try_finally
5092 temps_to_clean_up = code.funcstate.all_free_managed_temps()
5093 code.mark_pos(self.finally_clause.pos)
5097 error_label_used = 0
5098 for i, new_label in enumerate(new_labels):
5099 if new_label in code.labels_used:
5100 cases_used.append(i)
5101 if new_label == new_error_label:
5102 error_label_used = 1
5103 error_label_case = i
5107 if error_label_used and self.preserve_exception:
5109 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
5111 "int %s;" % Naming.exc_lineno_name)
5112 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
5113 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
5114 code.putln(exc_var_init_zero)
5116 exc_var_init_zero = None
5117 code.use_label(catch_label)
5119 "__pyx_why = 0; goto %s;" % catch_label)
5120 for i in cases_used:
5121 new_label = new_labels[i]
5122 #if new_label and new_label != "<try>":
5123 if new_label == new_error_label and self.preserve_exception:
5124 self.put_error_catcher(code,
5125 new_error_label, i+1, catch_label, temps_to_clean_up)
5127 code.put('%s: ' % new_label)
5128 if exc_var_init_zero:
5129 code.putln(exc_var_init_zero)
5130 code.putln("__pyx_why = %s; goto %s;" % (
5133 code.put_label(catch_label)
5134 code.set_all_labels(old_labels)
5135 if error_label_used:
5136 code.new_error_label()
5137 finally_error_label = code.error_label
5138 self.finally_clause.generate_execution_code(code)
5139 if error_label_used:
5140 if finally_error_label in code.labels_used and self.preserve_exception:
5141 over_label = code.new_label()
5142 code.put_goto(over_label);
5143 code.put_label(finally_error_label)
5144 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5145 for var in Naming.exc_vars:
5146 code.putln("Py_XDECREF(%s);" % var)
5148 code.put_goto(old_error_label)
5149 code.put_label(over_label)
5150 code.error_label = old_error_label
5153 "switch (__pyx_why) {")
5154 for i in cases_used:
5155 old_label = old_labels[i]
5156 if old_label == old_error_label and self.preserve_exception:
5157 self.put_error_uncatcher(code, i+1, old_error_label)
5159 code.use_label(old_label)
5161 "case %s: goto %s;" % (
5169 def generate_function_definitions(self, env, code):
5170 self.body.generate_function_definitions(env, code)
5171 self.finally_clause.generate_function_definitions(env, code)
5173 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5174 code.globalstate.use_utility_code(restore_exception_utility_code)
5181 for temp_name, type in temps_to_clean_up:
5182 code.put_xdecref_clear(temp_name, type)
5184 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5188 Naming.exc_lineno_name, Naming.lineno_cname))
5189 code.put_goto(catch_label)
5192 def put_error_uncatcher(self, code, i, error_label):
5193 code.globalstate.use_utility_code(restore_exception_utility_code)
5198 "__Pyx_ErrRestore(%s, %s, %s);" %
5202 Naming.lineno_cname, Naming.exc_lineno_name))
5203 for var in Naming.exc_vars:
5207 code.put_goto(error_label)
5211 def annotate(self, code):
5212 self.body.annotate(code)
5213 self.finally_clause.annotate(code)
5216 class GILStatNode(TryFinallyStatNode):
5217 # 'with gil' or 'with nogil' statement
5219 # state string 'gil' or 'nogil'
5223 preserve_exception = 0
5225 def __init__(self, pos, state, body):
5227 TryFinallyStatNode.__init__(self, pos,
5229 finally_clause = GILExitNode(pos, state = state))
5231 def analyse_expressions(self, env):
5232 env.use_utility_code(force_init_threads_utility_code)
5233 was_nogil = env.nogil
5235 TryFinallyStatNode.analyse_expressions(self, env)
5236 env.nogil = was_nogil
5240 def generate_execution_code(self, code):
5241 code.mark_pos(self.pos)
5243 if self.state == 'gil':
5244 code.putln("#ifdef WITH_THREAD")
5245 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5246 code.putln("#endif")
5248 code.putln("#ifdef WITH_THREAD")
5249 code.putln("PyThreadState *_save;")
5250 code.putln("#endif")
5251 code.putln("Py_UNBLOCK_THREADS")
5252 TryFinallyStatNode.generate_execution_code(self, code)
5256 class GILExitNode(StatNode):
5257 # Used as the 'finally' block in a GILStatNode
5259 # state string 'gil' or 'nogil'
5263 def analyse_expressions(self, env):
5266 def generate_execution_code(self, code):
5267 if self.state == 'gil':
5268 code.putln("#ifdef WITH_THREAD")
5269 code.putln("PyGILState_Release(_save);")
5270 code.putln("#endif")
5272 code.putln("Py_BLOCK_THREADS")
5275 class CImportStatNode(StatNode):
5278 # module_name string Qualified name of module being imported
5279 # as_name string or None Name specified in "as" clause, if any
5283 def analyse_declarations(self, env):
5284 if not env.is_module_scope:
5285 error(self.pos, "cimport only allowed at module level")
5287 module_scope = env.find_module(self.module_name, self.pos)
5288 if "." in self.module_name:
5289 names = [EncodedString(name) for name in self.module_name.split(".")]
5291 top_module_scope = env.context.find_submodule(top_name)
5292 module_scope = top_module_scope
5293 for name in names[1:]:
5294 submodule_scope = module_scope.find_submodule(name)
5295 module_scope.declare_module(name, submodule_scope, self.pos)
5296 module_scope = submodule_scope
5298 env.declare_module(self.as_name, module_scope, self.pos)
5300 env.declare_module(top_name, top_module_scope, self.pos)
5302 name = self.as_name or self.module_name
5303 env.declare_module(name, module_scope, self.pos)
5305 def analyse_expressions(self, env):
5308 def generate_execution_code(self, code):
5312 class FromCImportStatNode(StatNode):
5313 # from ... cimport statement
5315 # module_name string Qualified name of module
5316 # imported_names [(pos, name, as_name, kind)] Names to be imported
5320 def analyse_declarations(self, env):
5321 if not env.is_module_scope:
5322 error(self.pos, "cimport only allowed at module level")
5324 module_scope = env.find_module(self.module_name, self.pos)
5325 env.add_imported_module(module_scope)
5326 for pos, name, as_name, kind in self.imported_names:
5328 for local_name, entry in module_scope.entries.items():
5329 env.add_imported_entry(local_name, entry, pos)
5331 entry = module_scope.lookup(name)
5333 if kind and not self.declaration_matches(entry, kind):
5334 entry.redeclared(pos)
5336 if kind == 'struct' or kind == 'union':
5337 entry = module_scope.declare_struct_or_union(name,
5338 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5339 elif kind == 'class':
5340 entry = module_scope.declare_c_class(name, pos = pos,
5341 module_name = self.module_name)
5343 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5344 if submodule_scope.parent_module is module_scope:
5345 env.declare_module(as_name or name, submodule_scope, self.pos)
5347 error(pos, "Name '%s' not declared in module '%s'"
5348 % (name, self.module_name))
5351 local_name = as_name or name
5352 env.add_imported_entry(local_name, entry, pos)
5354 def declaration_matches(self, entry, kind):
5355 if not entry.is_type:
5359 if not type.is_extension_type:
5362 if not type.is_struct_or_union:
5364 if kind != type.kind:
5368 def analyse_expressions(self, env):
5371 def generate_execution_code(self, code):
5375 class FromImportStatNode(StatNode):
5376 # from ... import statement
5379 # items [(string, NameNode)]
5380 # interned_items [(string, NameNode, ExprNode)]
5381 # item PyTempNode used internally
5382 # import_star boolean used internally
5384 child_attrs = ["module"]
5387 def analyse_declarations(self, env):
5388 for name, target in self.items:
5390 if not env.is_module_scope:
5391 error(self.pos, "import * only allowed at module level")
5393 env.has_import_star = 1
5394 self.import_star = 1
5396 target.analyse_target_declaration(env)
5398 def analyse_expressions(self, env):
5400 self.module.analyse_expressions(env)
5401 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5402 self.interned_items = []
5403 for name, target in self.items:
5405 for _, entry in env.entries.items():
5406 if not entry.is_type and entry.type.is_extension_type:
5407 env.use_utility_code(ExprNodes.type_test_utility_code)
5410 entry = env.lookup(target.name)
5411 # check whether or not entry is already cimported
5412 if (entry.is_type and entry.type.name == name
5413 and hasattr(entry.type, 'module_name')):
5414 if entry.type.module_name == self.module.module_name.value:
5415 # cimported with absolute name
5418 # cimported with relative name
5419 module = env.find_module(self.module.module_name.value,
5421 if entry.type.module_name == module.qualified_name:
5423 except AttributeError:
5425 target.analyse_target_expression(env, None)
5426 if target.type is py_object_type:
5429 coerced_item = self.item.coerce_to(target.type, env)
5430 self.interned_items.append((name, target, coerced_item))
5432 def generate_execution_code(self, code):
5433 self.module.generate_evaluation_code(code)
5434 if self.import_star:
5436 'if (%s(%s) < 0) %s;' % (
5438 self.module.py_result(),
5439 code.error_goto(self.pos)))
5440 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5441 self.item.set_cname(item_temp)
5442 for name, target, coerced_item in self.interned_items:
5443 cname = code.intern_identifier(name)
5445 '%s = PyObject_GetAttr(%s, %s); %s' % (
5447 self.module.py_result(),
5449 code.error_goto_if_null(item_temp, self.pos)))
5450 code.put_gotref(item_temp)
5451 if coerced_item is None:
5452 target.generate_assignment_code(self.item, code)
5454 coerced_item.allocate_temp_result(code)
5455 coerced_item.generate_result_code(code)
5456 target.generate_assignment_code(coerced_item, code)
5457 code.put_decref_clear(item_temp, py_object_type)
5458 code.funcstate.release_temp(item_temp)
5459 self.module.generate_disposal_code(code)
5460 self.module.free_temps(code)
5464 #------------------------------------------------------------------------------------
5466 # Runtime support code
5468 #------------------------------------------------------------------------------------
5470 utility_function_predeclarations = \
5472 /* inline attribute */
5473 #ifndef CYTHON_INLINE
5474 #if defined(__GNUC__)
5475 #define CYTHON_INLINE __inline__
5476 #elif defined(_MSC_VER)
5477 #define CYTHON_INLINE __inline
5478 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5479 #define CYTHON_INLINE inline
5481 #define CYTHON_INLINE
5485 /* unused attribute */
5486 #ifndef CYTHON_UNUSED
5487 # if defined(__GNUC__)
5488 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5489 # define CYTHON_UNUSED __attribute__ ((__unused__))
5491 # define CYTHON_UNUSED
5493 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5494 # define CYTHON_UNUSED __attribute__ ((__unused__))
5496 # define CYTHON_UNUSED
5500 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*/
5504 if Options.gcc_branch_hints:
5505 branch_prediction_macros = \
5508 /* Test for GCC > 2.95 */
5509 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5510 #define likely(x) __builtin_expect(!!(x), 1)
5511 #define unlikely(x) __builtin_expect(!!(x), 0)
5512 #else /* __GNUC__ > 2 ... */
5513 #define likely(x) (x)
5514 #define unlikely(x) (x)
5515 #endif /* __GNUC__ > 2 ... */
5516 #else /* __GNUC__ */
5517 #define likely(x) (x)
5518 #define unlikely(x) (x)
5519 #endif /* __GNUC__ */
5522 branch_prediction_macros = \
5524 #define likely(x) (x)
5525 #define unlikely(x) (x)
5528 #get_name_predeclaration = \
5529 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5531 #get_name_interned_predeclaration = \
5532 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5534 #------------------------------------------------------------------------------------
5536 printing_utility_code = UtilityCode(
5538 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5539 #if PY_MAJOR_VERSION >= 3
5540 static PyObject* %s = 0;
5541 static PyObject* %s = 0;
5543 """ % (Naming.print_function, Naming.print_function_kwargs),
5545 #if PY_MAJOR_VERSION >= 3
5549 """ % (Naming.print_function, Naming.print_function_kwargs),
5551 #if PY_MAJOR_VERSION < 3
5552 static PyObject *__Pyx_GetStdout(void) {
5553 PyObject *f = PySys_GetObject((char *)"stdout");
5555 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5560 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5565 if (!(f = __Pyx_GetStdout()))
5568 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5569 if (PyFile_SoftSpace(f, 1)) {
5570 if (PyFile_WriteString(" ", f) < 0)
5573 v = PyTuple_GET_ITEM(arg_tuple, i);
5574 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5576 if (PyString_Check(v)) {
5577 char *s = PyString_AsString(v);
5578 Py_ssize_t len = PyString_Size(v);
5580 isspace(Py_CHARMASK(s[len-1])) &&
5582 PyFile_SoftSpace(f, 0);
5586 if (PyFile_WriteString("\n", f) < 0)
5588 PyFile_SoftSpace(f, 0);
5593 #else /* Python 3 has a print function */
5595 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5596 PyObject* kwargs = 0;
5597 PyObject* result = 0;
5598 PyObject* end_string;
5599 if (unlikely(!%(PRINT_FUNCTION)s)) {
5600 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5601 if (!%(PRINT_FUNCTION)s)
5605 kwargs = PyDict_New();
5606 if (unlikely(!kwargs))
5608 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5611 end_string = PyUnicode_FromStringAndSize(" ", 1);
5612 if (unlikely(!end_string))
5614 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5615 Py_DECREF(end_string);
5618 Py_DECREF(end_string);
5620 } else if (!newline) {
5621 if (unlikely(!%(PRINT_KWARGS)s)) {
5622 %(PRINT_KWARGS)s = PyDict_New();
5623 if (unlikely(!%(PRINT_KWARGS)s))
5625 end_string = PyUnicode_FromStringAndSize(" ", 1);
5626 if (unlikely(!end_string))
5628 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5629 Py_DECREF(end_string);
5632 Py_DECREF(end_string);
5634 kwargs = %(PRINT_KWARGS)s;
5636 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5637 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5644 if (kwargs != %(PRINT_KWARGS)s)
5650 """ % {'BUILTINS' : Naming.builtins_cname,
5651 'PRINT_FUNCTION' : Naming.print_function,
5652 'PRINT_KWARGS' : Naming.print_function_kwargs}
5656 printing_one_utility_code = UtilityCode(
5658 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5661 #if PY_MAJOR_VERSION < 3
5663 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5665 if (!(f = __Pyx_GetStdout()))
5668 if (PyFile_SoftSpace(f, 0)) {
5669 if (PyFile_WriteString(" ", f) < 0)
5672 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5674 if (PyFile_WriteString("\n", f) < 0)
5677 /* the line below is just to avoid compiler
5678 * compiler warnings about unused functions */
5679 return __Pyx_Print(f, NULL, 0);
5682 #else /* Python 3 has a print function */
5684 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5686 PyObject* arg_tuple = PyTuple_New(1);
5687 if (unlikely(!arg_tuple))
5690 PyTuple_SET_ITEM(arg_tuple, 0, o);
5691 res = __Pyx_Print(stream, arg_tuple, 1);
5692 Py_DECREF(arg_tuple);
5698 requires=[printing_utility_code])
5702 #------------------------------------------------------------------------------------
5704 # Exception raising code
5706 # Exceptions are raised by __Pyx_Raise() and stored as plain
5707 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5708 # 'except' statement, curexc_* is moved over to exc_* by
5709 # __Pyx_GetException()
5711 restore_exception_utility_code = UtilityCode(
5713 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5714 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5717 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5718 PyObject *tmp_type, *tmp_value, *tmp_tb;
5719 PyThreadState *tstate = PyThreadState_GET();
5721 tmp_type = tstate->curexc_type;
5722 tmp_value = tstate->curexc_value;
5723 tmp_tb = tstate->curexc_traceback;
5724 tstate->curexc_type = type;
5725 tstate->curexc_value = value;
5726 tstate->curexc_traceback = tb;
5727 Py_XDECREF(tmp_type);
5728 Py_XDECREF(tmp_value);
5732 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5733 PyThreadState *tstate = PyThreadState_GET();
5734 *type = tstate->curexc_type;
5735 *value = tstate->curexc_value;
5736 *tb = tstate->curexc_traceback;
5738 tstate->curexc_type = 0;
5739 tstate->curexc_value = 0;
5740 tstate->curexc_traceback = 0;
5745 # The following function is based on do_raise() from ceval.c. There
5746 # are separate versions for Python2 and Python3 as exception handling
5747 # has changed quite a lot between the two versions.
5749 raise_utility_code = UtilityCode(
5751 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5754 #if PY_MAJOR_VERSION < 3
5755 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5759 /* First, check the traceback argument, replacing None with NULL. */
5760 if (tb == Py_None) {
5764 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5765 PyErr_SetString(PyExc_TypeError,
5766 "raise: arg 3 must be a traceback or None");
5769 /* Next, replace a missing value with None */
5770 if (value == NULL) {
5774 #if PY_VERSION_HEX < 0x02050000
5775 if (!PyClass_Check(type))
5777 if (!PyType_Check(type))
5780 /* Raising an instance. The value should be a dummy. */
5781 if (value != Py_None) {
5782 PyErr_SetString(PyExc_TypeError,
5783 "instance exception may not have a separate value");
5786 /* Normalize to raise <class>, <instance> */
5789 #if PY_VERSION_HEX < 0x02050000
5790 if (PyInstance_Check(type)) {
5791 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5796 PyErr_SetString(PyExc_TypeError,
5797 "raise: exception must be an old-style class or instance");
5801 type = (PyObject*) Py_TYPE(type);
5803 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5804 PyErr_SetString(PyExc_TypeError,
5805 "raise: exception class must be a subclass of BaseException");
5811 __Pyx_ErrRestore(type, value, tb);
5820 #else /* Python 3+ */
5822 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5823 if (tb == Py_None) {
5825 } else if (tb && !PyTraceBack_Check(tb)) {
5826 PyErr_SetString(PyExc_TypeError,
5827 "raise: arg 3 must be a traceback or None");
5830 if (value == Py_None)
5833 if (PyExceptionInstance_Check(type)) {
5835 PyErr_SetString(PyExc_TypeError,
5836 "instance exception may not have a separate value");
5840 type = (PyObject*) Py_TYPE(value);
5841 } else if (!PyExceptionClass_Check(type)) {
5842 PyErr_SetString(PyExc_TypeError,
5843 "raise: exception class must be a subclass of BaseException");
5847 PyErr_SetObject(type, value);
5850 PyThreadState *tstate = PyThreadState_GET();
5851 PyObject* tmp_tb = tstate->curexc_traceback;
5854 tstate->curexc_traceback = tb;
5864 requires=[restore_exception_utility_code])
5866 #------------------------------------------------------------------------------------
5868 get_exception_utility_code = UtilityCode(
5870 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5873 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5874 PyObject *local_type, *local_value, *local_tb;
5875 PyObject *tmp_type, *tmp_value, *tmp_tb;
5876 PyThreadState *tstate = PyThreadState_GET();
5877 local_type = tstate->curexc_type;
5878 local_value = tstate->curexc_value;
5879 local_tb = tstate->curexc_traceback;
5880 tstate->curexc_type = 0;
5881 tstate->curexc_value = 0;
5882 tstate->curexc_traceback = 0;
5883 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5884 if (unlikely(tstate->curexc_type))
5886 #if PY_MAJOR_VERSION >= 3
5887 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5891 *value = local_value;
5893 Py_INCREF(local_type);
5894 Py_INCREF(local_value);
5895 Py_INCREF(local_tb);
5896 tmp_type = tstate->exc_type;
5897 tmp_value = tstate->exc_value;
5898 tmp_tb = tstate->exc_traceback;
5899 tstate->exc_type = local_type;
5900 tstate->exc_value = local_value;
5901 tstate->exc_traceback = local_tb;
5902 /* Make sure tstate is in a consistent state when we XDECREF
5903 these objects (XDECREF may run arbitrary code). */
5904 Py_XDECREF(tmp_type);
5905 Py_XDECREF(tmp_value);
5912 Py_XDECREF(local_type);
5913 Py_XDECREF(local_value);
5914 Py_XDECREF(local_tb);
5920 #------------------------------------------------------------------------------------
5922 get_exception_tuple_utility_code = UtilityCode(proto="""
5923 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5925 # I doubt that calling __Pyx_GetException() here is correct as it moves
5926 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5927 # exception handlers later on from receiving it.
5929 static PyObject *__Pyx_GetExceptionTuple(void) {
5930 PyObject *type = NULL, *value = NULL, *tb = NULL;
5931 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5932 PyObject* exc_info = PyTuple_New(3);
5937 PyTuple_SET_ITEM(exc_info, 0, type);
5938 PyTuple_SET_ITEM(exc_info, 1, value);
5939 PyTuple_SET_ITEM(exc_info, 2, tb);
5946 requires=[get_exception_utility_code])
5948 #------------------------------------------------------------------------------------
5950 reset_exception_utility_code = UtilityCode(
5952 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5953 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5956 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5957 PyThreadState *tstate = PyThreadState_GET();
5958 *type = tstate->exc_type;
5959 *value = tstate->exc_value;
5960 *tb = tstate->exc_traceback;
5966 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5967 PyObject *tmp_type, *tmp_value, *tmp_tb;
5968 PyThreadState *tstate = PyThreadState_GET();
5969 tmp_type = tstate->exc_type;
5970 tmp_value = tstate->exc_value;
5971 tmp_tb = tstate->exc_traceback;
5972 tstate->exc_type = type;
5973 tstate->exc_value = value;
5974 tstate->exc_traceback = tb;
5975 Py_XDECREF(tmp_type);
5976 Py_XDECREF(tmp_value);
5981 #------------------------------------------------------------------------------------
5983 arg_type_test_utility_code = UtilityCode(
5985 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5986 const char *name, int exact); /*proto*/
5989 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5990 const char *name, int exact)
5993 PyErr_Format(PyExc_SystemError, "Missing type object");
5996 if (none_allowed && obj == Py_None) return 1;
5998 if (Py_TYPE(obj) == type) return 1;
6001 if (PyObject_TypeCheck(obj, type)) return 1;
6003 PyErr_Format(PyExc_TypeError,
6004 "Argument '%s' has incorrect type (expected %s, got %s)",
6005 name, type->tp_name, Py_TYPE(obj)->tp_name);
6010 #------------------------------------------------------------------------------------
6012 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
6013 # many or too few positional arguments were found. This handles
6014 # Py_ssize_t formatting correctly.
6016 raise_argtuple_invalid_utility_code = UtilityCode(
6018 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
6019 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
6022 static void __Pyx_RaiseArgtupleInvalid(
6023 const char* func_name,
6027 Py_ssize_t num_found)
6029 Py_ssize_t num_expected;
6030 const char *number, *more_or_less;
6032 if (num_found < num_min) {
6033 num_expected = num_min;
6034 more_or_less = "at least";
6036 num_expected = num_max;
6037 more_or_less = "at most";
6040 more_or_less = "exactly";
6042 number = (num_expected == 1) ? "" : "s";
6043 PyErr_Format(PyExc_TypeError,
6044 #if PY_VERSION_HEX < 0x02050000
6045 "%s() takes %s %d positional argument%s (%d given)",
6047 "%s() takes %s %zd positional argument%s (%zd given)",
6049 func_name, more_or_less, num_expected, number, num_found);
6053 raise_keyword_required_utility_code = UtilityCode(
6055 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
6058 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
6059 const char* func_name,
6062 PyErr_Format(PyExc_TypeError,
6063 #if PY_MAJOR_VERSION >= 3
6064 "%s() needs keyword-only argument %U", func_name, kw_name);
6066 "%s() needs keyword-only argument %s", func_name,
6067 PyString_AS_STRING(kw_name));
6072 raise_double_keywords_utility_code = UtilityCode(
6074 static void __Pyx_RaiseDoubleKeywordsError(
6075 const char* func_name, PyObject* kw_name); /*proto*/
6078 static void __Pyx_RaiseDoubleKeywordsError(
6079 const char* func_name,
6082 PyErr_Format(PyExc_TypeError,
6083 #if PY_MAJOR_VERSION >= 3
6084 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
6086 "%s() got multiple values for keyword argument '%s'", func_name,
6087 PyString_AS_STRING(kw_name));
6092 #------------------------------------------------------------------------------------
6094 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
6095 # were passed to a function, or if any keywords were passed to a
6096 # function that does not accept them.
6098 keyword_string_check_utility_code = UtilityCode(
6100 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
6101 const char* function_name, int kw_allowed); /*proto*/
6104 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
6106 const char* function_name,
6111 while (PyDict_Next(kwdict, &pos, &key, 0)) {
6112 #if PY_MAJOR_VERSION < 3
6113 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
6115 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6117 goto invalid_keyword_type;
6119 if ((!kw_allowed) && unlikely(key))
6120 goto invalid_keyword;
6122 invalid_keyword_type:
6123 PyErr_Format(PyExc_TypeError,
6124 "%s() keywords must be strings", function_name);
6127 PyErr_Format(PyExc_TypeError,
6128 #if PY_MAJOR_VERSION < 3
6129 "%s() got an unexpected keyword argument '%s'",
6130 function_name, PyString_AsString(key));
6132 "%s() got an unexpected keyword argument '%U'",
6133 function_name, key);
6139 #------------------------------------------------------------------------------------
6141 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6142 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6143 # keywords will raise an invalid keyword error.
6145 # Three kinds of errors are checked: 1) non-string keywords, 2)
6146 # unexpected keywords and 3) overlap with positional arguments.
6148 # If num_posargs is greater 0, it denotes the number of positional
6149 # arguments that were passed and that must therefore not appear
6150 # amongst the keywords as well.
6152 # This method does not check for required keyword arguments.
6155 parse_keywords_utility_code = UtilityCode(
6157 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6158 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6159 const char* function_name); /*proto*/
6162 static int __Pyx_ParseOptionalKeywords(
6164 PyObject **argnames[],
6167 Py_ssize_t num_pos_args,
6168 const char* function_name)
6170 PyObject *key = 0, *value = 0;
6173 PyObject*** first_kw_arg = argnames + num_pos_args;
6175 while (PyDict_Next(kwds, &pos, &key, &value)) {
6176 name = first_kw_arg;
6177 while (*name && (**name != key)) name++;
6179 values[name-argnames] = value;
6181 #if PY_MAJOR_VERSION < 3
6182 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6184 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6186 goto invalid_keyword_type;
6188 for (name = first_kw_arg; *name; name++) {
6189 #if PY_MAJOR_VERSION >= 3
6190 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6191 PyUnicode_Compare(**name, key) == 0) break;
6193 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6194 _PyString_Eq(**name, key)) break;
6198 values[name-argnames] = value;
6200 /* unexpected keyword found */
6201 for (name=argnames; name != first_kw_arg; name++) {
6202 if (**name == key) goto arg_passed_twice;
6203 #if PY_MAJOR_VERSION >= 3
6204 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6205 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6207 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6208 _PyString_Eq(**name, key)) goto arg_passed_twice;
6212 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6214 goto invalid_keyword;
6222 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6224 invalid_keyword_type:
6225 PyErr_Format(PyExc_TypeError,
6226 "%s() keywords must be strings", function_name);
6229 PyErr_Format(PyExc_TypeError,
6230 #if PY_MAJOR_VERSION < 3
6231 "%s() got an unexpected keyword argument '%s'",
6232 function_name, PyString_AsString(key));
6234 "%s() got an unexpected keyword argument '%U'",
6235 function_name, key);
6242 #------------------------------------------------------------------------------------
6244 traceback_utility_code = UtilityCode(
6246 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6249 #include "compile.h"
6250 #include "frameobject.h"
6251 #include "traceback.h"
6253 static void __Pyx_AddTraceback(const char *funcname) {
6254 PyObject *py_srcfile = 0;
6255 PyObject *py_funcname = 0;
6256 PyObject *py_globals = 0;
6257 PyCodeObject *py_code = 0;
6258 PyFrameObject *py_frame = 0;
6260 #if PY_MAJOR_VERSION < 3
6261 py_srcfile = PyString_FromString(%(FILENAME)s);
6263 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6265 if (!py_srcfile) goto bad;
6267 #if PY_MAJOR_VERSION < 3
6268 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6270 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6274 #if PY_MAJOR_VERSION < 3
6275 py_funcname = PyString_FromString(funcname);
6277 py_funcname = PyUnicode_FromString(funcname);
6280 if (!py_funcname) goto bad;
6281 py_globals = PyModule_GetDict(%(GLOBALS)s);
6282 if (!py_globals) goto bad;
6283 py_code = PyCode_New(
6284 0, /*int argcount,*/
6285 #if PY_MAJOR_VERSION >= 3
6286 0, /*int kwonlyargcount,*/
6289 0, /*int stacksize,*/
6291 %(EMPTY_BYTES)s, /*PyObject *code,*/
6292 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6293 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6294 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6295 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6296 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6297 py_srcfile, /*PyObject *filename,*/
6298 py_funcname, /*PyObject *name,*/
6299 %(LINENO)s, /*int firstlineno,*/
6300 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6302 if (!py_code) goto bad;
6303 py_frame = PyFrame_New(
6304 PyThreadState_GET(), /*PyThreadState *tstate,*/
6305 py_code, /*PyCodeObject *code,*/
6306 py_globals, /*PyObject *globals,*/
6307 0 /*PyObject *locals*/
6309 if (!py_frame) goto bad;
6310 py_frame->f_lineno = %(LINENO)s;
6311 PyTraceBack_Here(py_frame);
6313 Py_XDECREF(py_srcfile);
6314 Py_XDECREF(py_funcname);
6315 Py_XDECREF(py_code);
6316 Py_XDECREF(py_frame);
6319 'FILENAME': Naming.filename_cname,
6320 'LINENO': Naming.lineno_cname,
6321 'CFILENAME': Naming.cfilenm_cname,
6322 'CLINENO': Naming.clineno_cname,
6323 'GLOBALS': Naming.module_cname,
6324 'EMPTY_TUPLE' : Naming.empty_tuple,
6325 'EMPTY_BYTES' : Naming.empty_bytes,
6328 #------------------------------------------------------------------------------------
6330 unraisable_exception_utility_code = UtilityCode(
6332 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6335 static void __Pyx_WriteUnraisable(const char *name) {
6336 PyObject *old_exc, *old_val, *old_tb;
6338 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6339 #if PY_MAJOR_VERSION < 3
6340 ctx = PyString_FromString(name);
6342 ctx = PyUnicode_FromString(name);
6344 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6346 PyErr_WriteUnraisable(Py_None);
6348 PyErr_WriteUnraisable(ctx);
6353 requires=[restore_exception_utility_code])
6355 #------------------------------------------------------------------------------------
6357 set_vtable_utility_code = UtilityCode(
6359 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6362 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6363 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6364 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6366 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6370 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6380 #------------------------------------------------------------------------------------
6382 get_vtable_utility_code = UtilityCode(
6384 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6387 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6388 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6391 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6392 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6394 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6396 if (!*(void **)vtabptr)
6406 #------------------------------------------------------------------------------------
6408 init_string_tab_utility_code = UtilityCode(
6410 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6413 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6415 #if PY_MAJOR_VERSION < 3
6416 if (t->is_unicode) {
6417 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6418 } else if (t->intern) {
6419 *t->p = PyString_InternFromString(t->s);
6421 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6423 #else /* Python 3+ has unicode identifiers */
6424 if (t->is_unicode | t->is_str) {
6426 *t->p = PyUnicode_InternFromString(t->s);
6427 } else if (t->encoding) {
6428 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6430 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6433 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6444 #------------------------------------------------------------------------------------
6446 force_init_threads_utility_code = UtilityCode(
6448 #ifndef __PYX_FORCE_INIT_THREADS
6449 #if PY_VERSION_HEX < 0x02040200
6450 #define __PYX_FORCE_INIT_THREADS 1
6452 #define __PYX_FORCE_INIT_THREADS 0
6457 #------------------------------------------------------------------------------------
6459 # Note that cPython ignores PyTrace_EXCEPTION,
6460 # but maybe some other profilers don't.
6462 profile_utility_code = UtilityCode(proto="""
6463 #ifndef CYTHON_PROFILE
6464 #define CYTHON_PROFILE 1
6467 #ifndef CYTHON_PROFILE_REUSE_FRAME
6468 #define CYTHON_PROFILE_REUSE_FRAME 0
6473 #include "compile.h"
6474 #include "frameobject.h"
6475 #include "traceback.h"
6477 #if CYTHON_PROFILE_REUSE_FRAME
6478 #define CYTHON_FRAME_MODIFIER static
6479 #define CYTHON_FRAME_DEL
6481 #define CYTHON_FRAME_MODIFIER
6482 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6485 #define __Pyx_TraceDeclarations \\
6486 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6487 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6488 int __Pyx_use_tracing = 0;
6490 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6491 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6492 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6495 #define __Pyx_TraceException() \\
6496 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6497 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6499 PyThreadState_GET()->c_profilefunc( \\
6500 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6501 Py_DECREF(exc_info); \\
6505 #define __Pyx_TraceReturn(result) \\
6506 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6507 PyThreadState_GET()->c_profilefunc( \\
6508 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6509 CYTHON_FRAME_DEL; \\
6512 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6513 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6517 #define __Pyx_TraceDeclarations
6518 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6519 #define __Pyx_TraceException()
6520 #define __Pyx_TraceReturn(result)
6522 #endif /* CYTHON_PROFILE */
6525 "FRAME": Naming.frame_cname,
6526 "FRAME_CODE": Naming.frame_code_cname,
6532 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6533 PyFrameObject** frame,
6534 const char *funcname,
6535 const char *srcfile,
6537 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6538 if (*code == NULL) {
6539 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6540 if (*code == NULL) return 0;
6542 *frame = PyFrame_New(
6543 PyThreadState_GET(), /*PyThreadState *tstate*/
6544 *code, /*PyCodeObject *code*/
6545 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6546 0 /*PyObject *locals*/
6548 if (*frame == NULL) return 0;
6551 (*frame)->f_tstate = PyThreadState_GET();
6553 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6556 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6557 PyObject *py_srcfile = 0;
6558 PyObject *py_funcname = 0;
6559 PyCodeObject *py_code = 0;
6561 #if PY_MAJOR_VERSION < 3
6562 py_funcname = PyString_FromString(funcname);
6563 py_srcfile = PyString_FromString(srcfile);
6565 py_funcname = PyUnicode_FromString(funcname);
6566 py_srcfile = PyUnicode_FromString(srcfile);
6568 if (!py_funcname | !py_srcfile) goto bad;
6570 py_code = PyCode_New(
6571 0, /*int argcount,*/
6572 #if PY_MAJOR_VERSION >= 3
6573 0, /*int kwonlyargcount,*/
6576 0, /*int stacksize,*/
6578 %(EMPTY_BYTES)s, /*PyObject *code,*/
6579 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6580 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6581 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6582 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6583 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6584 py_srcfile, /*PyObject *filename,*/
6585 py_funcname, /*PyObject *name,*/
6586 firstlineno, /*int firstlineno,*/
6587 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6591 Py_XDECREF(py_srcfile);
6592 Py_XDECREF(py_funcname);
6597 #endif /* CYTHON_PROFILE */
6599 'EMPTY_TUPLE' : Naming.empty_tuple,
6600 'EMPTY_BYTES' : Naming.empty_bytes,
6601 "MODULE": Naming.module_cname,