3 # Pyrex - Parse tree nodes
6 import sys, os, time, copy
12 from sets import Set as set
16 from Errors import error, warning, InternalError
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
30 absolute_path_length = 0
32 def relative_position(pos):
34 We embed the relative filename in the generated C file, since we
35 don't want to have to regnerate and compile all the source code
36 whenever the Python install directory moves (which could happen,
37 e.g,. when distributing binaries.)
40 a position tuple -- (absolute filename, line number column position)
48 global absolute_path_length
49 if absolute_path_length==0:
50 absolute_path_length = len(os.path.abspath(os.getcwd()))
51 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
53 def embed_position(pos, docstring):
54 if not Options.embed_pos_in_docstring:
56 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
59 return EncodedString(pos_line)
61 # make sure we can encode the filename in the docstring encoding
62 # otherwise make the docstring a unicode string
63 encoding = docstring.encoding
64 if encoding is not None:
66 encoded_bytes = pos_line.encode(encoding)
67 except UnicodeEncodeError:
71 # reuse the string encoding of the original docstring
72 doc = EncodedString(pos_line)
74 doc = EncodedString(pos_line + u'\n' + docstring)
75 doc.encoding = encoding
79 from Code import CCodeWriter
80 from types import FunctionType
82 def write_func_call(func):
84 if len(args) > 1 and isinstance(args[1], CCodeWriter):
85 # here we annotate the code with this function call
86 # but only if new code is generated
88 marker = ' /* %s -> %s.%s %s */' % (
89 ' ' * code.call_level,
90 node.__class__.__name__,
93 pristine = code.buffer.stream.tell()
95 start = code.buffer.stream.tell()
97 res = func(*args, **kwds)
99 if start == code.buffer.stream.tell():
100 code.buffer.stream.seek(pristine)
102 marker = marker.replace('->', '<-')
106 return func(*args, **kwds)
109 class VerboseCodeWriter(type):
110 # Set this as a metaclass to trace function calls in code.
111 # This slows down code generation and makes much larger files.
112 def __new__(cls, name, bases, attrs):
114 for mname, m in attrs.items():
115 if isinstance(m, FunctionType):
116 attrs[mname] = write_func_call(m)
117 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
121 # pos (string, int, int) Source file position
122 # is_name boolean Is a NameNode
123 # is_literal boolean Is a ConstNode
125 if DebugFlags.debug_trace_code_generation:
126 __metaclass__ = VerboseCodeWriter
132 # All descandants should set child_attrs to a list of the attributes
133 # containing nodes considered "children" in the tree. Each such attribute
134 # can either contain a single node or a list of nodes. See Visitor.py.
137 def __init__(self, pos, **kw):
139 self.__dict__.update(kw)
141 gil_message = "Operation"
145 def gil_error(self, env=None):
146 error(self.pos, "%s not allowed without gil" % self.gil_message)
148 cpp_message = "Operation"
150 def cpp_check(self, env):
155 error(self.pos, "%s only allowed in c++" % self.cpp_message)
157 def clone_node(self):
158 """Clone the node. This is defined as a shallow copy, except for member lists
159 amongst the child attributes (from get_child_accessors) which are also
160 copied. Lists containing child nodes are thus seen as a way for the node
161 to hold multiple children directly; the list is not treated as a seperate
162 level in the tree."""
163 result = copy.copy(self)
164 for attrname in result.child_attrs:
165 value = getattr(result, attrname)
166 if isinstance(value, list):
167 setattr(result, attrname, [x for x in value])
172 # There are 4 phases of parse tree processing, applied in order to
173 # all the statements in a given scope-block:
175 # (0) analyse_control_flow
176 # Create the control flow tree into which state can be asserted and
179 # (1) analyse_declarations
180 # Make symbol table entries for all declarations at the current
181 # level, both explicit (def, cdef, etc.) and implicit (assignment
182 # to an otherwise undeclared name).
184 # (2) analyse_expressions
185 # Determine the result types of expressions and fill in the
186 # 'type' attribute of each ExprNode. Insert coercion nodes into the
187 # tree where needed to convert to and from Python objects.
188 # Allocate temporary locals for intermediate results. Fill
189 # in the 'result_code' attribute of each ExprNode with a C code
193 # Emit C code for all declarations, statements and expressions.
194 # Recursively applies the 3 processing phases to the bodies of
198 def analyse_control_flow(self, env):
201 def analyse_declarations(self, env):
204 def analyse_expressions(self, env):
205 raise InternalError("analyse_expressions not implemented for %s" % \
206 self.__class__.__name__)
208 def generate_code(self, code):
209 raise InternalError("generate_code not implemented for %s" % \
210 self.__class__.__name__)
212 def annotate(self, code):
213 # mro does the wrong thing
214 if isinstance(self, BlockNode):
215 self.body.annotate(code)
220 except AttributeError:
222 if not self.child_attrs:
225 for attr in self.child_attrs:
226 child = getattr(self, attr)
227 # Sometimes lists, sometimes nodes
230 elif isinstance(child, list):
232 pos = max(pos, c.end_pos())
234 pos = max(pos, child.end_pos())
238 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
240 return "<...nesting level cutoff...>"
241 if encountered is None:
243 if id(self) in encountered:
244 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
245 encountered.add(id(self))
247 def dump_child(x, level):
248 if isinstance(x, Node):
249 return x.dump(level, filter_out, cutoff-1, encountered)
250 elif isinstance(x, list):
251 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
256 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
258 return "<%s (%d)>" % (self.__class__.__name__, id(self))
261 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
262 for key, value in attrs:
263 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
264 res += "%s>" % indent
267 class CompilerDirectivesNode(Node):
269 Sets compiler directives for the children nodes
271 # directives {string:value} A dictionary holding the right value for
272 # *all* possible directives.
274 child_attrs = ["body"]
276 def analyse_control_flow(self, env):
278 env.directives = self.directives
279 self.body.analyse_control_flow(env)
282 def analyse_declarations(self, env):
284 env.directives = self.directives
285 self.body.analyse_declarations(env)
288 def analyse_expressions(self, env):
290 env.directives = self.directives
291 self.body.analyse_expressions(env)
294 def generate_function_definitions(self, env, code):
295 env_old = env.directives
296 code_old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.generate_function_definitions(env, code)
299 env.directives = env_old
300 code.globalstate.directives = code_old
302 def generate_execution_code(self, code):
303 old = code.globalstate.directives
304 code.globalstate.directives = self.directives
305 self.body.generate_execution_code(code)
306 code.globalstate.directives = old
308 def annotate(self, code):
309 old = code.globalstate.directives
310 code.globalstate.directives = self.directives
311 self.body.annotate(code)
312 code.globalstate.directives = old
314 class BlockNode(object):
315 # Mixin class for nodes representing a declaration block.
317 def generate_cached_builtins_decls(self, env, code):
318 entries = env.global_scope().undeclared_cached_builtins
319 for entry in entries:
320 code.globalstate.add_cached_builtin_decl(entry)
324 class StatListNode(Node):
325 # stats a list of StatNode
327 child_attrs = ["stats"]
329 def create_analysed(pos, env, *args, **kw):
330 node = StatListNode(pos, *args, **kw)
331 return node # No node-specific analysis necesarry
332 create_analysed = staticmethod(create_analysed)
334 def analyse_control_flow(self, env):
335 for stat in self.stats:
336 stat.analyse_control_flow(env)
338 def analyse_declarations(self, env):
339 #print "StatListNode.analyse_declarations" ###
340 for stat in self.stats:
341 stat.analyse_declarations(env)
343 def analyse_expressions(self, env):
344 #print "StatListNode.analyse_expressions" ###
345 for stat in self.stats:
346 stat.analyse_expressions(env)
348 def generate_function_definitions(self, env, code):
349 #print "StatListNode.generate_function_definitions" ###
350 for stat in self.stats:
351 stat.generate_function_definitions(env, code)
353 def generate_execution_code(self, code):
354 #print "StatListNode.generate_execution_code" ###
355 for stat in self.stats:
356 code.mark_pos(stat.pos)
357 stat.generate_execution_code(code)
359 def annotate(self, code):
360 for stat in self.stats:
364 class StatNode(Node):
366 # Code generation for statements is split into the following subphases:
368 # (1) generate_function_definitions
369 # Emit C code for the definitions of any structs,
370 # unions, enums and functions defined in the current
373 # (2) generate_execution_code
374 # Emit C code for executable statements.
377 def generate_function_definitions(self, env, code):
380 def generate_execution_code(self, code):
381 raise InternalError("generate_execution_code not implemented for %s" % \
382 self.__class__.__name__)
385 class CDefExternNode(StatNode):
386 # include_file string or None
389 child_attrs = ["body"]
391 def analyse_declarations(self, env):
392 if self.include_file:
393 env.add_include_file(self.include_file)
394 old_cinclude_flag = env.in_cinclude
396 self.body.analyse_declarations(env)
397 env.in_cinclude = old_cinclude_flag
399 def analyse_expressions(self, env):
402 def generate_execution_code(self, code):
405 def annotate(self, code):
406 self.body.annotate(code)
409 class CDeclaratorNode(Node):
410 # Part of a C declaration.
412 # Processing during analyse_declarations phase:
415 # Returns (name, type) pair where name is the
416 # CNameDeclaratorNode of the name being declared
417 # and type is the type it is being declared as.
419 # calling_convention string Calling convention of CFuncDeclaratorNode
420 # for which this is a base
424 calling_convention = ""
427 class CNameDeclaratorNode(CDeclaratorNode):
428 # name string The Pyrex name being declared
429 # cname string or None C name, if specified
430 # default ExprNode or None the value assigned on declaration
432 child_attrs = ['default']
436 def analyse(self, base_type, env, nonempty = 0):
437 if nonempty and self.name == '':
438 # May have mistaken the name for the type.
439 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440 error(self.pos, "Missing argument name")
441 elif base_type.is_void:
442 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
444 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445 base_type = py_object_type
446 self.type = base_type
447 return self, base_type
449 class CPtrDeclaratorNode(CDeclaratorNode):
450 # base CDeclaratorNode
452 child_attrs = ["base"]
454 def analyse(self, base_type, env, nonempty = 0):
455 if base_type.is_pyobject:
457 "Pointer base type cannot be a Python object")
458 ptr_type = PyrexTypes.c_ptr_type(base_type)
459 return self.base.analyse(ptr_type, env, nonempty = nonempty)
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462 # base CDeclaratorNode
464 child_attrs = ["base"]
466 def analyse(self, base_type, env, nonempty = 0):
467 if base_type.is_pyobject:
469 "Reference base type cannot be a Python object")
470 ref_type = PyrexTypes.c_ref_type(base_type)
471 return self.base.analyse(ref_type, env, nonempty = nonempty)
473 class CArrayDeclaratorNode(CDeclaratorNode):
474 # base CDeclaratorNode
477 child_attrs = ["base", "dimension"]
479 def analyse(self, base_type, env, nonempty = 0):
480 if base_type.is_cpp_class:
481 from ExprNodes import TupleNode
482 if isinstance(self.dimension, TupleNode):
483 args = self.dimension.args
485 args = self.dimension,
486 values = [v.analyse_as_type(env) for v in args]
488 ix = values.index(None)
489 error(args[ix].pos, "Template parameter not a type.")
491 base_type = base_type.specialize_here(self.pos, values)
492 return self.base.analyse(base_type, env, nonempty = nonempty)
494 self.dimension.analyse_const_expression(env)
495 if not self.dimension.type.is_int:
496 error(self.dimension.pos, "Array dimension not integer")
497 size = self.dimension.get_constant_c_result_code()
506 if not base_type.is_complete():
508 "Array element type '%s' is incomplete" % base_type)
509 if base_type.is_pyobject:
511 "Array element cannot be a Python object")
512 if base_type.is_cfunction:
514 "Array element cannot be a function")
515 array_type = PyrexTypes.c_array_type(base_type, size)
516 return self.base.analyse(array_type, env, nonempty = nonempty)
519 class CFuncDeclaratorNode(CDeclaratorNode):
520 # base CDeclaratorNode
521 # args [CArgDeclNode]
522 # has_varargs boolean
523 # exception_value ConstNode
524 # exception_check boolean True if PyErr_Occurred check needed
525 # nogil boolean Can be called without gil
526 # with_gil boolean Acquire gil around function body
528 child_attrs = ["base", "args", "exception_value"]
531 optional_arg_count = 0
533 def analyse(self, return_type, env, nonempty = 0):
537 for arg_node in self.args:
538 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
539 name = name_declarator.name
540 if name_declarator.cname:
542 "Function argument cannot have C name specification")
543 # Turn *[] argument into **
545 type = PyrexTypes.c_ptr_type(type.base_type)
546 # Catch attempted C-style func(void) decl
548 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
549 func_type_args.append(
550 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
552 self.optional_arg_count += 1
553 elif self.optional_arg_count:
554 error(self.pos, "Non-default argument follows default argument")
556 if self.optional_arg_count:
557 scope = StructOrUnionScope()
558 arg_count_member = '%sn' % Naming.pyrex_prefix
559 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
560 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
561 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
562 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
563 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
568 cname = struct_cname)
569 self.op_args_struct.defined_in_pxd = 1
570 self.op_args_struct.used = 1
574 if self.exception_check == '+':
575 env.add_include_file('stdexcept')
576 if return_type.is_pyobject \
577 and (self.exception_value or self.exception_check) \
578 and self.exception_check != '+':
580 "Exception clause not allowed for function returning Python object")
582 if self.exception_value:
583 self.exception_value.analyse_const_expression(env)
584 if self.exception_check == '+':
585 self.exception_value.analyse_types(env)
586 exc_val_type = self.exception_value.type
587 if not exc_val_type.is_error and \
588 not exc_val_type.is_pyobject and \
589 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
590 error(self.exception_value.pos,
591 "Exception value must be a Python exception or cdef function with no arguments.")
592 exc_val = self.exception_value
594 if self.exception_value.analyse_const_expression(env):
595 exc_val = self.exception_value.get_constant_c_result_code()
597 raise InternalError("get_constant_c_result_code not implemented for %s" %
598 self.exception_value.__class__.__name__)
599 if not return_type.assignable_from(self.exception_value.type):
600 error(self.exception_value.pos,
601 "Exception value incompatible with function return type")
602 exc_check = self.exception_check
603 if return_type.is_array:
605 "Function cannot return an array")
606 if return_type.is_cfunction:
608 "Function cannot return a function")
609 func_type = PyrexTypes.CFuncType(
610 return_type, func_type_args, self.has_varargs,
611 optional_arg_count = self.optional_arg_count,
612 exception_value = exc_val, exception_check = exc_check,
613 calling_convention = self.base.calling_convention,
614 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
615 if self.optional_arg_count:
616 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
617 callspec = env.directives['callspec']
619 current = func_type.calling_convention
620 if current and current != callspec:
621 error(self.pos, "cannot have both '%s' and '%s' "
622 "calling conventions" % (current, callspec))
623 func_type.calling_convention = callspec
624 return self.base.analyse(func_type, env)
627 class CArgDeclNode(Node):
628 # Item in a function declaration argument list.
630 # base_type CBaseTypeNode
631 # declarator CDeclaratorNode
632 # not_none boolean Tagged with 'not None'
633 # or_none boolean Tagged with 'or None'
634 # accept_none boolean Resolved boolean for not_none/or_none
635 # default ExprNode or None
636 # default_value PyObjectConst constant for default value
637 # annotation ExprNode or None Py3 function arg annotation
638 # is_self_arg boolean Is the "self" arg of an extension type method
639 # is_type_arg boolean Is the "class" arg of an extension type classmethod
640 # is_kw_only boolean Is a keyword-only argument
642 child_attrs = ["base_type", "declarator", "default"]
648 name_declarator = None
652 def analyse(self, env, nonempty = 0):
653 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
654 if self.type is None:
655 # The parser may missinterpret names as types...
657 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
659 self.declarator.name = self.base_type.name
660 self.base_type.name = None
661 self.base_type.is_basic_c_type = False
664 could_be_name = False
665 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
666 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
667 self.declarator.name = self.base_type.arg_name
668 # The parser is unable to resolve the ambiguity of [] as part of the
669 # type (e.g. in buffers) or empty declarator (as with arrays).
670 # This is only arises for empty multi-dimensional arrays.
671 if (base_type.is_array
672 and isinstance(self.base_type, TemplatedTypeNode)
673 and isinstance(self.declarator, CArrayDeclaratorNode)):
674 declarator = self.declarator
675 while isinstance(declarator.base, CArrayDeclaratorNode):
676 declarator = declarator.base
677 declarator.base = self.base_type.array_declarator
678 base_type = base_type.base_type
679 return self.declarator.analyse(base_type, env, nonempty = nonempty)
681 return self.name_declarator, self.type
683 def calculate_default_value_code(self, code):
684 if self.default_value is None:
686 if self.default.is_literal:
687 # will not output any code, just assign the result_code
688 self.default.generate_evaluation_code(code)
689 return self.type.cast_code(self.default.result())
690 self.default_value = code.get_argument_default_const(self.type)
691 return self.default_value
693 def annotate(self, code):
695 self.default.annotate(code)
698 class CBaseTypeNode(Node):
699 # Abstract base class for C base type nodes.
701 # Processing during analyse_declarations phase:
708 def analyse_as_type(self, env):
709 return self.analyse(env)
711 class CAnalysedBaseTypeNode(Node):
716 def analyse(self, env, could_be_name = False):
719 class CSimpleBaseTypeNode(CBaseTypeNode):
721 # module_path [string] Qualifying name components
722 # is_basic_c_type boolean
726 # is_self_arg boolean Is self argument of C method
727 # ##is_type_arg boolean Is type argument of class method
730 arg_name = None # in case the argument name was interpreted as a type
732 def analyse(self, env, could_be_name = False):
733 # Return type descriptor.
734 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
736 if self.is_basic_c_type:
737 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
739 error(self.pos, "Unrecognised type modifier combination")
740 elif self.name == "object" and not self.module_path:
741 type = py_object_type
742 elif self.name is None:
743 if self.is_self_arg and env.is_c_class_scope:
744 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
745 type = env.parent_type
746 ## elif self.is_type_arg and env.is_c_class_scope:
747 ## type = Builtin.type_type
749 type = py_object_type
752 scope = env.find_imported_module(self.module_path, self.pos)
756 if scope.is_c_class_scope:
757 scope = scope.global_scope()
758 entry = scope.lookup(self.name)
759 if entry and entry.is_type:
762 if self.is_self_arg and env.is_c_class_scope:
763 type = env.parent_type
764 ## elif self.is_type_arg and env.is_c_class_scope:
765 ## type = Builtin.type_type
767 type = py_object_type
768 self.arg_name = self.name
771 if not self.name in self.templates:
772 error(self.pos, "'%s' is not a type identifier" % self.name)
773 type = PyrexTypes.TemplatePlaceholderType(self.name)
775 error(self.pos, "'%s' is not a type identifier" % self.name)
777 if not type.is_numeric or type.is_complex:
778 error(self.pos, "can only complexify c numeric types")
779 type = PyrexTypes.CComplexType(type)
780 type.create_declaration_utility_code(env)
784 return PyrexTypes.error_type
786 class CNestedBaseTypeNode(CBaseTypeNode):
787 # For C++ classes that live inside other C++ classes.
790 # base_type CBaseTypeNode
792 child_attrs = ['base_type']
794 def analyse(self, env, could_be_name = None):
795 base_type = self.base_type.analyse(env)
796 if base_type is PyrexTypes.error_type:
797 return PyrexTypes.error_type
798 if not base_type.is_cpp_class:
799 error(self.pos, "'%s' is not a valid type scope" % base_type)
800 return PyrexTypes.error_type
801 type_entry = base_type.scope.lookup_here(self.name)
802 if not type_entry or not type_entry.is_type:
803 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
804 return PyrexTypes.error_type
805 return type_entry.type
807 class TemplatedTypeNode(CBaseTypeNode):
809 # positional_args [ExprNode] List of positional arguments
810 # keyword_args DictNode Keyword arguments
811 # base_type_node CBaseTypeNode
814 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
817 child_attrs = ["base_type_node", "positional_args",
818 "keyword_args", "dtype_node"]
824 def analyse(self, env, could_be_name = False, base_type = None):
825 if base_type is None:
826 base_type = self.base_type_node.analyse(env)
827 if base_type.is_error: return base_type
829 if base_type.is_cpp_class:
831 if self.keyword_args and self.keyword_args.key_value_pairs:
832 error(self.pos, "c++ templates cannot take keyword arguments");
833 self.type = PyrexTypes.error_type
836 for template_node in self.positional_args:
837 type = template_node.analyse_as_type(env)
839 error(template_node.pos, "unknown type in template argument")
841 template_types.append(type)
842 self.type = base_type.specialize_here(self.pos, template_types)
844 elif base_type.is_pyobject:
848 options = Buffer.analyse_buffer_options(
851 self.positional_args,
853 base_type.buffer_defaults)
855 if sys.version_info[0] < 3:
856 # Py 2.x enforces byte strings as keyword arguments ...
857 options = dict([ (name.encode('ASCII'), value)
858 for name, value in options.iteritems() ])
860 self.type = PyrexTypes.BufferType(base_type, **options)
864 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
865 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
866 error(self.pos, "invalid array declaration")
867 self.type = PyrexTypes.error_type
869 # It would be nice to merge this class with CArrayDeclaratorNode,
870 # but arrays are part of the declaration, not the type...
871 if not self.positional_args:
874 dimension = self.positional_args[0]
875 self.array_declarator = CArrayDeclaratorNode(self.pos,
876 base = empty_declarator,
877 dimension = dimension)
878 self.type = self.array_declarator.analyse(base_type, env)[1]
882 class CComplexBaseTypeNode(CBaseTypeNode):
883 # base_type CBaseTypeNode
884 # declarator CDeclaratorNode
886 child_attrs = ["base_type", "declarator"]
888 def analyse(self, env, could_be_name = False):
889 base = self.base_type.analyse(env, could_be_name)
890 _, type = self.declarator.analyse(base, env)
894 class CVarDefNode(StatNode):
895 # C variable definition or forward/extern function declaration.
897 # visibility 'private' or 'public' or 'extern'
898 # base_type CBaseTypeNode
899 # declarators [CDeclaratorNode]
904 # decorators [cython.locals(...)] or None
905 # directive_locals { string : NameNode } locals defined by cython.locals(...)
907 child_attrs = ["base_type", "declarators"]
911 directive_locals = {}
913 def analyse_declarations(self, env, dest_scope = None):
916 self.dest_scope = dest_scope
917 base_type = self.base_type.analyse(env)
919 # If the field is an external typedef, we cannot be sure about the type,
920 # so do conversion ourself rather than rely on the CPython mechanism (through
921 # a property; made in AnalyseDeclarationsTransform).
922 if (dest_scope.is_c_class_scope
923 and self.visibility in ('public', 'readonly')):
927 need_property = False
928 visibility = self.visibility
930 for declarator in self.declarators:
931 name_declarator, type = declarator.analyse(base_type, env)
932 if not type.is_complete():
933 if not (self.visibility == 'extern' and type.is_array):
934 error(declarator.pos,
935 "Variable type '%s' is incomplete" % type)
936 if self.visibility == 'extern' and type.is_pyobject:
937 error(declarator.pos,
938 "Python object cannot be declared extern")
939 name = name_declarator.name
940 cname = name_declarator.cname
942 error(declarator.pos, "Missing name in declaration.")
944 if type.is_cfunction:
945 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
948 if entry is not None:
949 entry.directive_locals = self.directive_locals
951 if self.directive_locals:
952 s.error("Decorators can only be followed by functions")
953 if self.in_pxd and self.visibility != 'extern':
955 "Only 'extern' C variable declaration allowed in .pxd file")
956 entry = dest_scope.declare_var(name, type, declarator.pos,
957 cname = cname, visibility = visibility, is_cdef = 1)
959 self.properties.append(entry)
962 class CStructOrUnionDefNode(StatNode):
964 # cname string or None
965 # kind "struct" or "union"
966 # typedef_flag boolean
967 # visibility "public" or "private"
969 # attributes [CVarDefNode] or None
973 child_attrs = ["attributes"]
975 def analyse_declarations(self, env):
977 if self.visibility == 'extern' and self.packed:
978 error(self.pos, "Cannot declare extern struct as 'packed'")
979 if self.attributes is not None:
980 scope = StructOrUnionScope(self.name)
981 self.entry = env.declare_struct_or_union(
982 self.name, self.kind, scope, self.typedef_flag, self.pos,
983 self.cname, visibility = self.visibility, packed = self.packed)
984 if self.attributes is not None:
985 if self.in_pxd and not env.in_cinclude:
986 self.entry.defined_in_pxd = 1
987 for attr in self.attributes:
988 attr.analyse_declarations(env, scope)
989 if self.visibility != 'extern':
990 need_typedef_indirection = False
991 for attr in scope.var_entries:
994 type = type.base_type
995 if type == self.entry.type:
996 error(attr.pos, "Struct cannot contain itself as a member.")
997 if self.typedef_flag:
999 type = type.base_type
1000 if type == self.entry.type:
1001 need_typedef_indirection = True
1002 if need_typedef_indirection:
1003 # C can't handle typedef structs that refer to themselves.
1004 struct_entry = self.entry
1005 self.entry = env.declare_typedef(
1006 self.name, struct_entry.type, self.pos,
1007 cname = self.cname, visibility='ignore')
1008 struct_entry.type.typedef_flag = False
1009 # FIXME: this might be considered a hack ;-)
1010 struct_entry.cname = struct_entry.type.cname = \
1011 '_' + self.entry.type.typedef_cname
1013 def analyse_expressions(self, env):
1016 def generate_execution_code(self, code):
1020 class CppClassNode(CStructOrUnionDefNode):
1023 # cname string or None
1024 # visibility "extern"
1026 # attributes [CVarDefNode] or None
1028 # base_classes [string]
1029 # templates [string] or None
1031 def analyse_declarations(self, env):
1033 if self.attributes is not None:
1034 scope = CppClassScope(self.name, env)
1035 base_class_types = []
1036 for base_class_name in self.base_classes:
1037 base_class_entry = env.lookup(base_class_name)
1038 if base_class_entry is None:
1039 error(self.pos, "'%s' not found" % base_class_name)
1040 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1041 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1043 base_class_types.append(base_class_entry.type)
1044 if self.templates is None:
1045 template_types = None
1047 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1048 self.entry = env.declare_cpp_class(
1049 self.name, scope, self.pos,
1050 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1051 self.entry.is_cpp_class = 1
1052 if self.attributes is not None:
1053 if self.in_pxd and not env.in_cinclude:
1054 self.entry.defined_in_pxd = 1
1055 for attr in self.attributes:
1056 attr.analyse_declarations(scope)
1058 class CEnumDefNode(StatNode):
1059 # name string or None
1060 # cname string or None
1061 # items [CEnumDefItemNode]
1062 # typedef_flag boolean
1063 # visibility "public" or "private"
1067 child_attrs = ["items"]
1069 def analyse_declarations(self, env):
1070 self.entry = env.declare_enum(self.name, self.pos,
1071 cname = self.cname, typedef_flag = self.typedef_flag,
1072 visibility = self.visibility)
1073 if self.items is not None:
1074 if self.in_pxd and not env.in_cinclude:
1075 self.entry.defined_in_pxd = 1
1076 for item in self.items:
1077 item.analyse_declarations(env, self.entry)
1079 def analyse_expressions(self, env):
1082 def generate_execution_code(self, code):
1083 if self.visibility == 'public':
1084 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1085 for item in self.entry.enum_values:
1086 code.putln("%s = PyInt_FromLong(%s); %s" % (
1089 code.error_goto_if_null(temp, item.pos)))
1090 code.put_gotref(temp)
1091 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1092 Naming.module_cname,
1095 code.error_goto(item.pos)))
1096 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1097 code.funcstate.release_temp(temp)
1100 class CEnumDefItemNode(StatNode):
1102 # cname string or None
1103 # value ExprNode or None
1105 child_attrs = ["value"]
1107 def analyse_declarations(self, env, enum_entry):
1109 self.value.analyse_const_expression(env)
1110 if not self.value.type.is_int:
1111 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1112 self.value.analyse_const_expression(env)
1113 entry = env.declare_const(self.name, enum_entry.type,
1114 self.value, self.pos, cname = self.cname,
1115 visibility = enum_entry.visibility)
1116 enum_entry.enum_values.append(entry)
1119 class CTypeDefNode(StatNode):
1120 # base_type CBaseTypeNode
1121 # declarator CDeclaratorNode
1122 # visibility "public" or "private"
1125 child_attrs = ["base_type", "declarator"]
1127 def analyse_declarations(self, env):
1128 base = self.base_type.analyse(env)
1129 name_declarator, type = self.declarator.analyse(base, env)
1130 name = name_declarator.name
1131 cname = name_declarator.cname
1132 entry = env.declare_typedef(name, type, self.pos,
1133 cname = cname, visibility = self.visibility)
1134 if self.in_pxd and not env.in_cinclude:
1135 entry.defined_in_pxd = 1
1137 def analyse_expressions(self, env):
1139 def generate_execution_code(self, code):
1143 class FuncDefNode(StatNode, BlockNode):
1144 # Base class for function definition nodes.
1146 # return_type PyrexType
1147 # #filename string C name of filename string const
1148 # entry Symtab.Entry
1149 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1150 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1154 needs_closure = False
1157 def analyse_default_values(self, env):
1158 genv = env.global_scope()
1160 for arg in self.args:
1164 arg.default.analyse_types(env)
1165 arg.default = arg.default.coerce_to(arg.type, genv)
1168 "This argument cannot have a default value")
1173 error(arg.pos, "Non-default argument following default argument")
1175 def need_gil_acquisition(self, lenv):
1178 def create_local_scope(self, env):
1180 while genv.is_py_class_scope or genv.is_c_class_scope:
1181 genv = env.outer_scope
1182 if self.needs_closure:
1183 lenv = ClosureScope(name=self.entry.name,
1185 scope_name=self.entry.cname)
1187 lenv = LocalScope(name=self.entry.name,
1190 lenv.return_type = self.return_type
1191 type = self.entry.type
1192 if type.is_cfunction:
1193 lenv.nogil = type.nogil and not type.with_gil
1194 self.local_scope = lenv
1195 lenv.directives = env.directives
1198 def generate_function_definitions(self, env, code):
1201 lenv = self.local_scope
1202 if lenv.is_closure_scope:
1203 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1204 Naming.outer_scope_cname)
1206 outer_scope_cname = Naming.outer_scope_cname
1207 lenv.mangle_closure_cnames(outer_scope_cname)
1208 # Generate closure function definitions
1209 self.body.generate_function_definitions(lenv, code)
1210 # generate lambda function definitions
1211 for node in lenv.lambda_defs:
1212 node.generate_function_definitions(lenv, code)
1214 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1215 self.entry.scope.is_c_class_scope)
1216 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1217 self.entry.scope.is_c_class_scope)
1218 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1220 if 'cython_unused' not in self.modifiers:
1221 self.modifiers = self.modifiers + ['cython_unused']
1223 profile = code.globalstate.directives['profile']
1226 error(self.pos, "Cannot profile nogil function.")
1227 code.globalstate.use_utility_code(profile_utility_code)
1229 # Generate C code for header and body of function
1230 code.enter_cfunc_scope()
1231 code.return_from_error_cleanup_label = code.new_label()
1233 # ----- Top-level constants used by this function
1234 code.mark_pos(self.pos)
1235 self.generate_cached_builtins_decls(lenv, code)
1236 # ----- Function header
1238 with_pymethdef = self.needs_assignment_synthesis(env, code)
1240 self.py_func.generate_function_header(code,
1241 with_pymethdef = with_pymethdef,
1243 self.generate_function_header(code,
1244 with_pymethdef = with_pymethdef)
1245 # ----- Local variable declarations
1246 if lenv.is_closure_scope:
1247 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1249 elif env.is_closure_scope:
1250 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1252 self.generate_argument_declarations(lenv, code)
1253 for entry in lenv.var_entries:
1254 if not entry.in_closure:
1255 code.put_var_declaration(entry)
1257 if not self.return_type.is_void:
1258 if self.return_type.is_pyobject:
1262 (self.return_type.declaration_code(Naming.retval_cname),
1264 tempvardecl_code = code.insertion_point()
1265 self.generate_keyword_list(code)
1267 code.put_trace_declarations()
1268 # ----- Extern library function declarations
1269 lenv.generate_library_function_declarations(code)
1270 # ----- GIL acquisition
1271 acquire_gil = self.acquire_gil
1273 env.use_utility_code(force_init_threads_utility_code)
1274 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1275 # ----- set up refnanny
1277 code.put_setup_refcount_context(self.entry.name)
1278 # ----- Automatic lead-ins for certain special functions
1279 if is_getbuffer_slot:
1280 self.getbuffer_init(code)
1281 # ----- Create closure scope object
1282 if self.needs_closure:
1283 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1284 Naming.cur_scope_cname,
1285 lenv.scope_class.type.declaration_code(''),
1286 lenv.scope_class.type.typeptr_cname,
1287 lenv.scope_class.type.typeptr_cname,
1288 Naming.empty_tuple))
1289 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1290 if is_getbuffer_slot:
1291 self.getbuffer_error_cleanup(code)
1293 code.put_finish_refcount_context()
1294 # FIXME: what if the error return value is a Python value?
1295 code.putln("return %s;" % self.error_value())
1297 code.put_gotref(Naming.cur_scope_cname)
1298 # Note that it is unsafe to decref the scope at this point.
1299 if env.is_closure_scope:
1300 code.putln("%s = (%s)%s;" % (
1302 env.scope_class.type.declaration_code(''),
1304 if self.needs_closure:
1305 # inner closures own a reference to their outer parent
1306 code.put_incref(outer_scope_cname, env.scope_class.type)
1307 code.put_giveref(outer_scope_cname)
1308 # ----- Trace function call
1310 # this looks a bit late, but if we don't get here due to a
1311 # fatal error before hand, it's not really worth tracing
1312 code.put_trace_call(self.entry.name, self.pos)
1313 # ----- Fetch arguments
1314 self.generate_argument_parsing_code(env, code)
1315 # If an argument is assigned to in the body, we must
1316 # incref it to properly keep track of refcounts.
1317 for entry in lenv.arg_entries:
1318 if entry.type.is_pyobject:
1319 if entry.assignments and not entry.in_closure:
1320 code.put_var_incref(entry)
1321 # ----- Initialise local variables
1322 for entry in lenv.var_entries:
1323 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1324 code.put_init_var_to_py_none(entry)
1325 # ----- Initialise local buffer auxiliary variables
1326 for entry in lenv.var_entries + lenv.arg_entries:
1327 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1328 code.putln("%s.buf = NULL;" %
1329 entry.buffer_aux.buffer_info_var.cname)
1330 # ----- Check and convert arguments
1331 self.generate_argument_type_tests(code)
1332 # ----- Acquire buffer arguments
1333 for entry in lenv.arg_entries:
1334 if entry.type.is_buffer:
1335 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1337 # -------------------------
1338 # ----- Function body -----
1339 # -------------------------
1340 self.body.generate_execution_code(code)
1342 # ----- Default return value
1344 if self.return_type.is_pyobject:
1345 #if self.return_type.is_extension_type:
1346 # lhs = "(PyObject *)%s" % Naming.retval_cname
1348 lhs = Naming.retval_cname
1349 code.put_init_to_py_none(lhs, self.return_type)
1351 val = self.return_type.default_value
1353 code.putln("%s = %s;" % (Naming.retval_cname, val))
1354 # ----- Error cleanup
1355 if code.error_label in code.labels_used:
1356 code.put_goto(code.return_label)
1357 code.put_label(code.error_label)
1358 for cname, type in code.funcstate.all_managed_temps():
1359 code.put_xdecref(cname, type)
1361 # Clean up buffers -- this calls a Python function
1362 # so need to save and restore error state
1363 buffers_present = len(lenv.buffer_entries) > 0
1365 code.globalstate.use_utility_code(restore_exception_utility_code)
1366 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1367 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1368 for entry in lenv.buffer_entries:
1369 Buffer.put_release_buffer_code(code, entry)
1370 #code.putln("%s = 0;" % entry.cname)
1371 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1373 err_val = self.error_value()
1374 exc_check = self.caller_will_check_exceptions()
1375 if err_val is not None or exc_check:
1376 # TODO: Fix exception tracing (though currently unused by cProfile).
1377 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1378 # code.put_trace_exception()
1379 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1381 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1382 % self.entry.qualified_name, 0)
1384 '__Pyx_WriteUnraisable("%s");' %
1385 self.entry.qualified_name)
1386 env.use_utility_code(unraisable_exception_utility_code)
1387 env.use_utility_code(restore_exception_utility_code)
1388 default_retval = self.return_type.default_value
1389 if err_val is None and default_retval:
1390 err_val = default_retval
1391 if err_val is not None:
1392 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1394 if is_getbuffer_slot:
1395 self.getbuffer_error_cleanup(code)
1397 # If we are using the non-error cleanup section we should
1398 # jump past it if we have an error. The if-test below determine
1399 # whether this section is used.
1400 if buffers_present or is_getbuffer_slot:
1401 code.put_goto(code.return_from_error_cleanup_label)
1404 # ----- Non-error return cleanup
1405 code.put_label(code.return_label)
1406 for entry in lenv.buffer_entries:
1408 Buffer.put_release_buffer_code(code, entry)
1409 if is_getbuffer_slot:
1410 self.getbuffer_normal_cleanup(code)
1411 # ----- Return cleanup for both error and no-error return
1412 code.put_label(code.return_from_error_cleanup_label)
1413 if not Options.init_local_none:
1414 for entry in lenv.var_entries:
1415 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1416 entry.xdecref_cleanup = 1
1418 for entry in lenv.var_entries:
1419 if entry.type.is_pyobject:
1420 if entry.used and not entry.in_closure:
1421 code.put_var_decref(entry)
1422 elif entry.in_closure and self.needs_closure:
1423 code.put_giveref(entry.cname)
1424 # Decref any increfed args
1425 for entry in lenv.arg_entries:
1426 if entry.type.is_pyobject:
1427 if entry.in_closure:
1428 code.put_var_giveref(entry)
1429 elif entry.assignments:
1430 code.put_var_decref(entry)
1431 if self.needs_closure:
1432 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1435 # This code is duplicated in ModuleNode.generate_module_init_func
1437 default_retval = self.return_type.default_value
1438 err_val = self.error_value()
1439 if err_val is None and default_retval:
1440 err_val = default_retval
1441 if self.return_type.is_pyobject:
1442 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1444 if self.entry.is_special and self.entry.name == "__hash__":
1445 # Returning -1 for __hash__ is supposed to signal an error
1446 # We do as Python instances and coerce -1 into -2.
1447 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1448 Naming.retval_cname, Naming.retval_cname))
1451 if self.return_type.is_pyobject:
1452 code.put_trace_return(Naming.retval_cname)
1454 code.put_trace_return("Py_None")
1456 code.put_finish_refcount_context()
1459 code.putln("PyGILState_Release(_save);")
1461 if not self.return_type.is_void:
1462 code.putln("return %s;" % Naming.retval_cname)
1465 # ----- Go back and insert temp variable declarations
1466 tempvardecl_code.put_temp_declarations(code.funcstate)
1467 # ----- Python version
1468 code.exit_cfunc_scope()
1470 self.py_func.generate_function_definitions(env, code)
1471 self.generate_wrapper_functions(code)
1473 def declare_argument(self, env, arg):
1474 if arg.type.is_void:
1475 error(arg.pos, "Invalid use of 'void'")
1476 elif not arg.type.is_complete() and not arg.type.is_array:
1478 "Argument type '%s' is incomplete" % arg.type)
1479 return env.declare_arg(arg.name, arg.type, arg.pos)
1481 def generate_arg_type_test(self, arg, code):
1482 # Generate type test for one argument.
1483 if arg.type.typeobj_is_available():
1484 code.globalstate.use_utility_code(arg_type_test_utility_code)
1485 typeptr_cname = arg.type.typeptr_cname
1486 arg_code = "((PyObject *)%s)" % arg.entry.cname
1488 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1493 arg.type.is_builtin_type,
1494 code.error_goto(arg.pos)))
1496 error(arg.pos, "Cannot test type of extern C class "
1497 "without type object name specification")
1499 def generate_arg_none_check(self, arg, code):
1500 # Generate None check for one argument.
1501 code.globalstate.use_utility_code(arg_type_test_utility_code)
1502 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1503 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1505 code.error_goto(arg.pos)))
1508 def generate_wrapper_functions(self, code):
1511 def generate_execution_code(self, code):
1512 # Evaluate and store argument default values
1513 for arg in self.args:
1514 default = arg.default
1516 if not default.is_literal:
1517 default.generate_evaluation_code(code)
1518 default.make_owned_reference(code)
1519 result = default.result_as(arg.type)
1522 arg.calculate_default_value_code(code),
1524 if arg.type.is_pyobject:
1525 code.put_giveref(default.result())
1526 default.generate_post_assignment_code(code)
1527 default.free_temps(code)
1528 # For Python class methods, create and store function object
1530 self.assmt.generate_execution_code(code)
1533 # Special code for the __getbuffer__ function
1535 def getbuffer_init(self, code):
1536 info = self.local_scope.arg_entries[1].cname
1537 # Python 3.0 betas have a bug in memoryview which makes it call
1538 # getbuffer with a NULL parameter. For now we work around this;
1539 # the following line should be removed when this bug is fixed.
1540 code.putln("if (%s == NULL) return 0;" % info)
1541 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1542 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1544 def getbuffer_error_cleanup(self, code):
1545 info = self.local_scope.arg_entries[1].cname
1546 code.put_gotref("%s->obj" % info)
1547 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1550 def getbuffer_normal_cleanup(self, code):
1551 info = self.local_scope.arg_entries[1].cname
1552 code.putln("if (%s->obj == Py_None) {" % info)
1553 code.put_gotref("Py_None")
1554 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1557 class CFuncDefNode(FuncDefNode):
1558 # C function definition.
1560 # modifiers ['inline']
1561 # visibility 'private' or 'public' or 'extern'
1562 # base_type CBaseTypeNode
1563 # declarator CDeclaratorNode
1566 # decorators [DecoratorNode] list of decorators
1568 # with_gil boolean Acquire GIL around body
1570 # py_func wrapper for calling from Python
1571 # overridable whether or not this is a cpdef function
1572 # inline_in_pxd whether this is an inline function in a pxd file
1574 child_attrs = ["base_type", "declarator", "body", "py_func"]
1576 inline_in_pxd = False
1578 directive_locals = {}
1580 def unqualified_name(self):
1581 return self.entry.name
1583 def analyse_declarations(self, env):
1584 self.directive_locals.update(env.directives['locals'])
1585 base_type = self.base_type.analyse(env)
1586 # The 2 here is because we need both function and argument names.
1587 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1588 if not type.is_cfunction:
1590 "Suite attached to non-function declaration")
1591 # Remember the actual type according to the function header
1592 # written here, because the type in the symbol table entry
1593 # may be different if we're overriding a C method inherited
1594 # from the base type of an extension type.
1596 type.is_overridable = self.overridable
1597 declarator = self.declarator
1598 while not hasattr(declarator, 'args'):
1599 declarator = declarator.base
1600 self.args = declarator.args
1601 for formal_arg, type_arg in zip(self.args, type.args):
1602 formal_arg.type = type_arg.type
1603 formal_arg.name = type_arg.name
1604 formal_arg.cname = type_arg.cname
1605 name = name_declarator.name
1606 cname = name_declarator.cname
1607 self.entry = env.declare_cfunction(
1608 name, type, self.pos,
1609 cname = cname, visibility = self.visibility,
1610 defining = self.body is not None,
1611 api = self.api, modifiers = self.modifiers)
1612 self.entry.inline_func_in_pxd = self.inline_in_pxd
1613 self.return_type = type.return_type
1615 if self.overridable and not env.is_module_scope:
1616 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1617 # An error will be produced in the cdef function
1618 self.overridable = False
1620 if self.overridable:
1622 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1623 self.py_func = DefNode(pos = self.pos,
1624 name = self.entry.name,
1627 starstar_arg = None,
1629 body = py_func_body,
1631 self.py_func.is_module_scope = env.is_module_scope
1632 self.py_func.analyse_declarations(env)
1633 self.entry.as_variable = self.py_func.entry
1634 # Reset scope entry the above cfunction
1635 env.entries[name] = self.entry
1636 if not env.is_module_scope or Options.lookup_module_cpdef:
1637 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1638 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1639 self.create_local_scope(env)
1641 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1643 args = self.type.args
1644 if omit_optional_args:
1645 args = args[:len(args) - self.type.optional_arg_count]
1646 arg_names = [arg.name for arg in args]
1648 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1650 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1651 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1652 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1653 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)
1654 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1656 def declare_arguments(self, env):
1657 for arg in self.type.args:
1659 error(arg.pos, "Missing argument name")
1660 self.declare_argument(env, arg)
1662 def need_gil_acquisition(self, lenv):
1663 return self.type.with_gil
1665 def nogil_check(self, env):
1667 with_gil = type.with_gil
1668 if type.nogil and not with_gil:
1669 if type.return_type.is_pyobject:
1671 "Function with Python return type cannot be declared nogil")
1672 for entry in self.local_scope.var_entries:
1673 if entry.type.is_pyobject:
1674 error(self.pos, "Function declared nogil has Python locals or temporaries")
1676 def analyse_expressions(self, env):
1677 self.local_scope.directives = env.directives
1678 if self.py_func is not None:
1679 # this will also analyse the default values
1680 self.py_func.analyse_expressions(env)
1682 self.analyse_default_values(env)
1683 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1685 def needs_assignment_synthesis(self, env, code=None):
1688 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1691 visibility = self.entry.visibility
1692 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1693 arg_decls.append(arg.declaration_code())
1694 if with_dispatch and self.overridable:
1695 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1696 if type.optional_arg_count and with_opt_args:
1697 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1698 if type.has_varargs:
1699 arg_decls.append("...")
1701 arg_decls = ["void"]
1703 cname = self.entry.func_cname
1704 entity = type.function_header_code(cname, ', '.join(arg_decls))
1705 if visibility == 'public':
1706 dll_linkage = "DL_EXPORT"
1709 header = self.return_type.declaration_code(entity,
1710 dll_linkage = dll_linkage)
1711 if visibility == 'extern':
1712 storage_class = "%s " % Naming.extern_c_macro
1713 elif visibility == 'public':
1716 storage_class = "static "
1717 if 'inline' in self.modifiers:
1718 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1719 code.putln("%s%s %s {" % (
1721 ' '.join(self.modifiers).upper(), # macro forms
1724 def generate_argument_declarations(self, env, code):
1725 for arg in self.args:
1727 result = arg.calculate_default_value_code(code)
1728 code.putln('%s = %s;' % (
1729 arg.type.declaration_code(arg.cname), result))
1731 def generate_keyword_list(self, code):
1734 def generate_argument_parsing_code(self, env, code):
1736 if self.type.optional_arg_count:
1737 code.putln('if (%s) {' % Naming.optional_args_cname)
1738 for arg in self.args:
1740 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1741 declarator = arg.declarator
1742 while not hasattr(declarator, 'name'):
1743 declarator = declarator.base
1744 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1746 for _ in range(self.type.optional_arg_count):
1750 def generate_argument_conversion_code(self, code):
1753 def generate_argument_type_tests(self, code):
1754 # Generate type tests for args whose type in a parent
1755 # class is a supertype of the declared type.
1756 for arg in self.type.args:
1757 if arg.needs_type_test:
1758 self.generate_arg_type_test(arg, code)
1759 elif arg.type.is_pyobject and not arg.accept_none:
1760 self.generate_arg_none_check(arg, code)
1762 def error_value(self):
1763 if self.return_type.is_pyobject:
1767 return self.entry.type.exception_value
1769 def caller_will_check_exceptions(self):
1770 return self.entry.type.exception_check
1772 def generate_wrapper_functions(self, code):
1773 # If the C signature of a function has changed, we need to generate
1774 # wrappers to put in the slots here.
1777 func_type = entry.type
1778 while entry.prev_entry is not None:
1780 entry = entry.prev_entry
1781 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1783 self.generate_function_header(code,
1785 with_dispatch = entry.type.is_overridable,
1786 with_opt_args = entry.type.optional_arg_count,
1787 cname = entry.func_cname)
1788 if not self.return_type.is_void:
1790 args = self.type.args
1791 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1792 if entry.type.is_overridable:
1793 arglist.append(Naming.skip_dispatch_cname)
1794 elif func_type.is_overridable:
1796 if entry.type.optional_arg_count:
1797 arglist.append(Naming.optional_args_cname)
1798 elif func_type.optional_arg_count:
1799 arglist.append('NULL')
1800 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1804 class PyArgDeclNode(Node):
1805 # Argument which must be a Python object (used
1806 # for * and ** arguments).
1809 # entry Symtab.Entry
1810 # annotation ExprNode or None Py3 argument annotation
1813 def generate_function_definitions(self, env, code):
1814 self.entry.generate_function_definitions(env, code)
1816 class DecoratorNode(Node):
1819 # decorator NameNode or CallNode or AttributeNode
1820 child_attrs = ['decorator']
1823 class DefNode(FuncDefNode):
1824 # A Python function definition.
1826 # name string the Python name of the function
1827 # lambda_name string the internal name of a lambda 'function'
1828 # decorators [DecoratorNode] list of decorators
1829 # args [CArgDeclNode] formal arguments
1830 # star_arg PyArgDeclNode or None * argument
1831 # starstar_arg PyArgDeclNode or None ** argument
1832 # doc EncodedString or None
1834 # return_type_annotation
1835 # ExprNode or None the Py3 return type annotation
1837 # The following subnode is constructed internally
1838 # when the def statement is inside a Python class definition.
1840 # assmt AssignmentNode Function construction/assignment
1842 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1847 num_required_kw_args = 0
1848 reqd_kw_flags_cname = "0"
1851 return_type_annotation = None
1856 def __init__(self, pos, **kwds):
1857 FuncDefNode.__init__(self, pos, **kwds)
1859 for arg in self.args:
1866 self.num_kwonly_args = k
1867 self.num_required_kw_args = rk
1868 self.num_required_args = r
1870 def as_cfunction(self, cfunc=None, scope=None):
1872 error(self.star_arg.pos, "cdef function cannot have star argument")
1873 if self.starstar_arg:
1874 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1877 for formal_arg in self.args:
1878 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1879 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1881 type = py_object_type,
1882 pos = formal_arg.pos))
1883 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1885 has_varargs = False,
1886 exception_value = None,
1887 exception_check = False,
1890 is_overridable = True)
1891 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1893 cfunc_type = cfunc.type
1894 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1895 error(self.pos, "wrong number of arguments")
1896 error(cfunc.pos, "previous declaration here")
1897 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1898 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1899 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1900 formal_arg.type = type_arg.type
1901 formal_arg.name_declarator = name_declarator
1903 if cfunc_type.exception_value is None:
1904 exception_value = None
1906 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1907 declarator = CFuncDeclaratorNode(self.pos,
1908 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1910 has_varargs = False,
1911 exception_check = cfunc_type.exception_check,
1912 exception_value = exception_value,
1913 with_gil = cfunc_type.with_gil,
1914 nogil = cfunc_type.nogil)
1915 return CFuncDefNode(self.pos,
1917 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1918 declarator = declarator,
1921 overridable = cfunc_type.is_overridable,
1923 with_gil = cfunc_type.with_gil,
1924 nogil = cfunc_type.nogil,
1925 visibility = 'private',
1927 directive_locals = getattr(cfunc, 'directive_locals', {}))
1929 def analyse_declarations(self, env):
1930 self.is_classmethod = self.is_staticmethod = False
1932 for decorator in self.decorators:
1933 func = decorator.decorator
1935 self.is_classmethod |= func.name == 'classmethod'
1936 self.is_staticmethod |= func.name == 'staticmethod'
1938 if self.is_classmethod and env.lookup_here('classmethod'):
1939 # classmethod() was overridden - not much we can do here ...
1940 self.is_classmethod = False
1941 if self.is_staticmethod and env.lookup_here('staticmethod'):
1942 # staticmethod() was overridden - not much we can do here ...
1943 self.is_staticmethod = False
1945 self.analyse_argument_types(env)
1946 if self.name == '<lambda>':
1947 self.declare_lambda_function(env)
1949 self.declare_pyfunction(env)
1950 self.analyse_signature(env)
1951 self.return_type = self.entry.signature.return_type()
1952 self.create_local_scope(env)
1954 def analyse_argument_types(self, env):
1955 directive_locals = self.directive_locals = env.directives['locals']
1956 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1957 for arg in self.args:
1958 if hasattr(arg, 'name'):
1960 name_declarator = None
1962 base_type = arg.base_type.analyse(env)
1963 name_declarator, type = \
1964 arg.declarator.analyse(base_type, env)
1965 arg.name = name_declarator.name
1966 if arg.name in directive_locals:
1967 type_node = directive_locals[arg.name]
1968 other_type = type_node.analyse_as_type(env)
1969 if other_type is None:
1970 error(type_node.pos, "Not a type")
1971 elif (type is not PyrexTypes.py_object_type
1972 and not type.same_as(other_type)):
1973 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1974 error(type_node.pos, "Previous declaration here")
1977 if name_declarator and name_declarator.cname:
1979 "Python function argument cannot have C name specification")
1980 arg.type = type.as_argument_type()
1982 arg.needs_conversion = 0
1983 arg.needs_type_test = 0
1985 if arg.type.is_pyobject:
1987 arg.accept_none = True
1989 arg.accept_none = False
1990 elif arg.type.is_extension_type or arg.type.is_builtin_type:
1991 if arg.default and arg.default.constant_result is None:
1992 # special case: def func(MyType obj = None)
1993 arg.accept_none = True
1995 # default depends on compiler directive
1996 arg.accept_none = allow_none_for_extension_args
1998 # probably just a plain 'object'
1999 arg.accept_none = True
2001 arg.accept_none = True # won't be used, but must be there
2003 error(arg.pos, "Only Python type arguments can have 'not None'")
2005 error(arg.pos, "Only Python type arguments can have 'or None'")
2007 def analyse_signature(self, env):
2008 if self.entry.is_special:
2009 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2010 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2011 # Use the simpler calling signature for zero- and one-argument functions.
2012 if self.entry.signature is TypeSlots.pyfunction_signature:
2013 if len(self.args) == 0:
2014 self.entry.signature = TypeSlots.pyfunction_noargs
2015 elif len(self.args) == 1:
2016 if self.args[0].default is None and not self.args[0].kw_only:
2017 self.entry.signature = TypeSlots.pyfunction_onearg
2018 elif self.entry.signature is TypeSlots.pymethod_signature:
2019 if len(self.args) == 1:
2020 self.entry.signature = TypeSlots.unaryfunc
2021 elif len(self.args) == 2:
2022 if self.args[1].default is None and not self.args[1].kw_only:
2023 self.entry.signature = TypeSlots.ibinaryfunc
2025 sig = self.entry.signature
2026 nfixed = sig.num_fixed_args()
2027 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2028 and len(self.args) == 0 and self.star_arg:
2029 # this is the only case where a diverging number of
2030 # arguments is not an error - when we have no explicit
2031 # 'self' parameter as in method(*args)
2032 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2033 self.self_in_stararg = 1
2036 for i in range(min(nfixed, len(self.args))):
2039 if sig.is_self_arg(i) and not self.is_staticmethod:
2040 if self.is_classmethod:
2042 arg.hdr_type = arg.type = Builtin.type_type
2045 arg.hdr_type = arg.type = env.parent_type
2046 arg.needs_conversion = 0
2048 arg.hdr_type = sig.fixed_arg_type(i)
2049 if not arg.type.same_as(arg.hdr_type):
2050 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2051 arg.needs_type_test = 1
2053 arg.needs_conversion = 1
2054 if arg.needs_conversion:
2055 arg.hdr_cname = Naming.arg_prefix + arg.name
2057 arg.hdr_cname = Naming.var_prefix + arg.name
2059 if nfixed > len(self.args):
2060 self.bad_signature()
2062 elif nfixed < len(self.args):
2063 if not sig.has_generic_args:
2064 self.bad_signature()
2065 for arg in self.args:
2066 if arg.is_generic and \
2067 (arg.type.is_extension_type or arg.type.is_builtin_type):
2068 arg.needs_type_test = 1
2070 def bad_signature(self):
2071 sig = self.entry.signature
2072 expected_str = "%d" % sig.num_fixed_args()
2073 if sig.has_generic_args:
2074 expected_str = expected_str + " or more"
2076 if name.startswith("__") and name.endswith("__"):
2077 desc = "Special method"
2081 "%s %s has wrong number of arguments "
2082 "(%d declared, %s expected)" % (
2083 desc, self.name, len(self.args), expected_str))
2085 def signature_has_nongeneric_args(self):
2086 argcount = len(self.args)
2087 if argcount == 0 or (
2088 argcount == 1 and (self.args[0].is_self_arg or
2089 self.args[0].is_type_arg)):
2093 def signature_has_generic_args(self):
2094 return self.entry.signature.has_generic_args
2096 def declare_pyfunction(self, env):
2097 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2099 entry = env.lookup_here(name)
2100 if entry and entry.type.is_cfunction and not self.is_wrapper:
2101 warning(self.pos, "Overriding cdef method with def method.", 5)
2102 entry = env.declare_pyfunction(name, self.pos)
2104 prefix = env.scope_prefix
2105 entry.func_cname = \
2106 Naming.pyfunc_prefix + prefix + name
2107 entry.pymethdef_cname = \
2108 Naming.pymethdef_prefix + prefix + name
2109 if Options.docstrings:
2110 entry.doc = embed_position(self.pos, self.doc)
2112 Naming.funcdoc_prefix + prefix + name
2113 if entry.is_special:
2114 if entry.name in TypeSlots.invisible or not entry.doc:
2115 entry.wrapperbase_cname = None
2117 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2121 def declare_lambda_function(self, env):
2123 prefix = env.scope_prefix
2125 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2126 entry = env.declare_lambda_function(func_cname, self.pos)
2127 entry.pymethdef_cname = \
2128 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2129 entry.qualified_name = env.qualify_name(self.lambda_name)
2133 def declare_arguments(self, env):
2134 for arg in self.args:
2136 error(arg.pos, "Missing argument name")
2138 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2139 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2140 if arg.needs_conversion:
2141 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2142 if arg.type.is_pyobject:
2143 arg.entry.init = "0"
2144 arg.entry.init_to_none = 0
2146 arg.entry = self.declare_argument(env, arg)
2148 arg.entry.is_self_arg = arg.is_self_arg
2150 if arg.is_self_arg or arg.is_type_arg or \
2151 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2152 arg.entry.is_declared_generic = 1
2153 self.declare_python_arg(env, self.star_arg)
2154 self.declare_python_arg(env, self.starstar_arg)
2156 def declare_python_arg(self, env, arg):
2158 if env.directives['infer_types'] != False:
2159 type = PyrexTypes.unspecified_type
2161 type = py_object_type
2162 entry = env.declare_var(arg.name, type, arg.pos)
2165 entry.init_to_none = 0
2166 entry.xdecref_cleanup = 1
2168 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2170 def analyse_expressions(self, env):
2171 self.local_scope.directives = env.directives
2172 self.analyse_default_values(env)
2173 if self.needs_assignment_synthesis(env):
2174 # Shouldn't we be doing this at the module level too?
2175 self.synthesize_assignment_node(env)
2177 def needs_assignment_synthesis(self, env, code=None):
2178 # Should enable for module level as well, that will require more testing...
2179 if env.is_module_scope:
2181 return env.directives['binding']
2183 return code.globalstate.directives['binding']
2184 return env.is_py_class_scope or env.is_closure_scope
2186 def synthesize_assignment_node(self, env):
2188 if env.is_py_class_scope:
2189 rhs = ExprNodes.UnboundMethodNode(self.pos,
2190 function = ExprNodes.PyCFunctionNode(self.pos,
2191 pymethdef_cname = self.entry.pymethdef_cname))
2192 elif env.is_closure_scope:
2193 rhs = ExprNodes.InnerFunctionNode(
2194 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2196 rhs = ExprNodes.PyCFunctionNode(
2197 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2198 self.assmt = SingleAssignmentNode(self.pos,
2199 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2201 self.assmt.analyse_declarations(env)
2202 self.assmt.analyse_expressions(env)
2204 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2206 sig = self.entry.signature
2207 if sig.has_dummy_arg or self.self_in_stararg:
2208 arg_code_list.append(
2209 "PyObject *%s" % Naming.self_cname)
2210 for arg in self.args:
2211 if not arg.is_generic:
2212 if arg.is_self_arg or arg.is_type_arg:
2213 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2215 arg_code_list.append(
2216 arg.hdr_type.declaration_code(arg.hdr_cname))
2217 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2218 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2219 if sig.has_generic_args:
2220 arg_code_list.append(
2221 "PyObject *%s, PyObject *%s"
2222 % (Naming.args_cname, Naming.kwds_cname))
2223 arg_code = ", ".join(arg_code_list)
2224 dc = self.return_type.declaration_code(self.entry.func_cname)
2225 mf = " ".join(self.modifiers).upper()
2227 header = "static %s%s(%s)" % (mf, dc, arg_code)
2228 code.putln("%s; /*proto*/" % header)
2231 if (Options.docstrings and self.entry.doc and
2232 not self.entry.scope.is_property_scope and
2233 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2234 docstr = self.entry.doc
2235 if docstr.is_unicode:
2236 docstr = docstr.utf8encode()
2238 'static char %s[] = "%s";' % (
2239 self.entry.doc_cname,
2240 split_string_literal(escape_byte_string(docstr))))
2241 if self.entry.is_special:
2243 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2246 "static PyMethodDef %s = " %
2247 self.entry.pymethdef_cname)
2248 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2249 code.putln("%s {" % header)
2251 def generate_argument_declarations(self, env, code):
2252 for arg in self.args:
2253 if arg.is_generic: # or arg.needs_conversion:
2254 if arg.needs_conversion:
2255 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2256 elif not arg.entry.in_closure:
2257 code.put_var_declaration(arg.entry)
2259 def generate_keyword_list(self, code):
2260 if self.signature_has_generic_args() and \
2261 self.signature_has_nongeneric_args():
2263 "static PyObject **%s[] = {" %
2264 Naming.pykwdlist_cname)
2265 for arg in self.args:
2267 pystring_cname = code.intern_identifier(arg.name)
2268 code.put('&%s,' % pystring_cname)
2271 def generate_argument_parsing_code(self, env, code):
2272 # Generate PyArg_ParseTuple call for generic
2273 # arguments, if any.
2274 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2275 # get rid of unused argument warning
2276 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2278 old_error_label = code.new_error_label()
2279 our_error_label = code.error_label
2280 end_label = code.new_label("argument_unpacking_done")
2282 has_kwonly_args = self.num_kwonly_args > 0
2283 has_star_or_kw_args = self.star_arg is not None \
2284 or self.starstar_arg is not None or has_kwonly_args
2286 for arg in self.args:
2287 if not arg.type.is_pyobject:
2288 done = arg.type.create_from_py_utility_code(env)
2289 if not done: pass # will fail later
2291 if not self.signature_has_generic_args():
2292 if has_star_or_kw_args:
2293 error(self.pos, "This method cannot have * or keyword arguments")
2294 self.generate_argument_conversion_code(code)
2296 elif not self.signature_has_nongeneric_args():
2297 # func(*args) or func(**kw) or func(*args, **kw)
2298 self.generate_stararg_copy_code(code)
2301 positional_args = []
2303 for arg in self.args:
2304 arg_entry = arg.entry
2307 if not arg.is_self_arg and not arg.is_type_arg:
2309 kw_only_args.append(arg)
2311 positional_args.append(arg)
2313 kw_only_args.append(arg)
2314 elif not arg.is_self_arg and not arg.is_type_arg:
2315 positional_args.append(arg)
2317 self.generate_tuple_and_keyword_parsing_code(
2318 positional_args, kw_only_args, end_label, code)
2320 code.error_label = old_error_label
2321 if code.label_used(our_error_label):
2322 if not code.label_used(end_label):
2323 code.put_goto(end_label)
2324 code.put_label(our_error_label)
2325 if has_star_or_kw_args:
2326 self.generate_arg_decref(self.star_arg, code)
2327 if self.starstar_arg:
2328 if self.starstar_arg.entry.xdecref_cleanup:
2329 code.put_var_xdecref(self.starstar_arg.entry)
2331 code.put_var_decref(self.starstar_arg.entry)
2332 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2333 # The arguments are put into the closure one after the
2334 # other, so when type errors are found, all references in
2335 # the closure instance must be properly ref-counted to
2336 # facilitate generic closure instance deallocation. In
2337 # the case of an argument type error, it's best to just
2338 # DECREF+clear the already handled references, as this
2339 # frees their references as early as possible.
2340 for arg in self.args:
2341 if arg.type.is_pyobject and arg.entry.in_closure:
2342 code.put_var_xdecref_clear(arg.entry)
2343 if self.needs_closure:
2344 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2345 code.put_finish_refcount_context()
2346 code.putln("return %s;" % self.error_value())
2347 if code.label_used(end_label):
2348 code.put_label(end_label)
2350 def generate_arg_assignment(self, arg, item, code):
2351 if arg.type.is_pyobject:
2353 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2355 code.putln("%s = %s;" % (entry.cname, item))
2356 if entry.in_closure:
2357 code.put_var_incref(entry)
2359 func = arg.type.from_py_function
2361 code.putln("%s = %s(%s); %s" % (
2365 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2367 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2369 def generate_arg_xdecref(self, arg, code):
2371 code.put_var_xdecref(arg.entry)
2373 def generate_arg_decref(self, arg, code):
2375 code.put_var_decref(arg.entry)
2377 def generate_stararg_copy_code(self, code):
2378 if not self.star_arg:
2379 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2380 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2382 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2383 self.name, Naming.args_cname, self.error_value()))
2386 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2388 if self.starstar_arg:
2390 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2392 kwarg_check = "%s" % Naming.kwds_cname
2394 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2395 Naming.kwds_cname, Naming.kwds_cname)
2397 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2398 kwarg_check, Naming.kwds_cname, self.name,
2399 bool(self.starstar_arg), self.error_value()))
2401 if self.starstar_arg:
2402 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2403 self.starstar_arg.entry.cname,
2406 code.putln("if (unlikely(!%s)) return %s;" % (
2407 self.starstar_arg.entry.cname, self.error_value()))
2408 self.starstar_arg.entry.xdecref_cleanup = 0
2409 code.put_gotref(self.starstar_arg.entry.cname)
2411 if self.self_in_stararg:
2412 # need to create a new tuple with 'self' inserted as first item
2413 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2414 self.star_arg.entry.cname,
2416 self.star_arg.entry.cname))
2417 if self.starstar_arg:
2419 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2420 code.putln("return %s;" % self.error_value())
2423 code.putln("return %s;" % self.error_value())
2424 code.put_gotref(self.star_arg.entry.cname)
2425 code.put_incref(Naming.self_cname, py_object_type)
2426 code.put_giveref(Naming.self_cname)
2427 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2428 self.star_arg.entry.cname, Naming.self_cname))
2429 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2430 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2431 temp, temp, Naming.args_cname, temp))
2432 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2433 Naming.args_cname, temp))
2434 code.put_incref("item", py_object_type)
2435 code.put_giveref("item")
2436 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2437 self.star_arg.entry.cname, temp))
2439 code.funcstate.release_temp(temp)
2440 self.star_arg.entry.xdecref_cleanup = 0
2442 code.put_incref(Naming.args_cname, py_object_type)
2443 code.putln("%s = %s;" % (
2444 self.star_arg.entry.cname,
2446 self.star_arg.entry.xdecref_cleanup = 0
2448 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2449 kw_only_args, success_label, code):
2450 argtuple_error_label = code.new_label("argtuple_error")
2452 min_positional_args = self.num_required_args - self.num_required_kw_args
2453 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2454 min_positional_args -= 1
2455 max_positional_args = len(positional_args)
2456 has_fixed_positional_count = not self.star_arg and \
2457 min_positional_args == max_positional_args
2459 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2460 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2461 if self.num_required_kw_args:
2462 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2464 if self.starstar_arg or self.star_arg:
2465 self.generate_stararg_init_code(max_positional_args, code)
2467 # --- optimised code when we receive keyword arguments
2468 if self.num_required_kw_args:
2469 likely_hint = "likely"
2471 likely_hint = "unlikely"
2472 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2473 self.generate_keyword_unpacking_code(
2474 min_positional_args, max_positional_args,
2475 has_fixed_positional_count,
2476 positional_args, kw_only_args, argtuple_error_label, code)
2478 # --- optimised code when we do not receive any keyword arguments
2479 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2480 # Python raises arg tuple related errors first, so we must
2481 # check the length here
2482 if min_positional_args == max_positional_args and not self.star_arg:
2486 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2487 Naming.args_cname, compare, min_positional_args))
2488 code.put_goto(argtuple_error_label)
2490 if self.num_required_kw_args:
2491 # pure error case: keywords required but not passed
2492 if max_positional_args > min_positional_args and not self.star_arg:
2493 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2494 Naming.args_cname, max_positional_args))
2495 code.put_goto(argtuple_error_label)
2496 code.putln('} else {')
2497 for i, arg in enumerate(kw_only_args):
2499 pystring_cname = code.intern_identifier(arg.name)
2500 # required keyword-only argument missing
2501 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2504 code.putln(code.error_goto(self.pos))
2507 elif min_positional_args == max_positional_args:
2508 # parse the exact number of positional arguments from the
2510 code.putln('} else {')
2511 for i, arg in enumerate(positional_args):
2512 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2513 self.generate_arg_assignment(arg, item, code)
2514 self.generate_arg_default_assignments(code)
2517 # parse the positional arguments from the variable length
2519 code.putln('} else {')
2520 self.generate_arg_default_assignments(code)
2521 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2523 code.putln('default:')
2524 reversed_args = list(enumerate(positional_args))[::-1]
2525 for i, arg in reversed_args:
2526 if i >= min_positional_args-1:
2527 if min_positional_args > 1:
2528 code.putln('case %2d:' % (i+1)) # pure code beautification
2530 code.put('case %2d: ' % (i+1))
2531 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2532 self.generate_arg_assignment(arg, item, code)
2533 if min_positional_args == 0:
2534 code.put('case 0: ')
2535 code.putln('break;')
2537 if min_positional_args:
2538 for i in range(min_positional_args-1, -1, -1):
2539 code.putln('case %2d:' % i)
2540 code.put_goto(argtuple_error_label)
2542 code.put('default: ')
2543 code.put_goto(argtuple_error_label)
2548 if code.label_used(argtuple_error_label):
2549 code.put_goto(success_label)
2550 code.put_label(argtuple_error_label)
2551 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2552 self.name, has_fixed_positional_count,
2553 min_positional_args, max_positional_args,
2555 code.putln(code.error_goto(self.pos))
2557 def generate_arg_default_assignments(self, code):
2558 for arg in self.args:
2559 if arg.is_generic and arg.default:
2563 arg.calculate_default_value_code(code)))
2565 def generate_stararg_init_code(self, max_positional_args, code):
2566 if self.starstar_arg:
2567 self.starstar_arg.entry.xdecref_cleanup = 0
2568 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2569 self.starstar_arg.entry.cname,
2570 self.starstar_arg.entry.cname,
2571 self.error_value()))
2572 code.put_gotref(self.starstar_arg.entry.cname)
2574 self.star_arg.entry.xdecref_cleanup = 0
2575 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2577 max_positional_args))
2578 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2579 self.star_arg.entry.cname, Naming.args_cname,
2580 max_positional_args, Naming.args_cname))
2581 code.put_gotref(self.star_arg.entry.cname)
2582 if self.starstar_arg:
2584 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2585 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2586 code.putln('return %s;' % self.error_value())
2589 code.putln("if (unlikely(!%s)) return %s;" % (
2590 self.star_arg.entry.cname, self.error_value()))
2591 code.putln('} else {')
2592 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2593 code.put_incref(Naming.empty_tuple, py_object_type)
2596 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2597 has_fixed_positional_count, positional_args,
2598 kw_only_args, argtuple_error_label, code):
2599 all_args = tuple(positional_args) + tuple(kw_only_args)
2600 max_args = len(all_args)
2602 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2604 # the 'values' array collects borrowed references to arguments
2605 # before doing any type coercion etc.
2606 code.putln("PyObject* values[%d] = {%s};" % (
2607 max_args, ','.join('0'*max_args)))
2609 # assign borrowed Python default values to the values array,
2610 # so that they can be overwritten by received arguments below
2611 for i, arg in enumerate(all_args):
2612 if arg.default and arg.type.is_pyobject:
2613 default_value = arg.calculate_default_value_code(code)
2614 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2616 # parse the args tuple and check that it's not too long
2617 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2619 code.putln('default:')
2620 for i in range(max_positional_args-1, -1, -1):
2621 code.put('case %2d: ' % (i+1))
2622 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2623 i, Naming.args_cname, i))
2624 code.putln('case 0: break;')
2625 if not self.star_arg:
2626 code.put('default: ') # more arguments than allowed
2627 code.put_goto(argtuple_error_label)
2630 # now fill up the positional/required arguments with values
2632 if self.num_required_args or max_positional_args > 0:
2633 last_required_arg = -1
2634 for i, arg in enumerate(all_args):
2636 last_required_arg = i
2637 if last_required_arg < max_positional_args:
2638 last_required_arg = max_positional_args-1
2639 num_required_args = self.num_required_args
2640 if max_positional_args > 0:
2641 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2642 for i, arg in enumerate(all_args[:last_required_arg+1]):
2643 if max_positional_args > 0 and i <= max_positional_args:
2644 if self.star_arg and i == max_positional_args:
2645 code.putln('default:')
2647 code.putln('case %2d:' % i)
2648 pystring_cname = code.intern_identifier(arg.name)
2651 # handled separately below
2653 code.putln('if (kw_args > 0) {')
2654 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2655 Naming.kwds_cname, pystring_cname))
2656 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2659 num_required_args -= 1
2660 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2661 i, Naming.kwds_cname, pystring_cname))
2662 code.putln('if (likely(values[%d])) kw_args--;' % i);
2663 if i < min_positional_args:
2665 # special case: we know arg 0 is missing
2667 code.put_goto(argtuple_error_label)
2669 # print the correct number of values (args or
2670 # kwargs) that were passed into positional
2671 # arguments up to this point
2672 code.putln('else {')
2673 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2674 self.name, has_fixed_positional_count,
2675 min_positional_args, max_positional_args, i))
2676 code.putln(code.error_goto(self.pos))
2679 code.putln('else {')
2680 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2681 self.name, pystring_cname))
2682 code.putln(code.error_goto(self.pos))
2684 if max_positional_args > 0:
2687 if kw_only_args and not self.starstar_arg:
2688 # unpack optional keyword-only arguments
2689 # checking for interned strings in a dict is faster than iterating
2690 # but it's too likely that we must iterate if we expect **kwargs
2692 for i, arg in enumerate(all_args[max_positional_args:]):
2693 if not arg.kw_only or not arg.default:
2695 optional_args.append((i+max_positional_args, arg))
2697 # this mimics an unrolled loop so that we can "break" out of it
2698 code.putln('while (kw_args > 0) {')
2699 code.putln('PyObject* value;')
2700 for i, arg in optional_args:
2701 pystring_cname = code.intern_identifier(arg.name)
2703 'value = PyDict_GetItem(%s, %s);' % (
2704 Naming.kwds_cname, pystring_cname))
2706 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2707 code.putln('break;')
2710 code.putln('if (unlikely(kw_args > 0)) {')
2711 # non-positional/-required kw args left in dict: default args,
2712 # kw-only args, **kwargs or error
2714 # This is sort of a catch-all: except for checking required
2715 # arguments, this will always do the right thing for unpacking
2716 # keyword arguments, so that we can concentrate on optimising
2717 # common cases above.
2718 if max_positional_args == 0:
2721 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2722 Naming.args_cname, max_positional_args,
2723 Naming.args_cname, max_positional_args))
2724 pos_arg_count = "used_pos_args"
2726 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2727 code.globalstate.use_utility_code(parse_keywords_utility_code)
2729 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2731 Naming.pykwdlist_cname,
2732 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2735 code.putln(code.error_goto(self.pos))
2738 # convert arg values to their final type and assign them
2739 for i, arg in enumerate(all_args):
2740 if arg.default and not arg.type.is_pyobject:
2741 code.putln("if (values[%d]) {" % i)
2742 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2743 if arg.default and not arg.type.is_pyobject:
2744 code.putln('} else {')
2748 arg.calculate_default_value_code(code)))
2751 def generate_argument_conversion_code(self, code):
2752 # Generate code to convert arguments from signature type to
2753 # declared type, if needed. Also copies signature arguments
2754 # into closure fields.
2755 for arg in self.args:
2756 if arg.needs_conversion:
2757 self.generate_arg_conversion(arg, code)
2758 elif arg.entry.in_closure:
2759 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2760 if arg.type.is_pyobject:
2761 code.put_var_incref(arg.entry)
2763 def generate_arg_conversion(self, arg, code):
2764 # Generate conversion code for one argument.
2765 old_type = arg.hdr_type
2767 if old_type.is_pyobject:
2769 code.putln("if (%s) {" % arg.hdr_cname)
2771 code.putln("assert(%s); {" % arg.hdr_cname)
2772 self.generate_arg_conversion_from_pyobject(arg, code)
2774 elif new_type.is_pyobject:
2775 self.generate_arg_conversion_to_pyobject(arg, code)
2777 if new_type.assignable_from(old_type):
2779 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2782 "Cannot convert 1 argument from '%s' to '%s'" %
2783 (old_type, new_type))
2785 def generate_arg_conversion_from_pyobject(self, arg, code):
2787 func = new_type.from_py_function
2788 # copied from CoerceFromPyTypeNode
2790 lhs = arg.entry.cname
2791 rhs = "%s(%s)" % (func, arg.hdr_cname)
2792 if new_type.is_enum:
2793 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2794 code.putln("%s = %s; %s" % (
2797 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2800 "Cannot convert Python object argument to type '%s'"
2803 def generate_arg_conversion_to_pyobject(self, arg, code):
2804 old_type = arg.hdr_type
2805 func = old_type.to_py_function
2807 code.putln("%s = %s(%s); %s" % (
2811 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2812 code.put_var_gotref(arg.entry)
2815 "Cannot convert argument of type '%s' to Python object"
2818 def generate_argument_type_tests(self, code):
2819 # Generate type tests for args whose signature
2820 # type is PyObject * and whose declared type is
2821 # a subtype thereof.
2822 for arg in self.args:
2823 if arg.needs_type_test:
2824 self.generate_arg_type_test(arg, code)
2825 elif not arg.accept_none and arg.type.is_pyobject:
2826 self.generate_arg_none_check(arg, code)
2828 def error_value(self):
2829 return self.entry.signature.error_value
2831 def caller_will_check_exceptions(self):
2834 class OverrideCheckNode(StatNode):
2835 # A Node for dispatching to the def method if it
2844 child_attrs = ['body']
2848 def analyse_expressions(self, env):
2849 self.args = env.arg_entries
2850 if self.py_func.is_module_scope:
2855 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2856 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2857 call_node = ExprNodes.SimpleCallNode(self.pos,
2858 function=self.func_node,
2859 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2860 self.body = ReturnStatNode(self.pos, value=call_node)
2861 self.body.analyse_expressions(env)
2863 def generate_execution_code(self, code):
2864 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2865 # Check to see if we are an extension type
2866 if self.py_func.is_module_scope:
2867 self_arg = "((PyObject *)%s)" % Naming.module_cname
2869 self_arg = "((PyObject *)%s)" % self.args[0].cname
2870 code.putln("/* Check if called by wrapper */")
2871 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2872 code.putln("/* Check if overriden in Python */")
2873 if self.py_func.is_module_scope:
2874 code.putln("else {")
2876 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2877 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2878 self.func_node.set_cname(func_node_temp)
2879 # need to get attribute manually--scope would return cdef method
2880 err = code.error_goto_if_null(func_node_temp, self.pos)
2881 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2882 func_node_temp, self_arg, interned_attr_cname, err))
2883 code.put_gotref(func_node_temp)
2884 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2885 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2886 func_node_temp, self.py_func.entry.func_cname)
2887 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2888 self.body.generate_execution_code(code)
2890 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2891 code.funcstate.release_temp(func_node_temp)
2894 class ClassDefNode(StatNode, BlockNode):
2897 class PyClassDefNode(ClassDefNode):
2898 # A Python class definition.
2900 # name EncodedString Name of the class
2901 # doc string or None
2902 # body StatNode Attribute definition code
2903 # entry Symtab.Entry
2904 # scope PyClassScope
2905 # decorators [DecoratorNode] list of decorators or None
2907 # The following subnodes are constructed internally:
2909 # dict DictNode Class dictionary
2910 # classobj ClassNode Class object
2911 # target NameNode Variable to assign class object to
2913 child_attrs = ["body", "dict", "classobj", "target"]
2916 def __init__(self, pos, name, bases, doc, body, decorators = None):
2917 StatNode.__init__(self, pos)
2921 self.decorators = decorators
2923 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2924 if self.doc and Options.docstrings:
2925 doc = embed_position(self.pos, self.doc)
2926 # FIXME: correct string node?
2927 doc_node = ExprNodes.StringNode(pos, value = doc)
2930 self.classobj = ExprNodes.ClassNode(pos, name = name,
2931 bases = bases, dict = self.dict, doc = doc_node)
2932 self.target = ExprNodes.NameNode(pos, name = name)
2934 def as_cclass(self):
2936 Return this node as if it were declared as an extension class
2938 bases = self.classobj.bases.args
2940 base_class_name = None
2941 base_class_module = None
2942 elif len(bases) == 1:
2945 from ExprNodes import AttributeNode, NameNode
2946 while isinstance(base, AttributeNode):
2947 path.insert(0, base.attribute)
2949 if isinstance(base, NameNode):
2950 path.insert(0, base.name)
2951 base_class_name = path[-1]
2953 base_class_module = u'.'.join(path[:-1])
2955 base_class_module = None
2957 error(self.classobj.bases.args.pos, "Invalid base class")
2959 error(self.classobj.bases.args.pos, "C class may only have one base class")
2962 return CClassDefNode(self.pos,
2963 visibility = 'private',
2965 class_name = self.name,
2966 base_class_module = base_class_module,
2967 base_class_name = base_class_name,
2968 decorators = self.decorators,
2973 def create_scope(self, env):
2975 while env.is_py_class_scope or env.is_c_class_scope:
2976 env = env.outer_scope
2977 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2980 def analyse_declarations(self, env):
2981 self.target.analyse_target_declaration(env)
2982 cenv = self.create_scope(env)
2983 cenv.directives = env.directives
2984 cenv.class_obj_cname = self.target.entry.cname
2985 self.body.analyse_declarations(cenv)
2987 def analyse_expressions(self, env):
2988 self.dict.analyse_expressions(env)
2989 self.classobj.analyse_expressions(env)
2990 genv = env.global_scope()
2992 self.body.analyse_expressions(cenv)
2993 self.target.analyse_target_expression(env, self.classobj)
2995 def generate_function_definitions(self, env, code):
2996 self.body.generate_function_definitions(self.scope, code)
2998 def generate_execution_code(self, code):
2999 code.pyclass_stack.append(self)
3001 self.dict.generate_evaluation_code(code)
3002 self.classobj.generate_evaluation_code(code)
3003 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3004 self.body.generate_execution_code(code)
3005 self.target.generate_assignment_code(self.classobj, code)
3006 self.dict.generate_disposal_code(code)
3007 self.dict.free_temps(code)
3008 code.pyclass_stack.pop()
3011 class CClassDefNode(ClassDefNode):
3012 # An extension type definition.
3014 # visibility 'private' or 'public' or 'extern'
3015 # typedef_flag boolean
3017 # module_name string or None For import of extern type objects
3018 # class_name string Unqualified name of class
3019 # as_name string or None Name to declare as in this scope
3020 # base_class_module string or None Module containing the base class
3021 # base_class_name string or None Name of the base class
3022 # objstruct_name string or None Specified C name of object struct
3023 # typeobj_name string or None Specified C name of type object
3024 # in_pxd boolean Is in a .pxd file
3025 # decorators [DecoratorNode] list of decorators or None
3026 # doc string or None
3027 # body StatNode or None
3028 # entry Symtab.Entry
3029 # base_type PyExtensionType or None
3030 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3031 # buffer_defaults_pos
3033 child_attrs = ["body"]
3034 buffer_defaults_node = None
3035 buffer_defaults_pos = None
3036 typedef_flag = False
3038 objstruct_name = None
3042 def analyse_declarations(self, env):
3043 #print "CClassDefNode.analyse_declarations:", self.class_name
3044 #print "...visibility =", self.visibility
3045 #print "...module_name =", self.module_name
3048 if self.buffer_defaults_node:
3049 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3050 env, [], self.buffer_defaults_node,
3051 need_complete=False)
3053 buffer_defaults = None
3055 if env.in_cinclude and not self.objstruct_name:
3056 error(self.pos, "Object struct name specification required for "
3057 "C class defined in 'extern from' block")
3058 self.base_type = None
3059 # Now that module imports are cached, we need to
3060 # import the modules for extern classes.
3061 if self.module_name:
3063 for module in env.cimported_modules:
3064 if module.name == self.module_name:
3065 self.module = module
3066 if self.module is None:
3067 self.module = ModuleScope(self.module_name, None, env.context)
3068 self.module.has_extern_class = 1
3069 env.add_imported_module(self.module)
3071 if self.base_class_name:
3072 if self.base_class_module:
3073 base_class_scope = env.find_module(self.base_class_module, self.pos)
3075 base_class_scope = env
3076 if self.base_class_name == 'object':
3077 # extension classes are special and don't need to inherit from object
3078 if base_class_scope is None or base_class_scope.lookup('object') is None:
3079 self.base_class_name = None
3080 self.base_class_module = None
3081 base_class_scope = None
3082 if base_class_scope:
3083 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3084 if base_class_entry:
3085 if not base_class_entry.is_type:
3086 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3087 elif not base_class_entry.type.is_extension_type:
3088 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3089 elif not base_class_entry.type.is_complete():
3090 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
3092 self.base_type = base_class_entry.type
3093 has_body = self.body is not None
3094 if self.module_name and self.visibility != 'extern':
3095 module_path = self.module_name.split(".")
3096 home_scope = env.find_imported_module(module_path, self.pos)
3102 if self.visibility == 'extern':
3103 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3104 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3106 self.entry = home_scope.declare_c_class(
3107 name = self.class_name,
3109 defining = has_body and self.in_pxd,
3110 implementing = has_body and not self.in_pxd,
3111 module_name = self.module_name,
3112 base_type = self.base_type,
3113 objstruct_cname = self.objstruct_name,
3114 typeobj_cname = self.typeobj_name,
3115 visibility = self.visibility,
3116 typedef_flag = self.typedef_flag,
3118 buffer_defaults = buffer_defaults)
3119 if home_scope is not env and self.visibility == 'extern':
3120 env.add_imported_entry(self.class_name, self.entry, pos)
3121 self.scope = scope = self.entry.type.scope
3122 if scope is not None:
3123 scope.directives = env.directives
3125 if self.doc and Options.docstrings:
3126 scope.doc = embed_position(self.pos, self.doc)
3129 self.body.analyse_declarations(scope)
3133 scope.implemented = 1
3134 env.allocate_vtable_names(self.entry)
3136 def analyse_expressions(self, env):
3138 scope = self.entry.type.scope
3139 self.body.analyse_expressions(scope)
3141 def generate_function_definitions(self, env, code):
3143 self.body.generate_function_definitions(
3144 self.entry.type.scope, code)
3146 def generate_execution_code(self, code):
3147 # This is needed to generate evaluation code for
3148 # default values of method arguments.
3150 self.body.generate_execution_code(code)
3152 def annotate(self, code):
3154 self.body.annotate(code)
3157 class PropertyNode(StatNode):
3158 # Definition of a property in an extension type.
3161 # doc EncodedString or None Doc string
3164 child_attrs = ["body"]
3166 def analyse_declarations(self, env):
3167 entry = env.declare_property(self.name, self.doc, self.pos)
3169 entry.scope.directives = env.directives
3170 self.body.analyse_declarations(entry.scope)
3172 def analyse_expressions(self, env):
3173 self.body.analyse_expressions(env)
3175 def generate_function_definitions(self, env, code):
3176 self.body.generate_function_definitions(env, code)
3178 def generate_execution_code(self, code):
3181 def annotate(self, code):
3182 self.body.annotate(code)
3185 class GlobalNode(StatNode):
3186 # Global variable declaration.
3192 def analyse_declarations(self, env):
3193 for name in self.names:
3194 env.declare_global(name, self.pos)
3196 def analyse_expressions(self, env):
3199 def generate_execution_code(self, code):
3203 class ExprStatNode(StatNode):
3204 # Expression used as a statement.
3208 child_attrs = ["expr"]
3210 def analyse_declarations(self, env):
3212 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3213 func = self.expr.function.as_cython_attribute()
3214 if func == u'declare':
3215 args, kwds = self.expr.explicit_args_kwds()
3217 error(self.expr.pos, "Variable names must be specified.")
3218 for var, type_node in kwds.key_value_pairs:
3219 type = type_node.analyse_as_type(env)
3221 error(type_node.pos, "Unknown type")
3223 env.declare_var(var.value, type, var.pos, is_cdef = True)
3224 self.__class__ = PassStatNode
3226 def analyse_expressions(self, env):
3227 self.expr.analyse_expressions(env)
3229 def generate_execution_code(self, code):
3230 self.expr.generate_evaluation_code(code)
3231 if not self.expr.is_temp and self.expr.result():
3232 code.putln("%s;" % self.expr.result())
3233 self.expr.generate_disposal_code(code)
3234 self.expr.free_temps(code)
3236 def generate_function_definitions(self, env, code):
3237 self.expr.generate_function_definitions(env, code)
3239 def annotate(self, code):
3240 self.expr.annotate(code)
3243 class AssignmentNode(StatNode):
3244 # Abstract base class for assignment nodes.
3246 # The analyse_expressions and generate_execution_code
3247 # phases of assignments are split into two sub-phases
3248 # each, to enable all the right hand sides of a
3249 # parallel assignment to be evaluated before assigning
3250 # to any of the left hand sides.
3252 def analyse_expressions(self, env):
3253 self.analyse_types(env)
3255 # def analyse_expressions(self, env):
3256 # self.analyse_expressions_1(env)
3257 # self.analyse_expressions_2(env)
3259 def generate_execution_code(self, code):
3260 self.generate_rhs_evaluation_code(code)
3261 self.generate_assignment_code(code)
3264 class SingleAssignmentNode(AssignmentNode):
3265 # The simplest case:
3269 # lhs ExprNode Left hand side
3270 # rhs ExprNode Right hand side
3271 # first bool Is this guaranteed the first assignment to lhs?
3273 child_attrs = ["lhs", "rhs"]
3275 declaration_only = False
3277 def analyse_declarations(self, env):
3280 # handle declarations of the form x = cython.foo()
3281 if isinstance(self.rhs, ExprNodes.CallNode):
3282 func_name = self.rhs.function.as_cython_attribute()
3284 args, kwds = self.rhs.explicit_args_kwds()
3286 if func_name in ['declare', 'typedef']:
3287 if len(args) > 2 or kwds is not None:
3288 error(rhs.pos, "Can only declare one type at a time.")
3290 type = args[0].analyse_as_type(env)
3292 error(args[0].pos, "Unknown type")
3295 if func_name == 'declare':
3296 if isinstance(lhs, ExprNodes.NameNode):
3297 vars = [(lhs.name, lhs.pos)]
3298 elif isinstance(lhs, ExprNodes.TupleNode):
3299 vars = [(var.name, var.pos) for var in lhs.args]
3301 error(lhs.pos, "Invalid declaration")
3303 for var, pos in vars:
3304 env.declare_var(var, type, pos, is_cdef = True)
3309 self.declaration_only = True
3311 self.declaration_only = True
3312 if not isinstance(lhs, ExprNodes.NameNode):
3313 error(lhs.pos, "Invalid declaration.")
3314 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3316 elif func_name in ['struct', 'union']:
3317 self.declaration_only = True
3318 if len(args) > 0 or kwds is None:
3319 error(rhs.pos, "Struct or union members must be given by name.")
3322 for member, type_node in kwds.key_value_pairs:
3323 type = type_node.analyse_as_type(env)
3325 error(type_node.pos, "Unknown type")
3327 members.append((member.value, type, member.pos))
3328 if len(members) < len(kwds.key_value_pairs):
3330 if not isinstance(self.lhs, ExprNodes.NameNode):
3331 error(self.lhs.pos, "Invalid declaration.")
3332 name = self.lhs.name
3333 scope = StructOrUnionScope(name)
3334 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3335 for member, type, pos in members:
3336 scope.declare_var(member, type, pos)
3338 if self.declaration_only:
3341 self.lhs.analyse_target_declaration(env)
3343 def analyse_types(self, env, use_temp = 0):
3344 self.rhs.analyse_types(env)
3345 self.lhs.analyse_target_types(env)
3346 self.lhs.gil_assignment_check(env)
3347 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3349 self.rhs = self.rhs.coerce_to_temp(env)
3351 def generate_rhs_evaluation_code(self, code):
3352 self.rhs.generate_evaluation_code(code)
3354 def generate_assignment_code(self, code):
3355 self.lhs.generate_assignment_code(self.rhs, code)
3357 def generate_function_definitions(self, env, code):
3358 self.rhs.generate_function_definitions(env, code)
3360 def annotate(self, code):
3361 self.lhs.annotate(code)
3362 self.rhs.annotate(code)
3365 class CascadedAssignmentNode(AssignmentNode):
3366 # An assignment with multiple left hand sides:
3370 # lhs_list [ExprNode] Left hand sides
3371 # rhs ExprNode Right hand sides
3375 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3377 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3378 coerced_rhs_list = None
3380 def analyse_declarations(self, env):
3381 for lhs in self.lhs_list:
3382 lhs.analyse_target_declaration(env)
3384 def analyse_types(self, env, use_temp = 0):
3385 self.rhs.analyse_types(env)
3386 if not self.rhs.is_simple():
3388 self.rhs = self.rhs.coerce_to_temp(env)
3390 self.rhs = self.rhs.coerce_to_simple(env)
3391 from ExprNodes import CloneNode
3392 self.coerced_rhs_list = []
3393 for lhs in self.lhs_list:
3394 lhs.analyse_target_types(env)
3395 lhs.gil_assignment_check(env)
3396 rhs = CloneNode(self.rhs)
3397 rhs = rhs.coerce_to(lhs.type, env)
3398 self.coerced_rhs_list.append(rhs)
3400 def generate_rhs_evaluation_code(self, code):
3401 self.rhs.generate_evaluation_code(code)
3403 def generate_assignment_code(self, code):
3404 for i in range(len(self.lhs_list)):
3405 lhs = self.lhs_list[i]
3406 rhs = self.coerced_rhs_list[i]
3407 rhs.generate_evaluation_code(code)
3408 lhs.generate_assignment_code(rhs, code)
3409 # Assignment has disposed of the cloned RHS
3410 self.rhs.generate_disposal_code(code)
3411 self.rhs.free_temps(code)
3413 def generate_function_definitions(self, env, code):
3414 self.rhs.generate_function_definitions(env, code)
3416 def annotate(self, code):
3417 for i in range(len(self.lhs_list)):
3418 lhs = self.lhs_list[i].annotate(code)
3419 rhs = self.coerced_rhs_list[i].annotate(code)
3420 self.rhs.annotate(code)
3423 class ParallelAssignmentNode(AssignmentNode):
3424 # A combined packing/unpacking assignment:
3428 # This has been rearranged by the parser into
3430 # a = d ; b = e ; c = f
3432 # but we must evaluate all the right hand sides
3433 # before assigning to any of the left hand sides.
3435 # stats [AssignmentNode] The constituent assignments
3437 child_attrs = ["stats"]
3439 def analyse_declarations(self, env):
3440 for stat in self.stats:
3441 stat.analyse_declarations(env)
3443 def analyse_expressions(self, env):
3444 for stat in self.stats:
3445 stat.analyse_types(env, use_temp = 1)
3447 # def analyse_expressions(self, env):
3448 # for stat in self.stats:
3449 # stat.analyse_expressions_1(env, use_temp = 1)
3450 # for stat in self.stats:
3451 # stat.analyse_expressions_2(env)
3453 def generate_execution_code(self, code):
3454 for stat in self.stats:
3455 stat.generate_rhs_evaluation_code(code)
3456 for stat in self.stats:
3457 stat.generate_assignment_code(code)
3459 def generate_function_definitions(self, env, code):
3460 for stat in self.stats:
3461 stat.generate_function_definitions(env, code)
3463 def annotate(self, code):
3464 for stat in self.stats:
3468 class InPlaceAssignmentNode(AssignmentNode):
3469 # An in place arithmetic operand:
3475 # lhs ExprNode Left hand side
3476 # rhs ExprNode Right hand side
3477 # op char one of "+-*/%^&|"
3478 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3480 # This code is a bit tricky because in order to obey Python
3481 # semantics the sub-expressions (e.g. indices) of the lhs must
3482 # not be evaluated twice. So we must re-use the values calculated
3483 # in evaluation phase for the assignment phase as well.
3484 # Fortunately, the type of the lhs node is fairly constrained
3485 # (it must be a NameNode, AttributeNode, or IndexNode).
3487 child_attrs = ["lhs", "rhs"]
3490 def analyse_declarations(self, env):
3491 self.lhs.analyse_target_declaration(env)
3493 def analyse_types(self, env):
3494 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3495 self.rhs.analyse_types(env)
3496 self.lhs.analyse_target_types(env)
3498 if self.lhs.type.is_pyobject:
3499 self.rhs = self.rhs.coerce_to_pyobject(env)
3500 elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3501 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3502 if self.lhs.type.is_pyobject:
3503 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3504 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3506 def generate_execution_code(self, code):
3508 self.rhs.generate_evaluation_code(code)
3509 self.dup.generate_subexpr_evaluation_code(code)
3510 if self.dup.is_temp:
3511 self.dup.allocate_temp_result(code)
3512 # self.dup.generate_result_code is run only if it is not buffer access
3513 if self.operator == "**":
3517 if self.lhs.type.is_pyobject:
3518 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3519 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3520 self.dup.generate_result_code(code)
3521 self.result_value_temp.allocate(code)
3523 "%s = %s(%s, %s%s); %s" % (
3524 self.result_value.result(),
3525 self.py_operation_function(),
3526 self.dup.py_result(),
3527 self.rhs.py_result(),
3529 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3530 code.put_gotref(self.result_value.py_result())
3531 self.result_value.generate_evaluation_code(code) # May be a type check...
3532 self.rhs.generate_disposal_code(code)
3533 self.rhs.free_temps(code)
3534 self.dup.generate_disposal_code(code)
3535 self.dup.free_temps(code)
3536 self.lhs.generate_assignment_code(self.result_value, code)
3537 self.result_value_temp.release(code)
3539 c_op = self.operator
3543 error(self.pos, "No C inplace power operator")
3544 elif self.lhs.type.is_complex:
3545 error(self.pos, "Inplace operators not implemented for complex types.")
3547 # have to do assignment directly to avoid side-effects
3548 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3549 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3551 self.dup.generate_result_code(code)
3552 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3553 self.rhs.generate_disposal_code(code)
3554 self.rhs.free_temps(code)
3555 if self.dup.is_temp:
3556 self.dup.generate_subexpr_disposal_code(code)
3557 self.dup.free_subexpr_temps(code)
3559 def create_dup_node(self, env):
3562 self.dup.analyse_types(env)
3563 if isinstance(self.lhs, ExprNodes.NameNode):
3564 target_lhs = ExprNodes.NameNode(self.dup.pos,
3565 name = self.dup.name,
3566 is_temp = self.dup.is_temp,
3567 entry = self.dup.entry)
3568 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3569 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3570 obj = ExprNodes.CloneNode(self.lhs.obj),
3571 attribute = self.dup.attribute,
3572 is_temp = self.dup.is_temp)
3573 elif isinstance(self.lhs, ExprNodes.IndexNode):
3575 index = ExprNodes.CloneNode(self.lhs.index)
3578 if self.lhs.indices:
3579 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3582 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3583 base = ExprNodes.CloneNode(self.dup.base),
3586 is_temp = self.dup.is_temp)
3588 assert False, "Unsupported node: %s" % type(self.lhs)
3589 self.lhs = target_lhs
3592 def py_operation_function(self):
3593 return self.py_functions[self.operator]
3596 "|": "PyNumber_InPlaceOr",
3597 "^": "PyNumber_InPlaceXor",
3598 "&": "PyNumber_InPlaceAnd",
3599 "+": "PyNumber_InPlaceAdd",
3600 "-": "PyNumber_InPlaceSubtract",
3601 "*": "PyNumber_InPlaceMultiply",
3602 "/": "__Pyx_PyNumber_InPlaceDivide",
3603 "%": "PyNumber_InPlaceRemainder",
3604 "<<": "PyNumber_InPlaceLshift",
3605 ">>": "PyNumber_InPlaceRshift",
3606 "**": "PyNumber_InPlacePower",
3607 "//": "PyNumber_InPlaceFloorDivide",
3610 def annotate(self, code):
3611 self.lhs.annotate(code)
3612 self.rhs.annotate(code)
3613 self.dup.annotate(code)
3615 def create_binop_node(self):
3617 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3620 class PrintStatNode(StatNode):
3623 # arg_tuple TupleNode
3624 # stream ExprNode or None (stdout)
3625 # append_newline boolean
3627 child_attrs = ["arg_tuple", "stream"]
3629 def analyse_expressions(self, env):
3631 self.stream.analyse_expressions(env)
3632 self.stream = self.stream.coerce_to_pyobject(env)
3633 self.arg_tuple.analyse_expressions(env)
3634 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3635 env.use_utility_code(printing_utility_code)
3636 if len(self.arg_tuple.args) == 1 and self.append_newline:
3637 env.use_utility_code(printing_one_utility_code)
3639 nogil_check = Node.gil_error
3640 gil_message = "Python print statement"
3642 def generate_execution_code(self, code):
3644 self.stream.generate_evaluation_code(code)
3645 stream_result = self.stream.py_result()
3648 if len(self.arg_tuple.args) == 1 and self.append_newline:
3649 arg = self.arg_tuple.args[0]
3650 arg.generate_evaluation_code(code)
3653 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3656 code.error_goto(self.pos)))
3657 arg.generate_disposal_code(code)
3658 arg.free_temps(code)
3660 self.arg_tuple.generate_evaluation_code(code)
3662 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3664 self.arg_tuple.py_result(),
3665 self.append_newline,
3666 code.error_goto(self.pos)))
3667 self.arg_tuple.generate_disposal_code(code)
3668 self.arg_tuple.free_temps(code)
3671 self.stream.generate_disposal_code(code)
3672 self.stream.free_temps(code)
3674 def generate_function_definitions(self, env, code):
3676 self.stream.generate_function_definitions(env, code)
3677 self.arg_tuple.generate_function_definitions(env, code)
3679 def annotate(self, code):
3681 self.stream.annotate(code)
3682 self.arg_tuple.annotate(code)
3685 class ExecStatNode(StatNode):
3690 child_attrs = ["args"]
3692 def analyse_expressions(self, env):
3693 for i, arg in enumerate(self.args):
3694 arg.analyse_expressions(env)
3695 arg = arg.coerce_to_pyobject(env)
3697 env.use_utility_code(Builtin.pyexec_utility_code)
3699 nogil_check = Node.gil_error
3700 gil_message = "Python exec statement"
3702 def generate_execution_code(self, code):
3704 for arg in self.args:
3705 arg.generate_evaluation_code(code)
3706 args.append( arg.py_result() )
3707 args = tuple(args + ['0', '0'][:3-len(args)])
3708 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3709 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3710 (temp_result,) + args))
3711 for arg in self.args:
3712 arg.generate_disposal_code(code)
3713 arg.free_temps(code)
3715 code.error_goto_if_null(temp_result, self.pos))
3716 code.put_gotref(temp_result)
3717 code.put_decref_clear(temp_result, py_object_type)
3718 code.funcstate.release_temp(temp_result)
3720 def annotate(self, code):
3721 for arg in self.args:
3725 class DelStatNode(StatNode):
3730 child_attrs = ["args"]
3732 def analyse_declarations(self, env):
3733 for arg in self.args:
3734 arg.analyse_target_declaration(env)
3736 def analyse_expressions(self, env):
3737 for arg in self.args:
3738 arg.analyse_target_expression(env, None)
3739 if arg.type.is_pyobject:
3741 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3743 elif arg.type.is_cpp_class:
3744 error(arg.pos, "Deletion of non-heap C++ object")
3746 error(arg.pos, "Deletion of non-Python, non-C++ object")
3747 #arg.release_target_temp(env)
3749 def nogil_check(self, env):
3750 for arg in self.args:
3751 if arg.type.is_pyobject:
3754 gil_message = "Deleting Python object"
3756 def generate_execution_code(self, code):
3757 for arg in self.args:
3758 if arg.type.is_pyobject:
3759 arg.generate_deletion_code(code)
3760 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3761 arg.generate_result_code(code)
3762 code.putln("delete %s;" % arg.result())
3763 # else error reported earlier
3765 def annotate(self, code):
3766 for arg in self.args:
3770 class PassStatNode(StatNode):
3775 def analyse_expressions(self, env):
3778 def generate_execution_code(self, code):
3782 class BreakStatNode(StatNode):
3786 def analyse_expressions(self, env):
3789 def generate_execution_code(self, code):
3790 if not code.break_label:
3791 error(self.pos, "break statement not inside loop")
3793 code.put_goto(code.break_label)
3796 class ContinueStatNode(StatNode):
3800 def analyse_expressions(self, env):
3803 def generate_execution_code(self, code):
3804 if code.funcstate.in_try_finally:
3805 error(self.pos, "continue statement inside try of try...finally")
3806 elif not code.continue_label:
3807 error(self.pos, "continue statement not inside loop")
3809 code.put_goto(code.continue_label)
3812 class ReturnStatNode(StatNode):
3815 # value ExprNode or None
3816 # return_type PyrexType
3818 child_attrs = ["value"]
3820 def analyse_expressions(self, env):
3821 return_type = env.return_type
3822 self.return_type = return_type
3824 error(self.pos, "Return not inside a function body")
3827 self.value.analyse_types(env)
3828 if return_type.is_void or return_type.is_returncode:
3829 error(self.value.pos,
3830 "Return with value in void function")
3832 self.value = self.value.coerce_to(env.return_type, env)
3834 if (not return_type.is_void
3835 and not return_type.is_pyobject
3836 and not return_type.is_returncode):
3837 error(self.pos, "Return value required")
3839 def nogil_check(self, env):
3840 if self.return_type.is_pyobject:
3843 gil_message = "Returning Python object"
3845 def generate_execution_code(self, code):
3846 code.mark_pos(self.pos)
3847 if not self.return_type:
3848 # error reported earlier
3850 if self.return_type.is_pyobject:
3851 code.put_xdecref(Naming.retval_cname,
3854 self.value.generate_evaluation_code(code)
3855 self.value.make_owned_reference(code)
3858 Naming.retval_cname,
3859 self.value.result_as(self.return_type)))
3860 self.value.generate_post_assignment_code(code)
3861 self.value.free_temps(code)
3863 if self.return_type.is_pyobject:
3864 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3865 elif self.return_type.is_returncode:
3868 Naming.retval_cname,
3869 self.return_type.default_value))
3870 for cname, type in code.funcstate.temps_holding_reference():
3871 code.put_decref_clear(cname, type)
3872 code.put_goto(code.return_label)
3874 def generate_function_definitions(self, env, code):
3875 if self.value is not None:
3876 self.value.generate_function_definitions(env, code)
3878 def annotate(self, code):
3880 self.value.annotate(code)
3883 class RaiseStatNode(StatNode):
3886 # exc_type ExprNode or None
3887 # exc_value ExprNode or None
3888 # exc_tb ExprNode or None
3890 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3892 def analyse_expressions(self, env):
3894 self.exc_type.analyse_types(env)
3895 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3897 self.exc_value.analyse_types(env)
3898 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3900 self.exc_tb.analyse_types(env)
3901 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3902 env.use_utility_code(raise_utility_code)
3904 nogil_check = Node.gil_error
3905 gil_message = "Raising exception"
3907 def generate_execution_code(self, code):
3909 self.exc_type.generate_evaluation_code(code)
3910 type_code = self.exc_type.py_result()
3914 self.exc_value.generate_evaluation_code(code)
3915 value_code = self.exc_value.py_result()
3919 self.exc_tb.generate_evaluation_code(code)
3920 tb_code = self.exc_tb.py_result()
3924 "__Pyx_Raise(%s, %s, %s);" % (
3928 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3930 obj.generate_disposal_code(code)
3931 obj.free_temps(code)
3933 code.error_goto(self.pos))
3935 def generate_function_definitions(self, env, code):
3936 if self.exc_type is not None:
3937 self.exc_type.generate_function_definitions(env, code)
3938 if self.exc_value is not None:
3939 self.exc_value.generate_function_definitions(env, code)
3940 if self.exc_tb is not None:
3941 self.exc_tb.generate_function_definitions(env, code)
3943 def annotate(self, code):
3945 self.exc_type.annotate(code)
3947 self.exc_value.annotate(code)
3949 self.exc_tb.annotate(code)
3952 class ReraiseStatNode(StatNode):
3956 def analyse_expressions(self, env):
3957 env.use_utility_code(restore_exception_utility_code)
3959 nogil_check = Node.gil_error
3960 gil_message = "Raising exception"
3962 def generate_execution_code(self, code):
3963 vars = code.funcstate.exc_vars
3965 for varname in vars:
3966 code.put_giveref(varname)
3967 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3968 for varname in vars:
3969 code.put("%s = 0; " % varname)
3971 code.putln(code.error_goto(self.pos))
3973 error(self.pos, "Reraise not inside except clause")
3976 class AssertStatNode(StatNode):
3980 # value ExprNode or None
3982 child_attrs = ["cond", "value"]
3984 def analyse_expressions(self, env):
3985 self.cond = self.cond.analyse_boolean_expression(env)
3987 self.value.analyse_types(env)
3988 self.value = self.value.coerce_to_pyobject(env)
3990 nogil_check = Node.gil_error
3991 gil_message = "Raising exception"
3993 def generate_execution_code(self, code):
3994 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3995 self.cond.generate_evaluation_code(code)
3997 "if (unlikely(!%s)) {" %
4000 self.value.generate_evaluation_code(code)
4002 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4003 self.value.py_result())
4004 self.value.generate_disposal_code(code)
4005 self.value.free_temps(code)
4008 "PyErr_SetNone(PyExc_AssertionError);")
4010 code.error_goto(self.pos))
4013 self.cond.generate_disposal_code(code)
4014 self.cond.free_temps(code)
4015 code.putln("#endif")
4017 def generate_function_definitions(self, env, code):
4018 self.cond.generate_function_definitions(env, code)
4019 if self.value is not None:
4020 self.value.generate_function_definitions(env, code)
4022 def annotate(self, code):
4023 self.cond.annotate(code)
4025 self.value.annotate(code)
4028 class IfStatNode(StatNode):
4031 # if_clauses [IfClauseNode]
4032 # else_clause StatNode or None
4034 child_attrs = ["if_clauses", "else_clause"]
4036 def analyse_control_flow(self, env):
4037 env.start_branching(self.pos)
4038 for if_clause in self.if_clauses:
4039 if_clause.analyse_control_flow(env)
4040 env.next_branch(if_clause.end_pos())
4041 if self.else_clause:
4042 self.else_clause.analyse_control_flow(env)
4043 env.finish_branching(self.end_pos())
4045 def analyse_declarations(self, env):
4046 for if_clause in self.if_clauses:
4047 if_clause.analyse_declarations(env)
4048 if self.else_clause:
4049 self.else_clause.analyse_declarations(env)
4051 def analyse_expressions(self, env):
4052 for if_clause in self.if_clauses:
4053 if_clause.analyse_expressions(env)
4054 if self.else_clause:
4055 self.else_clause.analyse_expressions(env)
4057 def generate_execution_code(self, code):
4058 code.mark_pos(self.pos)
4059 end_label = code.new_label()
4060 for if_clause in self.if_clauses:
4061 if_clause.generate_execution_code(code, end_label)
4062 if self.else_clause:
4063 code.putln("/*else*/ {")
4064 self.else_clause.generate_execution_code(code)
4066 code.put_label(end_label)
4068 def generate_function_definitions(self, env, code):
4069 for clause in self.if_clauses:
4070 clause.generate_function_definitions(env, code)
4071 if self.else_clause is not None:
4072 self.else_clause.generate_function_definitions(env, code)
4074 def annotate(self, code):
4075 for if_clause in self.if_clauses:
4076 if_clause.annotate(code)
4077 if self.else_clause:
4078 self.else_clause.annotate(code)
4081 class IfClauseNode(Node):
4082 # if or elif clause in an if statement
4084 # condition ExprNode
4087 child_attrs = ["condition", "body"]
4089 def analyse_control_flow(self, env):
4090 self.body.analyse_control_flow(env)
4092 def analyse_declarations(self, env):
4093 self.condition.analyse_declarations(env)
4094 self.body.analyse_declarations(env)
4096 def analyse_expressions(self, env):
4098 self.condition.analyse_temp_boolean_expression(env)
4099 self.body.analyse_expressions(env)
4101 def get_constant_condition_result(self):
4102 if self.condition.has_constant_result():
4103 return bool(self.condition.constant_result)
4107 def generate_execution_code(self, code, end_label):
4108 self.condition.generate_evaluation_code(code)
4111 self.condition.result())
4112 self.condition.generate_disposal_code(code)
4113 self.condition.free_temps(code)
4114 self.body.generate_execution_code(code)
4115 code.put_goto(end_label)
4118 def generate_function_definitions(self, env, code):
4119 self.condition.generate_function_definitions(env, code)
4120 self.body.generate_function_definitions(env, code)
4122 def annotate(self, code):
4123 self.condition.annotate(code)
4124 self.body.annotate(code)
4127 class SwitchCaseNode(StatNode):
4128 # Generated in the optimization of an if-elif-else node
4130 # conditions [ExprNode]
4133 child_attrs = ['conditions', 'body']
4135 def generate_execution_code(self, code):
4136 for cond in self.conditions:
4137 code.mark_pos(cond.pos)
4138 cond.generate_evaluation_code(code)
4139 code.putln("case %s:" % cond.result())
4140 self.body.generate_execution_code(code)
4141 code.putln("break;")
4143 def generate_function_definitions(self, env, code):
4144 for cond in self.conditions:
4145 cond.generate_function_definitions(env, code)
4146 self.body.generate_function_definitions(env, code)
4148 def annotate(self, code):
4149 for cond in self.conditions:
4151 self.body.annotate(code)
4153 class SwitchStatNode(StatNode):
4154 # Generated in the optimization of an if-elif-else node
4157 # cases [SwitchCaseNode]
4158 # else_clause StatNode or None
4160 child_attrs = ['test', 'cases', 'else_clause']
4162 def generate_execution_code(self, code):
4163 code.putln("switch (%s) {" % self.test.result())
4164 for case in self.cases:
4165 case.generate_execution_code(code)
4166 if self.else_clause is not None:
4167 code.putln("default:")
4168 self.else_clause.generate_execution_code(code)
4169 code.putln("break;")
4172 def generate_function_definitions(self, env, code):
4173 self.test.generate_function_definitions(env, code)
4174 for case in self.cases:
4175 case.generate_function_definitions(env, code)
4176 if self.else_clause is not None:
4177 self.else_clause.generate_function_definitions(env, code)
4179 def annotate(self, code):
4180 self.test.annotate(code)
4181 for case in self.cases:
4183 if self.else_clause is not None:
4184 self.else_clause.annotate(code)
4186 class LoopNode(object):
4188 def analyse_control_flow(self, env):
4189 env.start_branching(self.pos)
4190 self.body.analyse_control_flow(env)
4191 env.next_branch(self.body.end_pos())
4192 if self.else_clause:
4193 self.else_clause.analyse_control_flow(env)
4194 env.finish_branching(self.end_pos())
4197 class WhileStatNode(LoopNode, StatNode):
4200 # condition ExprNode
4202 # else_clause StatNode
4204 child_attrs = ["condition", "body", "else_clause"]
4206 def analyse_declarations(self, env):
4207 self.body.analyse_declarations(env)
4208 if self.else_clause:
4209 self.else_clause.analyse_declarations(env)
4211 def analyse_expressions(self, env):
4213 self.condition.analyse_temp_boolean_expression(env)
4214 self.body.analyse_expressions(env)
4215 if self.else_clause:
4216 self.else_clause.analyse_expressions(env)
4218 def generate_execution_code(self, code):
4219 old_loop_labels = code.new_loop_labels()
4222 self.condition.generate_evaluation_code(code)
4223 self.condition.generate_disposal_code(code)
4226 self.condition.result())
4227 self.condition.free_temps(code)
4228 self.body.generate_execution_code(code)
4229 code.put_label(code.continue_label)
4231 break_label = code.break_label
4232 code.set_loop_labels(old_loop_labels)
4233 if self.else_clause:
4234 code.putln("/*else*/ {")
4235 self.else_clause.generate_execution_code(code)
4237 code.put_label(break_label)
4239 def generate_function_definitions(self, env, code):
4240 self.condition.generate_function_definitions(env, code)
4241 self.body.generate_function_definitions(env, code)
4242 if self.else_clause is not None:
4243 self.else_clause.generate_function_definitions(env, code)
4245 def annotate(self, code):
4246 self.condition.annotate(code)
4247 self.body.annotate(code)
4248 if self.else_clause:
4249 self.else_clause.annotate(code)
4252 def ForStatNode(pos, **kw):
4253 if 'iterator' in kw:
4254 return ForInStatNode(pos, **kw)
4256 return ForFromStatNode(pos, **kw)
4258 class ForInStatNode(LoopNode, StatNode):
4262 # iterator IteratorNode
4264 # else_clause StatNode
4265 # item NextNode used internally
4267 child_attrs = ["target", "iterator", "body", "else_clause"]
4270 def analyse_declarations(self, env):
4271 self.target.analyse_target_declaration(env)
4272 self.body.analyse_declarations(env)
4273 if self.else_clause:
4274 self.else_clause.analyse_declarations(env)
4276 def analyse_expressions(self, env):
4278 self.target.analyse_target_types(env)
4279 self.iterator.analyse_expressions(env)
4280 self.item = ExprNodes.NextNode(self.iterator, env)
4281 self.item = self.item.coerce_to(self.target.type, env)
4282 self.body.analyse_expressions(env)
4283 if self.else_clause:
4284 self.else_clause.analyse_expressions(env)
4286 def generate_execution_code(self, code):
4287 old_loop_labels = code.new_loop_labels()
4288 self.iterator.allocate_counter_temp(code)
4289 self.iterator.generate_evaluation_code(code)
4292 self.item.generate_evaluation_code(code)
4293 self.target.generate_assignment_code(self.item, code)
4294 self.body.generate_execution_code(code)
4295 code.put_label(code.continue_label)
4298 break_label = code.break_label
4299 code.set_loop_labels(old_loop_labels)
4301 if self.else_clause:
4302 # in nested loops, the 'else' block can contain a
4303 # 'continue' statement for the outer loop, but we may need
4304 # to generate cleanup code before taking that path, so we
4306 orig_continue_label = code.continue_label
4307 code.continue_label = code.new_label('outer_continue')
4309 code.putln("/*else*/ {")
4310 self.else_clause.generate_execution_code(code)
4313 if code.label_used(code.continue_label):
4314 code.put_goto(break_label)
4315 code.put_label(code.continue_label)
4316 self.iterator.generate_disposal_code(code)
4317 code.put_goto(orig_continue_label)
4318 code.set_loop_labels(old_loop_labels)
4320 if code.label_used(break_label):
4321 code.put_label(break_label)
4322 self.iterator.release_counter_temp(code)
4323 self.iterator.generate_disposal_code(code)
4324 self.iterator.free_temps(code)
4326 def generate_function_definitions(self, env, code):
4327 self.target.generate_function_definitions(env, code)
4328 self.iterator.generate_function_definitions(env, code)
4329 self.body.generate_function_definitions(env, code)
4330 if self.else_clause is not None:
4331 self.else_clause.generate_function_definitions(env, code)
4333 def annotate(self, code):
4334 self.target.annotate(code)
4335 self.iterator.annotate(code)
4336 self.body.annotate(code)
4337 if self.else_clause:
4338 self.else_clause.annotate(code)
4339 self.item.annotate(code)
4342 class ForFromStatNode(LoopNode, StatNode):
4343 # for name from expr rel name rel expr
4350 # step ExprNode or None
4352 # else_clause StatNode or None
4358 # loopvar_node ExprNode (usually a NameNode or temp node)
4359 # py_loopvar_node PyTempNode or None
4360 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4362 is_py_target = False
4364 py_loopvar_node = None
4367 gil_message = "For-loop using object bounds or target"
4369 def nogil_check(self, env):
4370 for x in (self.target, self.bound1, self.bound2):
4371 if x.type.is_pyobject:
4374 def analyse_declarations(self, env):
4375 self.target.analyse_target_declaration(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.target.analyse_target_types(env)
4383 self.bound1.analyse_types(env)
4384 self.bound2.analyse_types(env)
4385 if self.step is not None:
4386 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4387 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4388 self.step.analyse_types(env)
4390 target_type = self.target.type
4391 if self.target.type.is_numeric:
4392 loop_type = self.target.type
4394 loop_type = PyrexTypes.c_int_type
4395 if not self.bound1.type.is_pyobject:
4396 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4397 if not self.bound2.type.is_pyobject:
4398 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4399 if self.step is not None and not self.step.type.is_pyobject:
4400 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4401 self.bound1 = self.bound1.coerce_to(loop_type, env)
4402 self.bound2 = self.bound2.coerce_to(loop_type, env)
4403 if not self.bound2.is_literal:
4404 self.bound2 = self.bound2.coerce_to_temp(env)
4405 if self.step is not None:
4406 self.step = self.step.coerce_to(loop_type, env)
4407 if not self.step.is_literal:
4408 self.step = self.step.coerce_to_temp(env)
4410 target_type = self.target.type
4411 if not (target_type.is_pyobject or target_type.is_numeric):
4412 error(self.target.pos,
4413 "for-from loop variable must be c numeric type or Python object")
4414 if target_type.is_numeric:
4415 self.is_py_target = False
4416 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4417 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4418 self.loopvar_node = self.target
4419 self.py_loopvar_node = None
4421 self.is_py_target = True
4422 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4423 self.loopvar_node = c_loopvar_node
4424 self.py_loopvar_node = \
4425 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4426 self.body.analyse_expressions(env)
4427 if self.else_clause:
4428 self.else_clause.analyse_expressions(env)
4430 def generate_execution_code(self, code):
4431 old_loop_labels = code.new_loop_labels()
4432 from_range = self.from_range
4433 self.bound1.generate_evaluation_code(code)
4434 self.bound2.generate_evaluation_code(code)
4435 offset, incop = self.relation_table[self.relation1]
4436 if self.step is not None:
4437 self.step.generate_evaluation_code(code)
4438 step = self.step.result()
4439 incop = "%s=%s" % (incop[0], step)
4441 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4442 self.loopvar_node.allocate(code)
4443 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4444 self.py_loopvar_node.allocate(code)
4446 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4448 loopvar_name = self.loopvar_node.result()
4450 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4452 self.bound1.result(), offset,
4453 loopvar_name, self.relation2, self.bound2.result(),
4454 loopvar_name, incop))
4455 if self.py_loopvar_node:
4456 self.py_loopvar_node.generate_evaluation_code(code)
4457 self.target.generate_assignment_code(self.py_loopvar_node, code)
4459 code.putln("%s = %s;" % (
4460 self.target.result(), loopvar_name))
4461 self.body.generate_execution_code(code)
4462 code.put_label(code.continue_label)
4463 if self.py_loopvar_node:
4464 # This mess is to make for..from loops with python targets behave
4465 # exactly like those with C targets with regards to re-assignment
4466 # of the loop variable.
4468 if self.target.entry.is_pyglobal:
4469 # We know target is a NameNode, this is the only ugly case.
4470 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4471 target_node.allocate(code)
4472 interned_cname = code.intern_identifier(self.target.entry.name)
4473 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4474 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4475 target_node.result(),
4476 Naming.module_cname,
4478 code.error_goto_if_null(target_node.result(), self.target.pos)))
4479 code.put_gotref(target_node.result())
4481 target_node = self.target
4482 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4483 from_py_node.temp_code = loopvar_name
4484 from_py_node.generate_result_code(code)
4485 if self.target.entry.is_pyglobal:
4486 code.put_decref(target_node.result(), target_node.type)
4487 target_node.release(code)
4489 if self.py_loopvar_node:
4490 # This is potentially wasteful, but we don't want the semantics to
4491 # depend on whether or not the loop is a python type.
4492 self.py_loopvar_node.generate_evaluation_code(code)
4493 self.target.generate_assignment_code(self.py_loopvar_node, code)
4495 code.funcstate.release_temp(loopvar_name)
4496 break_label = code.break_label
4497 code.set_loop_labels(old_loop_labels)
4498 if self.else_clause:
4499 code.putln("/*else*/ {")
4500 self.else_clause.generate_execution_code(code)
4502 code.put_label(break_label)
4503 self.bound1.generate_disposal_code(code)
4504 self.bound1.free_temps(code)
4505 self.bound2.generate_disposal_code(code)
4506 self.bound2.free_temps(code)
4507 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4508 self.loopvar_node.release(code)
4509 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4510 self.py_loopvar_node.release(code)
4511 if self.step is not None:
4512 self.step.generate_disposal_code(code)
4513 self.step.free_temps(code)
4516 # {relop : (initial offset, increment op)}
4523 def generate_function_definitions(self, env, code):
4524 self.target.generate_function_definitions(env, code)
4525 self.bound1.generate_function_definitions(env, code)
4526 self.bound2.generate_function_definitions(env, code)
4527 if self.step is not None:
4528 self.step.generate_function_definitions(env, code)
4529 self.body.generate_function_definitions(env, code)
4530 if self.else_clause is not None:
4531 self.else_clause.generate_function_definitions(env, code)
4533 def annotate(self, code):
4534 self.target.annotate(code)
4535 self.bound1.annotate(code)
4536 self.bound2.annotate(code)
4538 self.step.annotate(code)
4539 self.body.annotate(code)
4540 if self.else_clause:
4541 self.else_clause.annotate(code)
4544 class WithStatNode(StatNode):
4546 Represents a Python with statement.
4548 This is only used at parse tree level; and is not present in
4549 analysis or generation phases.
4551 # manager The with statement manager object
4552 # target Node (lhs expression)
4554 child_attrs = ["manager", "target", "body"]
4556 class TryExceptStatNode(StatNode):
4557 # try .. except statement
4560 # except_clauses [ExceptClauseNode]
4561 # else_clause StatNode or None
4563 child_attrs = ["body", "except_clauses", "else_clause"]
4565 def analyse_control_flow(self, env):
4566 env.start_branching(self.pos)
4567 self.body.analyse_control_flow(env)
4568 successful_try = env.control_flow # grab this for later
4569 env.next_branch(self.body.end_pos())
4570 env.finish_branching(self.body.end_pos())
4572 env.start_branching(self.except_clauses[0].pos)
4573 for except_clause in self.except_clauses:
4574 except_clause.analyse_control_flow(env)
4575 env.next_branch(except_clause.end_pos())
4577 # the else cause it executed only when the try clause finishes
4578 env.control_flow.incoming = successful_try
4579 if self.else_clause:
4580 self.else_clause.analyse_control_flow(env)
4581 env.finish_branching(self.end_pos())
4583 def analyse_declarations(self, env):
4584 self.body.analyse_declarations(env)
4585 for except_clause in self.except_clauses:
4586 except_clause.analyse_declarations(env)
4587 if self.else_clause:
4588 self.else_clause.analyse_declarations(env)
4589 env.use_utility_code(reset_exception_utility_code)
4591 def analyse_expressions(self, env):
4592 self.body.analyse_expressions(env)
4593 default_clause_seen = 0
4594 for except_clause in self.except_clauses:
4595 except_clause.analyse_expressions(env)
4596 if default_clause_seen:
4597 error(except_clause.pos, "default 'except:' must be last")
4598 if not except_clause.pattern:
4599 default_clause_seen = 1
4600 self.has_default_clause = default_clause_seen
4601 if self.else_clause:
4602 self.else_clause.analyse_expressions(env)
4604 nogil_check = Node.gil_error
4605 gil_message = "Try-except statement"
4607 def generate_execution_code(self, code):
4608 old_return_label = code.return_label
4609 old_break_label = code.break_label
4610 old_continue_label = code.continue_label
4611 old_error_label = code.new_error_label()
4612 our_error_label = code.error_label
4613 except_end_label = code.new_label('exception_handled')
4614 except_error_label = code.new_label('except_error')
4615 except_return_label = code.new_label('except_return')
4616 try_return_label = code.new_label('try_return')
4617 try_break_label = code.new_label('try_break')
4618 try_continue_label = code.new_label('try_continue')
4619 try_end_label = code.new_label('try_end')
4622 code.putln("PyObject %s;" %
4623 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4624 code.putln("__Pyx_ExceptionSave(%s);" %
4625 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4626 for var in Naming.exc_save_vars:
4627 code.put_xgotref(var)
4630 code.return_label = try_return_label
4631 code.break_label = try_break_label
4632 code.continue_label = try_continue_label
4633 self.body.generate_execution_code(code)
4636 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4637 code.error_label = except_error_label
4638 code.return_label = except_return_label
4639 if self.else_clause:
4642 self.else_clause.generate_execution_code(code)
4645 for var in Naming.exc_save_vars:
4646 code.put_xdecref_clear(var, py_object_type)
4647 code.put_goto(try_end_label)
4648 if code.label_used(try_return_label):
4649 code.put_label(try_return_label)
4650 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4651 code.putln("__Pyx_ExceptionReset(%s);" %
4652 ', '.join(Naming.exc_save_vars))
4653 code.put_goto(old_return_label)
4654 code.put_label(our_error_label)
4655 for temp_name, type in temps_to_clean_up:
4656 code.put_xdecref_clear(temp_name, type)
4657 for except_clause in self.except_clauses:
4658 except_clause.generate_handling_code(code, except_end_label)
4660 error_label_used = code.label_used(except_error_label)
4661 if error_label_used or not self.has_default_clause:
4662 if error_label_used:
4663 code.put_label(except_error_label)
4664 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4665 code.putln("__Pyx_ExceptionReset(%s);" %
4666 ', '.join(Naming.exc_save_vars))
4667 code.put_goto(old_error_label)
4669 for exit_label, old_label in zip(
4670 [try_break_label, try_continue_label, except_return_label],
4671 [old_break_label, old_continue_label, old_return_label]):
4673 if code.label_used(exit_label):
4674 code.put_label(exit_label)
4675 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4676 code.putln("__Pyx_ExceptionReset(%s);" %
4677 ', '.join(Naming.exc_save_vars))
4678 code.put_goto(old_label)
4680 if code.label_used(except_end_label):
4681 code.put_label(except_end_label)
4682 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4683 code.putln("__Pyx_ExceptionReset(%s);" %
4684 ', '.join(Naming.exc_save_vars))
4685 code.put_label(try_end_label)
4688 code.return_label = old_return_label
4689 code.break_label = old_break_label
4690 code.continue_label = old_continue_label
4691 code.error_label = old_error_label
4693 def generate_function_definitions(self, env, code):
4694 self.body.generate_function_definitions(env, code)
4695 for except_clause in self.except_clauses:
4696 except_clause.generate_function_definitions(env, code)
4697 if self.else_clause is not None:
4698 self.else_clause.generate_function_definitions(env, code)
4700 def annotate(self, code):
4701 self.body.annotate(code)
4702 for except_node in self.except_clauses:
4703 except_node.annotate(code)
4704 if self.else_clause:
4705 self.else_clause.annotate(code)
4708 class ExceptClauseNode(Node):
4709 # Part of try ... except statement.
4712 # target ExprNode or None
4714 # excinfo_target NameNode or None optional target for exception info
4715 # match_flag string result of exception match
4716 # exc_value ExcValueNode used internally
4717 # function_name string qualified name of enclosing function
4718 # exc_vars (string * 3) local exception variables
4720 # excinfo_target is never set by the parser, but can be set by a transform
4721 # in order to extract more extensive information about the exception as a
4722 # sys.exc_info()-style tuple into a target variable
4724 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4727 excinfo_target = None
4729 def analyse_declarations(self, env):
4731 self.target.analyse_target_declaration(env)
4732 if self.excinfo_target is not None:
4733 self.excinfo_target.analyse_target_declaration(env)
4734 self.body.analyse_declarations(env)
4736 def analyse_expressions(self, env):
4738 genv = env.global_scope()
4739 self.function_name = env.qualified_name
4741 self.pattern.analyse_expressions(env)
4742 self.pattern = self.pattern.coerce_to_pyobject(env)
4745 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4746 self.target.analyse_target_expression(env, self.exc_value)
4747 if self.excinfo_target is not None:
4749 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4750 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4751 self.excinfo_tuple.analyse_expressions(env)
4752 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4754 self.body.analyse_expressions(env)
4756 def generate_handling_code(self, code, end_label):
4757 code.mark_pos(self.pos)
4759 self.pattern.generate_evaluation_code(code)
4761 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4763 "%s = PyErr_ExceptionMatches(%s);" % (
4765 self.pattern.py_result()))
4766 self.pattern.generate_disposal_code(code)
4767 self.pattern.free_temps(code)
4771 code.funcstate.release_temp(match_flag)
4773 code.putln("/*except:*/ {")
4775 if not getattr(self.body, 'stats', True) and \
4776 self.excinfo_target is None and self.target is None:
4777 # most simple case: no exception variable, empty body (pass)
4778 # => reset the exception state, done
4779 code.putln("PyErr_Restore(0,0,0);")
4780 code.put_goto(end_label)
4784 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4787 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4788 # We always have to fetch the exception value even if
4789 # there is no target, because this also normalises the
4790 # exception and stores it in the thread state.
4791 code.globalstate.use_utility_code(get_exception_utility_code)
4792 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4793 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4794 code.error_goto(self.pos)))
4798 self.exc_value.set_var(exc_vars[1])
4799 self.exc_value.generate_evaluation_code(code)
4800 self.target.generate_assignment_code(self.exc_value, code)
4801 if self.excinfo_target is not None:
4802 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4803 node.set_var(tempvar)
4804 self.excinfo_tuple.generate_evaluation_code(code)
4805 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4807 old_break_label, old_continue_label = code.break_label, code.continue_label
4808 code.break_label = code.new_label('except_break')
4809 code.continue_label = code.new_label('except_continue')
4811 old_exc_vars = code.funcstate.exc_vars
4812 code.funcstate.exc_vars = exc_vars
4813 self.body.generate_execution_code(code)
4814 code.funcstate.exc_vars = old_exc_vars
4815 for var in exc_vars:
4816 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4817 code.put_goto(end_label)
4819 if code.label_used(code.break_label):
4820 code.put_label(code.break_label)
4821 for var in exc_vars:
4822 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4823 code.put_goto(old_break_label)
4824 code.break_label = old_break_label
4826 if code.label_used(code.continue_label):
4827 code.put_label(code.continue_label)
4828 for var in exc_vars:
4829 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4830 code.put_goto(old_continue_label)
4831 code.continue_label = old_continue_label
4833 for temp in exc_vars:
4834 code.funcstate.release_temp(temp)
4839 def generate_function_definitions(self, env, code):
4840 if self.target is not None:
4841 self.target.generate_function_definitions(env, code)
4842 self.body.generate_function_definitions(env, code)
4844 def annotate(self, code):
4846 self.pattern.annotate(code)
4848 self.target.annotate(code)
4849 self.body.annotate(code)
4852 class TryFinallyStatNode(StatNode):
4853 # try ... finally statement
4856 # finally_clause StatNode
4858 # The plan is that we funnel all continue, break
4859 # return and error gotos into the beginning of the
4860 # finally block, setting a variable to remember which
4861 # one we're doing. At the end of the finally block, we
4862 # switch on the variable to figure out where to go.
4863 # In addition, if we're doing an error, we save the
4864 # exception on entry to the finally block and restore
4867 child_attrs = ["body", "finally_clause"]
4869 preserve_exception = 1
4871 disallow_continue_in_try_finally = 0
4872 # There doesn't seem to be any point in disallowing
4873 # continue in the try block, since we have no problem
4876 def create_analysed(pos, env, body, finally_clause):
4877 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4879 create_analysed = staticmethod(create_analysed)
4881 def analyse_control_flow(self, env):
4882 env.start_branching(self.pos)
4883 self.body.analyse_control_flow(env)
4884 env.next_branch(self.body.end_pos())
4885 env.finish_branching(self.body.end_pos())
4886 self.finally_clause.analyse_control_flow(env)
4888 def analyse_declarations(self, env):
4889 self.body.analyse_declarations(env)
4890 self.finally_clause.analyse_declarations(env)
4892 def analyse_expressions(self, env):
4893 self.body.analyse_expressions(env)
4894 self.finally_clause.analyse_expressions(env)
4896 nogil_check = Node.gil_error
4897 gil_message = "Try-finally statement"
4899 def generate_execution_code(self, code):
4900 old_error_label = code.error_label
4901 old_labels = code.all_new_labels()
4902 new_labels = code.get_all_labels()
4903 new_error_label = code.error_label
4904 catch_label = code.new_label()
4907 if self.disallow_continue_in_try_finally:
4908 was_in_try_finally = code.funcstate.in_try_finally
4909 code.funcstate.in_try_finally = 1
4910 self.body.generate_execution_code(code)
4911 if self.disallow_continue_in_try_finally:
4912 code.funcstate.in_try_finally = was_in_try_finally
4915 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4916 code.mark_pos(self.finally_clause.pos)
4920 error_label_used = 0
4921 for i, new_label in enumerate(new_labels):
4922 if new_label in code.labels_used:
4923 cases_used.append(i)
4924 if new_label == new_error_label:
4925 error_label_used = 1
4926 error_label_case = i
4930 if error_label_used and self.preserve_exception:
4932 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4934 "int %s;" % Naming.exc_lineno_name)
4935 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4936 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4937 code.putln(exc_var_init_zero)
4939 exc_var_init_zero = None
4940 code.use_label(catch_label)
4942 "__pyx_why = 0; goto %s;" % catch_label)
4943 for i in cases_used:
4944 new_label = new_labels[i]
4945 #if new_label and new_label != "<try>":
4946 if new_label == new_error_label and self.preserve_exception:
4947 self.put_error_catcher(code,
4948 new_error_label, i+1, catch_label, temps_to_clean_up)
4950 code.put('%s: ' % new_label)
4951 if exc_var_init_zero:
4952 code.putln(exc_var_init_zero)
4953 code.putln("__pyx_why = %s; goto %s;" % (
4956 code.put_label(catch_label)
4957 code.set_all_labels(old_labels)
4958 if error_label_used:
4959 code.new_error_label()
4960 finally_error_label = code.error_label
4961 self.finally_clause.generate_execution_code(code)
4962 if error_label_used:
4963 if finally_error_label in code.labels_used and self.preserve_exception:
4964 over_label = code.new_label()
4965 code.put_goto(over_label);
4966 code.put_label(finally_error_label)
4967 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4968 for var in Naming.exc_vars:
4969 code.putln("Py_XDECREF(%s);" % var)
4971 code.put_goto(old_error_label)
4972 code.put_label(over_label)
4973 code.error_label = old_error_label
4976 "switch (__pyx_why) {")
4977 for i in cases_used:
4978 old_label = old_labels[i]
4979 if old_label == old_error_label and self.preserve_exception:
4980 self.put_error_uncatcher(code, i+1, old_error_label)
4982 code.use_label(old_label)
4984 "case %s: goto %s;" % (
4992 def generate_function_definitions(self, env, code):
4993 self.body.generate_function_definitions(env, code)
4994 self.finally_clause.generate_function_definitions(env, code)
4996 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4997 code.globalstate.use_utility_code(restore_exception_utility_code)
5004 for temp_name, type in temps_to_clean_up:
5005 code.put_xdecref_clear(temp_name, type)
5007 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5011 Naming.exc_lineno_name, Naming.lineno_cname))
5012 code.put_goto(catch_label)
5015 def put_error_uncatcher(self, code, i, error_label):
5016 code.globalstate.use_utility_code(restore_exception_utility_code)
5021 "__Pyx_ErrRestore(%s, %s, %s);" %
5025 Naming.lineno_cname, Naming.exc_lineno_name))
5026 for var in Naming.exc_vars:
5030 code.put_goto(error_label)
5034 def annotate(self, code):
5035 self.body.annotate(code)
5036 self.finally_clause.annotate(code)
5039 class GILStatNode(TryFinallyStatNode):
5040 # 'with gil' or 'with nogil' statement
5042 # state string 'gil' or 'nogil'
5046 preserve_exception = 0
5048 def __init__(self, pos, state, body):
5050 TryFinallyStatNode.__init__(self, pos,
5052 finally_clause = GILExitNode(pos, state = state))
5054 def analyse_expressions(self, env):
5055 env.use_utility_code(force_init_threads_utility_code)
5056 was_nogil = env.nogil
5058 TryFinallyStatNode.analyse_expressions(self, env)
5059 env.nogil = was_nogil
5063 def generate_execution_code(self, code):
5064 code.mark_pos(self.pos)
5065 if self.state == 'gil':
5066 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5068 code.putln("{ PyThreadState *_save;")
5069 code.putln("Py_UNBLOCK_THREADS")
5070 TryFinallyStatNode.generate_execution_code(self, code)
5074 class GILExitNode(StatNode):
5075 # Used as the 'finally' block in a GILStatNode
5077 # state string 'gil' or 'nogil'
5081 def analyse_expressions(self, env):
5084 def generate_execution_code(self, code):
5085 if self.state == 'gil':
5086 code.putln("PyGILState_Release();")
5088 code.putln("Py_BLOCK_THREADS")
5091 class CImportStatNode(StatNode):
5094 # module_name string Qualified name of module being imported
5095 # as_name string or None Name specified in "as" clause, if any
5099 def analyse_declarations(self, env):
5100 if not env.is_module_scope:
5101 error(self.pos, "cimport only allowed at module level")
5103 module_scope = env.find_module(self.module_name, self.pos)
5104 if "." in self.module_name:
5105 names = [EncodedString(name) for name in self.module_name.split(".")]
5107 top_module_scope = env.context.find_submodule(top_name)
5108 module_scope = top_module_scope
5109 for name in names[1:]:
5110 submodule_scope = module_scope.find_submodule(name)
5111 module_scope.declare_module(name, submodule_scope, self.pos)
5112 module_scope = submodule_scope
5114 env.declare_module(self.as_name, module_scope, self.pos)
5116 env.declare_module(top_name, top_module_scope, self.pos)
5118 name = self.as_name or self.module_name
5119 env.declare_module(name, module_scope, self.pos)
5121 def analyse_expressions(self, env):
5124 def generate_execution_code(self, code):
5128 class FromCImportStatNode(StatNode):
5129 # from ... cimport statement
5131 # module_name string Qualified name of module
5132 # imported_names [(pos, name, as_name, kind)] Names to be imported
5136 def analyse_declarations(self, env):
5137 if not env.is_module_scope:
5138 error(self.pos, "cimport only allowed at module level")
5140 module_scope = env.find_module(self.module_name, self.pos)
5141 env.add_imported_module(module_scope)
5142 for pos, name, as_name, kind in self.imported_names:
5144 for local_name, entry in module_scope.entries.items():
5145 env.add_imported_entry(local_name, entry, pos)
5147 entry = module_scope.lookup(name)
5149 if kind and not self.declaration_matches(entry, kind):
5150 entry.redeclared(pos)
5152 if kind == 'struct' or kind == 'union':
5153 entry = module_scope.declare_struct_or_union(name,
5154 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5155 elif kind == 'class':
5156 entry = module_scope.declare_c_class(name, pos = pos,
5157 module_name = self.module_name)
5159 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5160 if submodule_scope.parent_module is module_scope:
5161 env.declare_module(as_name or name, submodule_scope, self.pos)
5163 error(pos, "Name '%s' not declared in module '%s'"
5164 % (name, self.module_name))
5167 local_name = as_name or name
5168 env.add_imported_entry(local_name, entry, pos)
5170 def declaration_matches(self, entry, kind):
5171 if not entry.is_type:
5175 if not type.is_extension_type:
5178 if not type.is_struct_or_union:
5180 if kind != type.kind:
5184 def analyse_expressions(self, env):
5187 def generate_execution_code(self, code):
5191 class FromImportStatNode(StatNode):
5192 # from ... import statement
5195 # items [(string, NameNode)]
5196 # interned_items [(string, NameNode, ExprNode)]
5197 # item PyTempNode used internally
5198 # import_star boolean used internally
5200 child_attrs = ["module"]
5203 def analyse_declarations(self, env):
5204 for name, target in self.items:
5206 if not env.is_module_scope:
5207 error(self.pos, "import * only allowed at module level")
5209 env.has_import_star = 1
5210 self.import_star = 1
5212 target.analyse_target_declaration(env)
5214 def analyse_expressions(self, env):
5216 self.module.analyse_expressions(env)
5217 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5218 self.interned_items = []
5219 for name, target in self.items:
5221 for _, entry in env.entries.items():
5222 if not entry.is_type and entry.type.is_extension_type:
5223 env.use_utility_code(ExprNodes.type_test_utility_code)
5226 entry = env.lookup(target.name)
5227 # check whether or not entry is already cimported
5228 if (entry.is_type and entry.type.name == name
5229 and hasattr(entry.type, 'module_name')):
5230 if entry.type.module_name == self.module.module_name.value:
5231 # cimported with absolute name
5234 # cimported with relative name
5235 module = env.find_module(self.module.module_name.value,
5237 if entry.type.module_name == module.qualified_name:
5239 except AttributeError:
5241 target.analyse_target_expression(env, None)
5242 if target.type is py_object_type:
5245 coerced_item = self.item.coerce_to(target.type, env)
5246 self.interned_items.append((name, target, coerced_item))
5248 def generate_execution_code(self, code):
5249 self.module.generate_evaluation_code(code)
5250 if self.import_star:
5252 'if (%s(%s) < 0) %s;' % (
5254 self.module.py_result(),
5255 code.error_goto(self.pos)))
5256 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5257 self.item.set_cname(item_temp)
5258 for name, target, coerced_item in self.interned_items:
5259 cname = code.intern_identifier(name)
5261 '%s = PyObject_GetAttr(%s, %s); %s' % (
5263 self.module.py_result(),
5265 code.error_goto_if_null(item_temp, self.pos)))
5266 code.put_gotref(item_temp)
5267 if coerced_item is None:
5268 target.generate_assignment_code(self.item, code)
5270 coerced_item.allocate_temp_result(code)
5271 coerced_item.generate_result_code(code)
5272 target.generate_assignment_code(coerced_item, code)
5273 code.put_decref_clear(item_temp, py_object_type)
5274 code.funcstate.release_temp(item_temp)
5275 self.module.generate_disposal_code(code)
5276 self.module.free_temps(code)
5280 #------------------------------------------------------------------------------------
5282 # Runtime support code
5284 #------------------------------------------------------------------------------------
5286 utility_function_predeclarations = \
5288 /* inline attribute */
5289 #ifndef CYTHON_INLINE
5290 #if defined(__GNUC__)
5291 #define CYTHON_INLINE __inline__
5292 #elif defined(_MSC_VER)
5293 #define CYTHON_INLINE __inline
5294 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5295 #define CYTHON_INLINE inline
5297 #define CYTHON_INLINE
5301 /* unused attribute */
5302 #ifndef CYTHON_UNUSED
5303 # if defined(__GNUC__)
5304 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5305 # define CYTHON_UNUSED __attribute__ ((__unused__))
5307 # define CYTHON_UNUSED
5309 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5310 # define CYTHON_UNUSED __attribute__ ((__unused__))
5312 # define CYTHON_UNUSED
5316 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*/
5320 if Options.gcc_branch_hints:
5321 branch_prediction_macros = \
5324 /* Test for GCC > 2.95 */
5325 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5326 #define likely(x) __builtin_expect(!!(x), 1)
5327 #define unlikely(x) __builtin_expect(!!(x), 0)
5328 #else /* __GNUC__ > 2 ... */
5329 #define likely(x) (x)
5330 #define unlikely(x) (x)
5331 #endif /* __GNUC__ > 2 ... */
5332 #else /* __GNUC__ */
5333 #define likely(x) (x)
5334 #define unlikely(x) (x)
5335 #endif /* __GNUC__ */
5338 branch_prediction_macros = \
5340 #define likely(x) (x)
5341 #define unlikely(x) (x)
5344 #get_name_predeclaration = \
5345 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5347 #get_name_interned_predeclaration = \
5348 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5350 #------------------------------------------------------------------------------------
5352 printing_utility_code = UtilityCode(
5354 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5355 #if PY_MAJOR_VERSION >= 3
5356 static PyObject* %s = 0;
5357 static PyObject* %s = 0;
5359 """ % (Naming.print_function, Naming.print_function_kwargs),
5361 #if PY_MAJOR_VERSION >= 3
5365 """ % (Naming.print_function, Naming.print_function_kwargs),
5367 #if PY_MAJOR_VERSION < 3
5368 static PyObject *__Pyx_GetStdout(void) {
5369 PyObject *f = PySys_GetObject((char *)"stdout");
5371 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5376 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5381 if (!(f = __Pyx_GetStdout()))
5384 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5385 if (PyFile_SoftSpace(f, 1)) {
5386 if (PyFile_WriteString(" ", f) < 0)
5389 v = PyTuple_GET_ITEM(arg_tuple, i);
5390 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5392 if (PyString_Check(v)) {
5393 char *s = PyString_AsString(v);
5394 Py_ssize_t len = PyString_Size(v);
5396 isspace(Py_CHARMASK(s[len-1])) &&
5398 PyFile_SoftSpace(f, 0);
5402 if (PyFile_WriteString("\n", f) < 0)
5404 PyFile_SoftSpace(f, 0);
5409 #else /* Python 3 has a print function */
5411 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5412 PyObject* kwargs = 0;
5413 PyObject* result = 0;
5414 PyObject* end_string;
5415 if (unlikely(!%(PRINT_FUNCTION)s)) {
5416 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5417 if (!%(PRINT_FUNCTION)s)
5421 kwargs = PyDict_New();
5422 if (unlikely(!kwargs))
5424 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5427 end_string = PyUnicode_FromStringAndSize(" ", 1);
5428 if (unlikely(!end_string))
5430 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5431 Py_DECREF(end_string);
5434 Py_DECREF(end_string);
5436 } else if (!newline) {
5437 if (unlikely(!%(PRINT_KWARGS)s)) {
5438 %(PRINT_KWARGS)s = PyDict_New();
5439 if (unlikely(!%(PRINT_KWARGS)s))
5441 end_string = PyUnicode_FromStringAndSize(" ", 1);
5442 if (unlikely(!end_string))
5444 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5445 Py_DECREF(end_string);
5448 Py_DECREF(end_string);
5450 kwargs = %(PRINT_KWARGS)s;
5452 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5453 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5460 if (kwargs != %(PRINT_KWARGS)s)
5466 """ % {'BUILTINS' : Naming.builtins_cname,
5467 'PRINT_FUNCTION' : Naming.print_function,
5468 'PRINT_KWARGS' : Naming.print_function_kwargs}
5472 printing_one_utility_code = UtilityCode(
5474 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5477 #if PY_MAJOR_VERSION < 3
5479 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5481 if (!(f = __Pyx_GetStdout()))
5484 if (PyFile_SoftSpace(f, 0)) {
5485 if (PyFile_WriteString(" ", f) < 0)
5488 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5490 if (PyFile_WriteString("\n", f) < 0)
5493 /* the line below is just to avoid compiler
5494 * compiler warnings about unused functions */
5495 return __Pyx_Print(f, NULL, 0);
5498 #else /* Python 3 has a print function */
5500 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5502 PyObject* arg_tuple = PyTuple_New(1);
5503 if (unlikely(!arg_tuple))
5506 PyTuple_SET_ITEM(arg_tuple, 0, o);
5507 res = __Pyx_Print(stream, arg_tuple, 1);
5508 Py_DECREF(arg_tuple);
5514 requires=[printing_utility_code])
5518 #------------------------------------------------------------------------------------
5520 # Exception raising code
5522 # Exceptions are raised by __Pyx_Raise() and stored as plain
5523 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5524 # 'except' statement, curexc_* is moved over to exc_* by
5525 # __Pyx_GetException()
5527 restore_exception_utility_code = UtilityCode(
5529 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5530 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5533 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5534 PyObject *tmp_type, *tmp_value, *tmp_tb;
5535 PyThreadState *tstate = PyThreadState_GET();
5537 tmp_type = tstate->curexc_type;
5538 tmp_value = tstate->curexc_value;
5539 tmp_tb = tstate->curexc_traceback;
5540 tstate->curexc_type = type;
5541 tstate->curexc_value = value;
5542 tstate->curexc_traceback = tb;
5543 Py_XDECREF(tmp_type);
5544 Py_XDECREF(tmp_value);
5548 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5549 PyThreadState *tstate = PyThreadState_GET();
5550 *type = tstate->curexc_type;
5551 *value = tstate->curexc_value;
5552 *tb = tstate->curexc_traceback;
5554 tstate->curexc_type = 0;
5555 tstate->curexc_value = 0;
5556 tstate->curexc_traceback = 0;
5561 # The following function is based on do_raise() from ceval.c. There
5562 # are separate versions for Python2 and Python3 as exception handling
5563 # has changed quite a lot between the two versions.
5565 raise_utility_code = UtilityCode(
5567 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5570 #if PY_MAJOR_VERSION < 3
5571 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5575 /* First, check the traceback argument, replacing None with NULL. */
5576 if (tb == Py_None) {
5580 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5581 PyErr_SetString(PyExc_TypeError,
5582 "raise: arg 3 must be a traceback or None");
5585 /* Next, replace a missing value with None */
5586 if (value == NULL) {
5590 #if PY_VERSION_HEX < 0x02050000
5591 if (!PyClass_Check(type))
5593 if (!PyType_Check(type))
5596 /* Raising an instance. The value should be a dummy. */
5597 if (value != Py_None) {
5598 PyErr_SetString(PyExc_TypeError,
5599 "instance exception may not have a separate value");
5602 /* Normalize to raise <class>, <instance> */
5605 #if PY_VERSION_HEX < 0x02050000
5606 if (PyInstance_Check(type)) {
5607 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5612 PyErr_SetString(PyExc_TypeError,
5613 "raise: exception must be an old-style class or instance");
5617 type = (PyObject*) Py_TYPE(type);
5619 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5620 PyErr_SetString(PyExc_TypeError,
5621 "raise: exception class must be a subclass of BaseException");
5627 __Pyx_ErrRestore(type, value, tb);
5636 #else /* Python 3+ */
5638 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5639 if (tb == Py_None) {
5641 } else if (tb && !PyTraceBack_Check(tb)) {
5642 PyErr_SetString(PyExc_TypeError,
5643 "raise: arg 3 must be a traceback or None");
5646 if (value == Py_None)
5649 if (PyExceptionInstance_Check(type)) {
5651 PyErr_SetString(PyExc_TypeError,
5652 "instance exception may not have a separate value");
5656 type = (PyObject*) Py_TYPE(value);
5657 } else if (!PyExceptionClass_Check(type)) {
5658 PyErr_SetString(PyExc_TypeError,
5659 "raise: exception class must be a subclass of BaseException");
5663 PyErr_SetObject(type, value);
5666 PyThreadState *tstate = PyThreadState_GET();
5667 PyObject* tmp_tb = tstate->curexc_traceback;
5670 tstate->curexc_traceback = tb;
5680 requires=[restore_exception_utility_code])
5682 #------------------------------------------------------------------------------------
5684 get_exception_utility_code = UtilityCode(
5686 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5689 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5690 PyObject *local_type, *local_value, *local_tb;
5691 PyObject *tmp_type, *tmp_value, *tmp_tb;
5692 PyThreadState *tstate = PyThreadState_GET();
5693 local_type = tstate->curexc_type;
5694 local_value = tstate->curexc_value;
5695 local_tb = tstate->curexc_traceback;
5696 tstate->curexc_type = 0;
5697 tstate->curexc_value = 0;
5698 tstate->curexc_traceback = 0;
5699 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5700 if (unlikely(tstate->curexc_type))
5702 #if PY_MAJOR_VERSION >= 3
5703 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5707 *value = local_value;
5709 Py_INCREF(local_type);
5710 Py_INCREF(local_value);
5711 Py_INCREF(local_tb);
5712 tmp_type = tstate->exc_type;
5713 tmp_value = tstate->exc_value;
5714 tmp_tb = tstate->exc_traceback;
5715 tstate->exc_type = local_type;
5716 tstate->exc_value = local_value;
5717 tstate->exc_traceback = local_tb;
5718 /* Make sure tstate is in a consistent state when we XDECREF
5719 these objects (XDECREF may run arbitrary code). */
5720 Py_XDECREF(tmp_type);
5721 Py_XDECREF(tmp_value);
5728 Py_XDECREF(local_type);
5729 Py_XDECREF(local_value);
5730 Py_XDECREF(local_tb);
5736 #------------------------------------------------------------------------------------
5738 get_exception_tuple_utility_code = UtilityCode(proto="""
5739 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5741 # I doubt that calling __Pyx_GetException() here is correct as it moves
5742 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5743 # exception handlers later on from receiving it.
5745 static PyObject *__Pyx_GetExceptionTuple(void) {
5746 PyObject *type = NULL, *value = NULL, *tb = NULL;
5747 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5748 PyObject* exc_info = PyTuple_New(3);
5753 PyTuple_SET_ITEM(exc_info, 0, type);
5754 PyTuple_SET_ITEM(exc_info, 1, value);
5755 PyTuple_SET_ITEM(exc_info, 2, tb);
5762 requires=[get_exception_utility_code])
5764 #------------------------------------------------------------------------------------
5766 reset_exception_utility_code = UtilityCode(
5768 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5769 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5772 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5773 PyThreadState *tstate = PyThreadState_GET();
5774 *type = tstate->exc_type;
5775 *value = tstate->exc_value;
5776 *tb = tstate->exc_traceback;
5782 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5783 PyObject *tmp_type, *tmp_value, *tmp_tb;
5784 PyThreadState *tstate = PyThreadState_GET();
5785 tmp_type = tstate->exc_type;
5786 tmp_value = tstate->exc_value;
5787 tmp_tb = tstate->exc_traceback;
5788 tstate->exc_type = type;
5789 tstate->exc_value = value;
5790 tstate->exc_traceback = tb;
5791 Py_XDECREF(tmp_type);
5792 Py_XDECREF(tmp_value);
5797 #------------------------------------------------------------------------------------
5799 arg_type_test_utility_code = UtilityCode(
5801 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5802 const char *name, int exact); /*proto*/
5805 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5806 const char *name, int exact)
5809 PyErr_Format(PyExc_SystemError, "Missing type object");
5812 if (none_allowed && obj == Py_None) return 1;
5814 if (Py_TYPE(obj) == type) return 1;
5817 if (PyObject_TypeCheck(obj, type)) return 1;
5819 PyErr_Format(PyExc_TypeError,
5820 "Argument '%s' has incorrect type (expected %s, got %s)",
5821 name, type->tp_name, Py_TYPE(obj)->tp_name);
5826 #------------------------------------------------------------------------------------
5828 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5829 # many or too few positional arguments were found. This handles
5830 # Py_ssize_t formatting correctly.
5832 raise_argtuple_invalid_utility_code = UtilityCode(
5834 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5835 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5838 static void __Pyx_RaiseArgtupleInvalid(
5839 const char* func_name,
5843 Py_ssize_t num_found)
5845 Py_ssize_t num_expected;
5846 const char *number, *more_or_less;
5848 if (num_found < num_min) {
5849 num_expected = num_min;
5850 more_or_less = "at least";
5852 num_expected = num_max;
5853 more_or_less = "at most";
5856 more_or_less = "exactly";
5858 number = (num_expected == 1) ? "" : "s";
5859 PyErr_Format(PyExc_TypeError,
5860 #if PY_VERSION_HEX < 0x02050000
5861 "%s() takes %s %d positional argument%s (%d given)",
5863 "%s() takes %s %zd positional argument%s (%zd given)",
5865 func_name, more_or_less, num_expected, number, num_found);
5869 raise_keyword_required_utility_code = UtilityCode(
5871 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5874 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5875 const char* func_name,
5878 PyErr_Format(PyExc_TypeError,
5879 #if PY_MAJOR_VERSION >= 3
5880 "%s() needs keyword-only argument %U", func_name, kw_name);
5882 "%s() needs keyword-only argument %s", func_name,
5883 PyString_AS_STRING(kw_name));
5888 raise_double_keywords_utility_code = UtilityCode(
5890 static void __Pyx_RaiseDoubleKeywordsError(
5891 const char* func_name, PyObject* kw_name); /*proto*/
5894 static void __Pyx_RaiseDoubleKeywordsError(
5895 const char* func_name,
5898 PyErr_Format(PyExc_TypeError,
5899 #if PY_MAJOR_VERSION >= 3
5900 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5902 "%s() got multiple values for keyword argument '%s'", func_name,
5903 PyString_AS_STRING(kw_name));
5908 #------------------------------------------------------------------------------------
5910 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5911 # were passed to a function, or if any keywords were passed to a
5912 # function that does not accept them.
5914 keyword_string_check_utility_code = UtilityCode(
5916 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5917 const char* function_name, int kw_allowed); /*proto*/
5920 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5922 const char* function_name,
5927 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5928 #if PY_MAJOR_VERSION < 3
5929 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5931 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5933 goto invalid_keyword_type;
5935 if ((!kw_allowed) && unlikely(key))
5936 goto invalid_keyword;
5938 invalid_keyword_type:
5939 PyErr_Format(PyExc_TypeError,
5940 "%s() keywords must be strings", function_name);
5943 PyErr_Format(PyExc_TypeError,
5944 #if PY_MAJOR_VERSION < 3
5945 "%s() got an unexpected keyword argument '%s'",
5946 function_name, PyString_AsString(key));
5948 "%s() got an unexpected keyword argument '%U'",
5949 function_name, key);
5955 #------------------------------------------------------------------------------------
5957 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5958 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5959 # keywords will raise an invalid keyword error.
5961 # Three kinds of errors are checked: 1) non-string keywords, 2)
5962 # unexpected keywords and 3) overlap with positional arguments.
5964 # If num_posargs is greater 0, it denotes the number of positional
5965 # arguments that were passed and that must therefore not appear
5966 # amongst the keywords as well.
5968 # This method does not check for required keyword arguments.
5971 parse_keywords_utility_code = UtilityCode(
5973 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5974 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5975 const char* function_name); /*proto*/
5978 static int __Pyx_ParseOptionalKeywords(
5980 PyObject **argnames[],
5983 Py_ssize_t num_pos_args,
5984 const char* function_name)
5986 PyObject *key = 0, *value = 0;
5989 PyObject*** first_kw_arg = argnames + num_pos_args;
5991 while (PyDict_Next(kwds, &pos, &key, &value)) {
5992 name = first_kw_arg;
5993 while (*name && (**name != key)) name++;
5995 values[name-argnames] = value;
5997 #if PY_MAJOR_VERSION < 3
5998 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6000 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6002 goto invalid_keyword_type;
6004 for (name = first_kw_arg; *name; name++) {
6005 #if PY_MAJOR_VERSION >= 3
6006 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6007 PyUnicode_Compare(**name, key) == 0) break;
6009 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6010 _PyString_Eq(**name, key)) break;
6014 values[name-argnames] = value;
6016 /* unexpected keyword found */
6017 for (name=argnames; name != first_kw_arg; name++) {
6018 if (**name == key) goto arg_passed_twice;
6019 #if PY_MAJOR_VERSION >= 3
6020 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6021 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6023 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6024 _PyString_Eq(**name, key)) goto arg_passed_twice;
6028 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6030 goto invalid_keyword;
6038 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6040 invalid_keyword_type:
6041 PyErr_Format(PyExc_TypeError,
6042 "%s() keywords must be strings", function_name);
6045 PyErr_Format(PyExc_TypeError,
6046 #if PY_MAJOR_VERSION < 3
6047 "%s() got an unexpected keyword argument '%s'",
6048 function_name, PyString_AsString(key));
6050 "%s() got an unexpected keyword argument '%U'",
6051 function_name, key);
6058 #------------------------------------------------------------------------------------
6060 traceback_utility_code = UtilityCode(
6062 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6065 #include "compile.h"
6066 #include "frameobject.h"
6067 #include "traceback.h"
6069 static void __Pyx_AddTraceback(const char *funcname) {
6070 PyObject *py_srcfile = 0;
6071 PyObject *py_funcname = 0;
6072 PyObject *py_globals = 0;
6073 PyCodeObject *py_code = 0;
6074 PyFrameObject *py_frame = 0;
6076 #if PY_MAJOR_VERSION < 3
6077 py_srcfile = PyString_FromString(%(FILENAME)s);
6079 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6081 if (!py_srcfile) goto bad;
6083 #if PY_MAJOR_VERSION < 3
6084 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6086 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6090 #if PY_MAJOR_VERSION < 3
6091 py_funcname = PyString_FromString(funcname);
6093 py_funcname = PyUnicode_FromString(funcname);
6096 if (!py_funcname) goto bad;
6097 py_globals = PyModule_GetDict(%(GLOBALS)s);
6098 if (!py_globals) goto bad;
6099 py_code = PyCode_New(
6100 0, /*int argcount,*/
6101 #if PY_MAJOR_VERSION >= 3
6102 0, /*int kwonlyargcount,*/
6105 0, /*int stacksize,*/
6107 %(EMPTY_BYTES)s, /*PyObject *code,*/
6108 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6109 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6110 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6111 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6112 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6113 py_srcfile, /*PyObject *filename,*/
6114 py_funcname, /*PyObject *name,*/
6115 %(LINENO)s, /*int firstlineno,*/
6116 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6118 if (!py_code) goto bad;
6119 py_frame = PyFrame_New(
6120 PyThreadState_GET(), /*PyThreadState *tstate,*/
6121 py_code, /*PyCodeObject *code,*/
6122 py_globals, /*PyObject *globals,*/
6123 0 /*PyObject *locals*/
6125 if (!py_frame) goto bad;
6126 py_frame->f_lineno = %(LINENO)s;
6127 PyTraceBack_Here(py_frame);
6129 Py_XDECREF(py_srcfile);
6130 Py_XDECREF(py_funcname);
6131 Py_XDECREF(py_code);
6132 Py_XDECREF(py_frame);
6135 'FILENAME': Naming.filename_cname,
6136 'LINENO': Naming.lineno_cname,
6137 'CFILENAME': Naming.cfilenm_cname,
6138 'CLINENO': Naming.clineno_cname,
6139 'GLOBALS': Naming.module_cname,
6140 'EMPTY_TUPLE' : Naming.empty_tuple,
6141 'EMPTY_BYTES' : Naming.empty_bytes,
6144 #------------------------------------------------------------------------------------
6146 unraisable_exception_utility_code = UtilityCode(
6148 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6151 static void __Pyx_WriteUnraisable(const char *name) {
6152 PyObject *old_exc, *old_val, *old_tb;
6154 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6155 #if PY_MAJOR_VERSION < 3
6156 ctx = PyString_FromString(name);
6158 ctx = PyUnicode_FromString(name);
6160 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6162 PyErr_WriteUnraisable(Py_None);
6164 PyErr_WriteUnraisable(ctx);
6169 requires=[restore_exception_utility_code])
6171 #------------------------------------------------------------------------------------
6173 set_vtable_utility_code = UtilityCode(
6175 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6178 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6179 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6180 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6182 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6186 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6196 #------------------------------------------------------------------------------------
6198 get_vtable_utility_code = UtilityCode(
6200 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6203 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6204 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6207 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6208 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6210 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6212 if (!*(void **)vtabptr)
6222 #------------------------------------------------------------------------------------
6224 init_string_tab_utility_code = UtilityCode(
6226 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6229 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6231 #if PY_MAJOR_VERSION < 3
6232 if (t->is_unicode) {
6233 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6234 } else if (t->intern) {
6235 *t->p = PyString_InternFromString(t->s);
6237 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6239 #else /* Python 3+ has unicode identifiers */
6240 if (t->is_unicode | t->is_str) {
6242 *t->p = PyUnicode_InternFromString(t->s);
6243 } else if (t->encoding) {
6244 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6246 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6249 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6260 #------------------------------------------------------------------------------------
6262 force_init_threads_utility_code = UtilityCode(
6264 #ifndef __PYX_FORCE_INIT_THREADS
6265 #if PY_VERSION_HEX < 0x02040200
6266 #define __PYX_FORCE_INIT_THREADS 1
6268 #define __PYX_FORCE_INIT_THREADS 0
6273 #------------------------------------------------------------------------------------
6275 # Note that cPython ignores PyTrace_EXCEPTION,
6276 # but maybe some other profilers don't.
6278 profile_utility_code = UtilityCode(proto="""
6279 #ifndef CYTHON_PROFILE
6280 #define CYTHON_PROFILE 1
6283 #ifndef CYTHON_PROFILE_REUSE_FRAME
6284 #define CYTHON_PROFILE_REUSE_FRAME 0
6289 #include "compile.h"
6290 #include "frameobject.h"
6291 #include "traceback.h"
6293 #if CYTHON_PROFILE_REUSE_FRAME
6294 #define CYTHON_FRAME_MODIFIER static
6295 #define CYTHON_FRAME_DEL
6297 #define CYTHON_FRAME_MODIFIER
6298 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6301 #define __Pyx_TraceDeclarations \\
6302 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6303 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6304 int __Pyx_use_tracing = 0;
6306 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6307 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6308 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6311 #define __Pyx_TraceException() \\
6312 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6313 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6315 PyThreadState_GET()->c_profilefunc( \\
6316 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6317 Py_DECREF(exc_info); \\
6321 #define __Pyx_TraceReturn(result) \\
6322 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6323 PyThreadState_GET()->c_profilefunc( \\
6324 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6325 CYTHON_FRAME_DEL; \\
6328 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6329 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6333 #define __Pyx_TraceDeclarations
6334 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6335 #define __Pyx_TraceException()
6336 #define __Pyx_TraceReturn(result)
6338 #endif /* CYTHON_PROFILE */
6341 "FRAME": Naming.frame_cname,
6342 "FRAME_CODE": Naming.frame_code_cname,
6348 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6349 PyFrameObject** frame,
6350 const char *funcname,
6351 const char *srcfile,
6353 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6354 if (*code == NULL) {
6355 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6356 if (*code == NULL) return 0;
6358 *frame = PyFrame_New(
6359 PyThreadState_GET(), /*PyThreadState *tstate*/
6360 *code, /*PyCodeObject *code*/
6361 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6362 0 /*PyObject *locals*/
6364 if (*frame == NULL) return 0;
6367 (*frame)->f_tstate = PyThreadState_GET();
6369 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6372 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6373 PyObject *py_srcfile = 0;
6374 PyObject *py_funcname = 0;
6375 PyCodeObject *py_code = 0;
6377 #if PY_MAJOR_VERSION < 3
6378 py_funcname = PyString_FromString(funcname);
6379 py_srcfile = PyString_FromString(srcfile);
6381 py_funcname = PyUnicode_FromString(funcname);
6382 py_srcfile = PyUnicode_FromString(srcfile);
6384 if (!py_funcname | !py_srcfile) goto bad;
6386 py_code = PyCode_New(
6387 0, /*int argcount,*/
6388 #if PY_MAJOR_VERSION >= 3
6389 0, /*int kwonlyargcount,*/
6392 0, /*int stacksize,*/
6394 %(EMPTY_BYTES)s, /*PyObject *code,*/
6395 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6396 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6397 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6398 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6399 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6400 py_srcfile, /*PyObject *filename,*/
6401 py_funcname, /*PyObject *name,*/
6402 firstlineno, /*int firstlineno,*/
6403 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6407 Py_XDECREF(py_srcfile);
6408 Py_XDECREF(py_funcname);
6413 #endif /* CYTHON_PROFILE */
6415 'EMPTY_TUPLE' : Naming.empty_tuple,
6416 'EMPTY_BYTES' : Naming.empty_bytes,
6417 "MODULE": Naming.module_cname,