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
2116 def declare_lambda_function(self, env):
2118 prefix = env.scope_prefix
2120 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2121 entry = env.declare_lambda_function(func_cname, self.pos)
2122 entry.pymethdef_cname = \
2123 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2124 entry.qualified_name = env.qualify_name(self.lambda_name)
2128 def declare_arguments(self, env):
2129 for arg in self.args:
2131 error(arg.pos, "Missing argument name")
2133 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2134 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2135 if arg.needs_conversion:
2136 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2137 if arg.type.is_pyobject:
2138 arg.entry.init = "0"
2139 arg.entry.init_to_none = 0
2141 arg.entry = self.declare_argument(env, arg)
2143 arg.entry.is_self_arg = arg.is_self_arg
2145 if arg.is_self_arg or arg.is_type_arg or \
2146 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2147 arg.entry.is_declared_generic = 1
2148 self.declare_python_arg(env, self.star_arg)
2149 self.declare_python_arg(env, self.starstar_arg)
2151 def declare_python_arg(self, env, arg):
2153 if env.directives['infer_types'] != False:
2154 type = PyrexTypes.unspecified_type
2156 type = py_object_type
2157 entry = env.declare_var(arg.name, type, arg.pos)
2160 entry.init_to_none = 0
2161 entry.xdecref_cleanup = 1
2163 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2165 def analyse_expressions(self, env):
2166 self.local_scope.directives = env.directives
2167 self.analyse_default_values(env)
2168 if self.needs_assignment_synthesis(env):
2169 # Shouldn't we be doing this at the module level too?
2170 self.synthesize_assignment_node(env)
2172 def needs_assignment_synthesis(self, env, code=None):
2173 # Should enable for module level as well, that will require more testing...
2174 if env.is_module_scope:
2176 return env.directives['binding']
2178 return code.globalstate.directives['binding']
2179 return env.is_py_class_scope or env.is_closure_scope
2181 def synthesize_assignment_node(self, env):
2183 if env.is_py_class_scope:
2184 rhs = ExprNodes.UnboundMethodNode(self.pos,
2185 function = ExprNodes.PyCFunctionNode(self.pos,
2186 pymethdef_cname = self.entry.pymethdef_cname))
2187 elif env.is_closure_scope:
2188 rhs = ExprNodes.InnerFunctionNode(
2189 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2191 rhs = ExprNodes.PyCFunctionNode(
2192 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2193 self.assmt = SingleAssignmentNode(self.pos,
2194 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2196 self.assmt.analyse_declarations(env)
2197 self.assmt.analyse_expressions(env)
2199 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2201 sig = self.entry.signature
2202 if sig.has_dummy_arg or self.self_in_stararg:
2203 arg_code_list.append(
2204 "PyObject *%s" % Naming.self_cname)
2205 for arg in self.args:
2206 if not arg.is_generic:
2207 if arg.is_self_arg or arg.is_type_arg:
2208 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2210 arg_code_list.append(
2211 arg.hdr_type.declaration_code(arg.hdr_cname))
2212 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2213 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2214 if sig.has_generic_args:
2215 arg_code_list.append(
2216 "PyObject *%s, PyObject *%s"
2217 % (Naming.args_cname, Naming.kwds_cname))
2218 arg_code = ", ".join(arg_code_list)
2219 dc = self.return_type.declaration_code(self.entry.func_cname)
2220 mf = " ".join(self.modifiers).upper()
2222 header = "static %s%s(%s)" % (mf, dc, arg_code)
2223 code.putln("%s; /*proto*/" % header)
2226 if (Options.docstrings and self.entry.doc and
2227 (not self.entry.is_special or
2228 self.entry.signature.method_flags()) and
2229 not self.entry.scope.is_property_scope
2231 docstr = self.entry.doc
2232 if docstr.is_unicode:
2233 docstr = docstr.utf8encode()
2235 'static char %s[] = "%s";' % (
2236 self.entry.doc_cname,
2237 split_string_literal(escape_byte_string(docstr))))
2240 "static PyMethodDef %s = " %
2241 self.entry.pymethdef_cname)
2242 code.put_pymethoddef(self.entry, ";")
2243 code.putln("%s {" % header)
2245 def generate_argument_declarations(self, env, code):
2246 for arg in self.args:
2247 if arg.is_generic: # or arg.needs_conversion:
2248 if arg.needs_conversion:
2249 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2250 elif not arg.entry.in_closure:
2251 code.put_var_declaration(arg.entry)
2253 def generate_keyword_list(self, code):
2254 if self.signature_has_generic_args() and \
2255 self.signature_has_nongeneric_args():
2257 "static PyObject **%s[] = {" %
2258 Naming.pykwdlist_cname)
2259 for arg in self.args:
2261 pystring_cname = code.intern_identifier(arg.name)
2262 code.put('&%s,' % pystring_cname)
2265 def generate_argument_parsing_code(self, env, code):
2266 # Generate PyArg_ParseTuple call for generic
2267 # arguments, if any.
2268 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2269 # get rid of unused argument warning
2270 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2272 old_error_label = code.new_error_label()
2273 our_error_label = code.error_label
2274 end_label = code.new_label("argument_unpacking_done")
2276 has_kwonly_args = self.num_kwonly_args > 0
2277 has_star_or_kw_args = self.star_arg is not None \
2278 or self.starstar_arg is not None or has_kwonly_args
2280 for arg in self.args:
2281 if not arg.type.is_pyobject:
2282 done = arg.type.create_from_py_utility_code(env)
2283 if not done: pass # will fail later
2285 if not self.signature_has_generic_args():
2286 if has_star_or_kw_args:
2287 error(self.pos, "This method cannot have * or keyword arguments")
2288 self.generate_argument_conversion_code(code)
2290 elif not self.signature_has_nongeneric_args():
2291 # func(*args) or func(**kw) or func(*args, **kw)
2292 self.generate_stararg_copy_code(code)
2295 positional_args = []
2297 for arg in self.args:
2298 arg_entry = arg.entry
2301 if not arg.is_self_arg and not arg.is_type_arg:
2303 kw_only_args.append(arg)
2305 positional_args.append(arg)
2307 kw_only_args.append(arg)
2308 elif not arg.is_self_arg and not arg.is_type_arg:
2309 positional_args.append(arg)
2311 self.generate_tuple_and_keyword_parsing_code(
2312 positional_args, kw_only_args, end_label, code)
2314 code.error_label = old_error_label
2315 if code.label_used(our_error_label):
2316 if not code.label_used(end_label):
2317 code.put_goto(end_label)
2318 code.put_label(our_error_label)
2319 if has_star_or_kw_args:
2320 self.generate_arg_decref(self.star_arg, code)
2321 if self.starstar_arg:
2322 if self.starstar_arg.entry.xdecref_cleanup:
2323 code.put_var_xdecref(self.starstar_arg.entry)
2325 code.put_var_decref(self.starstar_arg.entry)
2326 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2327 # The arguments are put into the closure one after the
2328 # other, so when type errors are found, all references in
2329 # the closure instance must be properly ref-counted to
2330 # facilitate generic closure instance deallocation. In
2331 # the case of an argument type error, it's best to just
2332 # DECREF+clear the already handled references, as this
2333 # frees their references as early as possible.
2334 for arg in self.args:
2335 if arg.type.is_pyobject and arg.entry.in_closure:
2336 code.put_var_xdecref_clear(arg.entry)
2337 if self.needs_closure:
2338 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2339 code.put_finish_refcount_context()
2340 code.putln("return %s;" % self.error_value())
2341 if code.label_used(end_label):
2342 code.put_label(end_label)
2344 def generate_arg_assignment(self, arg, item, code):
2345 if arg.type.is_pyobject:
2347 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2349 code.putln("%s = %s;" % (entry.cname, item))
2350 if entry.in_closure:
2351 code.put_var_incref(entry)
2353 func = arg.type.from_py_function
2355 code.putln("%s = %s(%s); %s" % (
2359 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2361 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2363 def generate_arg_xdecref(self, arg, code):
2365 code.put_var_xdecref(arg.entry)
2367 def generate_arg_decref(self, arg, code):
2369 code.put_var_decref(arg.entry)
2371 def generate_stararg_copy_code(self, code):
2372 if not self.star_arg:
2373 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2374 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2376 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2377 self.name, Naming.args_cname, self.error_value()))
2380 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2382 if self.starstar_arg:
2384 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2386 kwarg_check = "%s" % Naming.kwds_cname
2388 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2389 Naming.kwds_cname, Naming.kwds_cname)
2391 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2392 kwarg_check, Naming.kwds_cname, self.name,
2393 bool(self.starstar_arg), self.error_value()))
2395 if self.starstar_arg:
2396 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2397 self.starstar_arg.entry.cname,
2400 code.putln("if (unlikely(!%s)) return %s;" % (
2401 self.starstar_arg.entry.cname, self.error_value()))
2402 self.starstar_arg.entry.xdecref_cleanup = 0
2403 code.put_gotref(self.starstar_arg.entry.cname)
2405 if self.self_in_stararg:
2406 # need to create a new tuple with 'self' inserted as first item
2407 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2408 self.star_arg.entry.cname,
2410 self.star_arg.entry.cname))
2411 if self.starstar_arg:
2413 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2414 code.putln("return %s;" % self.error_value())
2417 code.putln("return %s;" % self.error_value())
2418 code.put_gotref(self.star_arg.entry.cname)
2419 code.put_incref(Naming.self_cname, py_object_type)
2420 code.put_giveref(Naming.self_cname)
2421 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2422 self.star_arg.entry.cname, Naming.self_cname))
2423 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2424 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2425 temp, temp, Naming.args_cname, temp))
2426 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2427 Naming.args_cname, temp))
2428 code.put_incref("item", py_object_type)
2429 code.put_giveref("item")
2430 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2431 self.star_arg.entry.cname, temp))
2433 code.funcstate.release_temp(temp)
2434 self.star_arg.entry.xdecref_cleanup = 0
2436 code.put_incref(Naming.args_cname, py_object_type)
2437 code.putln("%s = %s;" % (
2438 self.star_arg.entry.cname,
2440 self.star_arg.entry.xdecref_cleanup = 0
2442 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2443 kw_only_args, success_label, code):
2444 argtuple_error_label = code.new_label("argtuple_error")
2446 min_positional_args = self.num_required_args - self.num_required_kw_args
2447 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2448 min_positional_args -= 1
2449 max_positional_args = len(positional_args)
2450 has_fixed_positional_count = not self.star_arg and \
2451 min_positional_args == max_positional_args
2453 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2454 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2455 if self.num_required_kw_args:
2456 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2458 if self.starstar_arg or self.star_arg:
2459 self.generate_stararg_init_code(max_positional_args, code)
2461 # --- optimised code when we receive keyword arguments
2462 if self.num_required_kw_args:
2463 likely_hint = "likely"
2465 likely_hint = "unlikely"
2466 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2467 self.generate_keyword_unpacking_code(
2468 min_positional_args, max_positional_args,
2469 has_fixed_positional_count,
2470 positional_args, kw_only_args, argtuple_error_label, code)
2472 # --- optimised code when we do not receive any keyword arguments
2473 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2474 # Python raises arg tuple related errors first, so we must
2475 # check the length here
2476 if min_positional_args == max_positional_args and not self.star_arg:
2480 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2481 Naming.args_cname, compare, min_positional_args))
2482 code.put_goto(argtuple_error_label)
2484 if self.num_required_kw_args:
2485 # pure error case: keywords required but not passed
2486 if max_positional_args > min_positional_args and not self.star_arg:
2487 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2488 Naming.args_cname, max_positional_args))
2489 code.put_goto(argtuple_error_label)
2490 code.putln('} else {')
2491 for i, arg in enumerate(kw_only_args):
2493 pystring_cname = code.intern_identifier(arg.name)
2494 # required keyword-only argument missing
2495 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2498 code.putln(code.error_goto(self.pos))
2501 elif min_positional_args == max_positional_args:
2502 # parse the exact number of positional arguments from the
2504 code.putln('} else {')
2505 for i, arg in enumerate(positional_args):
2506 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2507 self.generate_arg_assignment(arg, item, code)
2508 self.generate_arg_default_assignments(code)
2511 # parse the positional arguments from the variable length
2513 code.putln('} else {')
2514 self.generate_arg_default_assignments(code)
2515 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2517 code.putln('default:')
2518 reversed_args = list(enumerate(positional_args))[::-1]
2519 for i, arg in reversed_args:
2520 if i >= min_positional_args-1:
2521 if min_positional_args > 1:
2522 code.putln('case %2d:' % (i+1)) # pure code beautification
2524 code.put('case %2d: ' % (i+1))
2525 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2526 self.generate_arg_assignment(arg, item, code)
2527 if min_positional_args == 0:
2528 code.put('case 0: ')
2529 code.putln('break;')
2531 if min_positional_args:
2532 for i in range(min_positional_args-1, -1, -1):
2533 code.putln('case %2d:' % i)
2534 code.put_goto(argtuple_error_label)
2536 code.put('default: ')
2537 code.put_goto(argtuple_error_label)
2542 if code.label_used(argtuple_error_label):
2543 code.put_goto(success_label)
2544 code.put_label(argtuple_error_label)
2545 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2546 self.name, has_fixed_positional_count,
2547 min_positional_args, max_positional_args,
2549 code.putln(code.error_goto(self.pos))
2551 def generate_arg_default_assignments(self, code):
2552 for arg in self.args:
2553 if arg.is_generic and arg.default:
2557 arg.calculate_default_value_code(code)))
2559 def generate_stararg_init_code(self, max_positional_args, code):
2560 if self.starstar_arg:
2561 self.starstar_arg.entry.xdecref_cleanup = 0
2562 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2563 self.starstar_arg.entry.cname,
2564 self.starstar_arg.entry.cname,
2565 self.error_value()))
2566 code.put_gotref(self.starstar_arg.entry.cname)
2568 self.star_arg.entry.xdecref_cleanup = 0
2569 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2571 max_positional_args))
2572 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2573 self.star_arg.entry.cname, Naming.args_cname,
2574 max_positional_args, Naming.args_cname))
2575 code.put_gotref(self.star_arg.entry.cname)
2576 if self.starstar_arg:
2578 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2579 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2580 code.putln('return %s;' % self.error_value())
2583 code.putln("if (unlikely(!%s)) return %s;" % (
2584 self.star_arg.entry.cname, self.error_value()))
2585 code.putln('} else {')
2586 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2587 code.put_incref(Naming.empty_tuple, py_object_type)
2590 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2591 has_fixed_positional_count, positional_args,
2592 kw_only_args, argtuple_error_label, code):
2593 all_args = tuple(positional_args) + tuple(kw_only_args)
2594 max_args = len(all_args)
2597 for i, arg in enumerate(all_args):
2598 if arg.default and arg.type.is_pyobject:
2599 default_value = arg.calculate_default_value_code(code)
2600 if arg.type is not PyrexTypes.py_object_type:
2601 default_value = "(PyObject*)"+default_value
2602 default_args.append((i, default_value))
2604 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2606 # the 'values' array collects borrowed references to arguments
2607 # before doing any type coercion etc.
2608 code.putln("PyObject* values[%d] = {%s};" % (
2609 max_args, ','.join('0'*max_args)))
2610 # it looks funny to separate the init-to-0 from setting the
2611 # default value, but C89 needs this
2612 for i, default_value in default_args:
2613 code.putln('values[%d] = %s;' % (i, default_value))
2615 # parse the tuple and check that it's not too long
2616 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2618 code.putln('default:')
2619 for i in range(max_positional_args-1, -1, -1):
2620 code.put('case %2d: ' % (i+1))
2621 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2622 i, Naming.args_cname, i))
2623 code.putln('case 0: break;')
2624 if not self.star_arg:
2625 code.put('default: ') # more arguments than allowed
2626 code.put_goto(argtuple_error_label)
2629 # now fill up the positional/required arguments with values
2631 if self.num_required_args or max_positional_args > 0:
2632 last_required_arg = -1
2633 for i, arg in enumerate(all_args):
2635 last_required_arg = i
2636 if last_required_arg < max_positional_args:
2637 last_required_arg = max_positional_args-1
2638 num_required_args = self.num_required_args
2639 if max_positional_args > 0:
2640 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2641 for i, arg in enumerate(all_args[:last_required_arg+1]):
2642 if max_positional_args > 0 and i <= max_positional_args:
2643 if self.star_arg and i == max_positional_args:
2644 code.putln('default:')
2646 code.putln('case %2d:' % i)
2647 pystring_cname = code.intern_identifier(arg.name)
2650 # handled separately below
2652 code.putln('if (kw_args > 0) {')
2653 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2654 Naming.kwds_cname, pystring_cname))
2655 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2658 num_required_args -= 1
2659 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2660 i, Naming.kwds_cname, pystring_cname))
2661 code.putln('if (likely(values[%d])) kw_args--;' % i);
2662 if i < min_positional_args:
2664 # special case: we know arg 0 is missing
2666 code.put_goto(argtuple_error_label)
2668 # print the correct number of values (args or
2669 # kwargs) that were passed into positional
2670 # arguments up to this point
2671 code.putln('else {')
2672 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2673 self.name, has_fixed_positional_count,
2674 min_positional_args, max_positional_args, i))
2675 code.putln(code.error_goto(self.pos))
2678 code.putln('else {')
2679 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2680 self.name, pystring_cname))
2681 code.putln(code.error_goto(self.pos))
2683 if max_positional_args > 0:
2686 if kw_only_args and not self.starstar_arg:
2687 # unpack optional keyword-only arguments
2688 # checking for interned strings in a dict is faster than iterating
2689 # but it's too likely that we must iterate if we expect **kwargs
2691 for i, arg in enumerate(all_args[max_positional_args:]):
2692 if not arg.kw_only or not arg.default:
2694 optional_args.append((i+max_positional_args, arg))
2696 # this mimics an unrolled loop so that we can "break" out of it
2697 code.putln('while (kw_args > 0) {')
2698 code.putln('PyObject* value;')
2699 for i, arg in optional_args:
2700 pystring_cname = code.intern_identifier(arg.name)
2702 'value = PyDict_GetItem(%s, %s);' % (
2703 Naming.kwds_cname, pystring_cname))
2705 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2706 code.putln('break;')
2709 code.putln('if (unlikely(kw_args > 0)) {')
2710 # non-positional/-required kw args left in dict: default args,
2711 # kw-only args, **kwargs or error
2713 # This is sort of a catch-all: except for checking required
2714 # arguments, this will always do the right thing for unpacking
2715 # keyword arguments, so that we can concentrate on optimising
2716 # common cases above.
2717 if max_positional_args == 0:
2720 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2721 Naming.args_cname, max_positional_args,
2722 Naming.args_cname, max_positional_args))
2723 pos_arg_count = "used_pos_args"
2725 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2726 code.globalstate.use_utility_code(parse_keywords_utility_code)
2728 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2730 Naming.pykwdlist_cname,
2731 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2734 code.putln(code.error_goto(self.pos))
2737 # convert arg values to their final type and assign them
2738 for i, arg in enumerate(all_args):
2739 if arg.default and not arg.type.is_pyobject:
2740 code.putln("if (values[%d]) {" % i)
2741 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2742 if arg.default and not arg.type.is_pyobject:
2743 code.putln('} else {')
2747 arg.calculate_default_value_code(code)))
2750 def generate_argument_conversion_code(self, code):
2751 # Generate code to convert arguments from signature type to
2752 # declared type, if needed. Also copies signature arguments
2753 # into closure fields.
2754 for arg in self.args:
2755 if arg.needs_conversion:
2756 self.generate_arg_conversion(arg, code)
2757 elif arg.entry.in_closure:
2758 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2759 if arg.type.is_pyobject:
2760 code.put_var_incref(arg.entry)
2762 def generate_arg_conversion(self, arg, code):
2763 # Generate conversion code for one argument.
2764 old_type = arg.hdr_type
2766 if old_type.is_pyobject:
2768 code.putln("if (%s) {" % arg.hdr_cname)
2770 code.putln("assert(%s); {" % arg.hdr_cname)
2771 self.generate_arg_conversion_from_pyobject(arg, code)
2773 elif new_type.is_pyobject:
2774 self.generate_arg_conversion_to_pyobject(arg, code)
2776 if new_type.assignable_from(old_type):
2778 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2781 "Cannot convert 1 argument from '%s' to '%s'" %
2782 (old_type, new_type))
2784 def generate_arg_conversion_from_pyobject(self, arg, code):
2786 func = new_type.from_py_function
2787 # copied from CoerceFromPyTypeNode
2789 lhs = arg.entry.cname
2790 rhs = "%s(%s)" % (func, arg.hdr_cname)
2791 if new_type.is_enum:
2792 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2793 code.putln("%s = %s; %s" % (
2796 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2799 "Cannot convert Python object argument to type '%s'"
2802 def generate_arg_conversion_to_pyobject(self, arg, code):
2803 old_type = arg.hdr_type
2804 func = old_type.to_py_function
2806 code.putln("%s = %s(%s); %s" % (
2810 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2811 code.put_var_gotref(arg.entry)
2814 "Cannot convert argument of type '%s' to Python object"
2817 def generate_argument_type_tests(self, code):
2818 # Generate type tests for args whose signature
2819 # type is PyObject * and whose declared type is
2820 # a subtype thereof.
2821 for arg in self.args:
2822 if arg.needs_type_test:
2823 self.generate_arg_type_test(arg, code)
2824 elif not arg.accept_none and arg.type.is_pyobject:
2825 self.generate_arg_none_check(arg, code)
2827 def error_value(self):
2828 return self.entry.signature.error_value
2830 def caller_will_check_exceptions(self):
2833 class OverrideCheckNode(StatNode):
2834 # A Node for dispatching to the def method if it
2843 child_attrs = ['body']
2847 def analyse_expressions(self, env):
2848 self.args = env.arg_entries
2849 if self.py_func.is_module_scope:
2854 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2855 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2856 call_node = ExprNodes.SimpleCallNode(self.pos,
2857 function=self.func_node,
2858 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2859 self.body = ReturnStatNode(self.pos, value=call_node)
2860 self.body.analyse_expressions(env)
2862 def generate_execution_code(self, code):
2863 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2864 # Check to see if we are an extension type
2865 if self.py_func.is_module_scope:
2866 self_arg = "((PyObject *)%s)" % Naming.module_cname
2868 self_arg = "((PyObject *)%s)" % self.args[0].cname
2869 code.putln("/* Check if called by wrapper */")
2870 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2871 code.putln("/* Check if overriden in Python */")
2872 if self.py_func.is_module_scope:
2873 code.putln("else {")
2875 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2876 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2877 self.func_node.set_cname(func_node_temp)
2878 # need to get attribute manually--scope would return cdef method
2879 err = code.error_goto_if_null(func_node_temp, self.pos)
2880 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2881 func_node_temp, self_arg, interned_attr_cname, err))
2882 code.put_gotref(func_node_temp)
2883 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2884 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2885 func_node_temp, self.py_func.entry.func_cname)
2886 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2887 self.body.generate_execution_code(code)
2889 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2890 code.funcstate.release_temp(func_node_temp)
2893 class ClassDefNode(StatNode, BlockNode):
2896 class PyClassDefNode(ClassDefNode):
2897 # A Python class definition.
2899 # name EncodedString Name of the class
2900 # doc string or None
2901 # body StatNode Attribute definition code
2902 # entry Symtab.Entry
2903 # scope PyClassScope
2904 # decorators [DecoratorNode] list of decorators or None
2906 # The following subnodes are constructed internally:
2908 # dict DictNode Class dictionary
2909 # classobj ClassNode Class object
2910 # target NameNode Variable to assign class object to
2912 child_attrs = ["body", "dict", "classobj", "target"]
2915 def __init__(self, pos, name, bases, doc, body, decorators = None):
2916 StatNode.__init__(self, pos)
2920 self.decorators = decorators
2922 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2923 if self.doc and Options.docstrings:
2924 doc = embed_position(self.pos, self.doc)
2925 # FIXME: correct string node?
2926 doc_node = ExprNodes.StringNode(pos, value = doc)
2929 self.classobj = ExprNodes.ClassNode(pos, name = name,
2930 bases = bases, dict = self.dict, doc = doc_node)
2931 self.target = ExprNodes.NameNode(pos, name = name)
2933 def as_cclass(self):
2935 Return this node as if it were declared as an extension class
2937 bases = self.classobj.bases.args
2939 base_class_name = None
2940 base_class_module = None
2941 elif len(bases) == 1:
2944 from ExprNodes import AttributeNode, NameNode
2945 while isinstance(base, AttributeNode):
2946 path.insert(0, base.attribute)
2948 if isinstance(base, NameNode):
2949 path.insert(0, base.name)
2950 base_class_name = path[-1]
2952 base_class_module = u'.'.join(path[:-1])
2954 base_class_module = None
2956 error(self.classobj.bases.args.pos, "Invalid base class")
2958 error(self.classobj.bases.args.pos, "C class may only have one base class")
2961 return CClassDefNode(self.pos,
2962 visibility = 'private',
2964 class_name = self.name,
2965 base_class_module = base_class_module,
2966 base_class_name = base_class_name,
2967 decorators = self.decorators,
2972 def create_scope(self, env):
2974 while env.is_py_class_scope or env.is_c_class_scope:
2975 env = env.outer_scope
2976 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2979 def analyse_declarations(self, env):
2980 self.target.analyse_target_declaration(env)
2981 cenv = self.create_scope(env)
2982 cenv.directives = env.directives
2983 cenv.class_obj_cname = self.target.entry.cname
2984 self.body.analyse_declarations(cenv)
2986 def analyse_expressions(self, env):
2987 self.dict.analyse_expressions(env)
2988 self.classobj.analyse_expressions(env)
2989 genv = env.global_scope()
2991 self.body.analyse_expressions(cenv)
2992 self.target.analyse_target_expression(env, self.classobj)
2994 def generate_function_definitions(self, env, code):
2995 self.body.generate_function_definitions(self.scope, code)
2997 def generate_execution_code(self, code):
2998 code.pyclass_stack.append(self)
3000 self.dict.generate_evaluation_code(code)
3001 self.classobj.generate_evaluation_code(code)
3002 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3003 self.body.generate_execution_code(code)
3004 self.target.generate_assignment_code(self.classobj, code)
3005 self.dict.generate_disposal_code(code)
3006 self.dict.free_temps(code)
3007 code.pyclass_stack.pop()
3010 class CClassDefNode(ClassDefNode):
3011 # An extension type definition.
3013 # visibility 'private' or 'public' or 'extern'
3014 # typedef_flag boolean
3016 # module_name string or None For import of extern type objects
3017 # class_name string Unqualified name of class
3018 # as_name string or None Name to declare as in this scope
3019 # base_class_module string or None Module containing the base class
3020 # base_class_name string or None Name of the base class
3021 # objstruct_name string or None Specified C name of object struct
3022 # typeobj_name string or None Specified C name of type object
3023 # in_pxd boolean Is in a .pxd file
3024 # decorators [DecoratorNode] list of decorators or None
3025 # doc string or None
3026 # body StatNode or None
3027 # entry Symtab.Entry
3028 # base_type PyExtensionType or None
3029 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3030 # buffer_defaults_pos
3032 child_attrs = ["body"]
3033 buffer_defaults_node = None
3034 buffer_defaults_pos = None
3035 typedef_flag = False
3037 objstruct_name = None
3041 def analyse_declarations(self, env):
3042 #print "CClassDefNode.analyse_declarations:", self.class_name
3043 #print "...visibility =", self.visibility
3044 #print "...module_name =", self.module_name
3047 if self.buffer_defaults_node:
3048 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3049 env, [], self.buffer_defaults_node,
3050 need_complete=False)
3052 buffer_defaults = None
3054 if env.in_cinclude and not self.objstruct_name:
3055 error(self.pos, "Object struct name specification required for "
3056 "C class defined in 'extern from' block")
3057 self.base_type = None
3058 # Now that module imports are cached, we need to
3059 # import the modules for extern classes.
3060 if self.module_name:
3062 for module in env.cimported_modules:
3063 if module.name == self.module_name:
3064 self.module = module
3065 if self.module is None:
3066 self.module = ModuleScope(self.module_name, None, env.context)
3067 self.module.has_extern_class = 1
3068 env.add_imported_module(self.module)
3070 if self.base_class_name:
3071 if self.base_class_module:
3072 base_class_scope = env.find_module(self.base_class_module, self.pos)
3074 base_class_scope = env
3075 if self.base_class_name == 'object':
3076 # extension classes are special and don't need to inherit from object
3077 if base_class_scope is None or base_class_scope.lookup('object') is None:
3078 self.base_class_name = None
3079 self.base_class_module = None
3080 base_class_scope = None
3081 if base_class_scope:
3082 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3083 if base_class_entry:
3084 if not base_class_entry.is_type:
3085 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3086 elif not base_class_entry.type.is_extension_type:
3087 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3088 elif not base_class_entry.type.is_complete():
3089 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
3091 self.base_type = base_class_entry.type
3092 has_body = self.body is not None
3093 if self.module_name and self.visibility != 'extern':
3094 module_path = self.module_name.split(".")
3095 home_scope = env.find_imported_module(module_path, self.pos)
3101 if self.visibility == 'extern':
3102 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3103 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3105 self.entry = home_scope.declare_c_class(
3106 name = self.class_name,
3108 defining = has_body and self.in_pxd,
3109 implementing = has_body and not self.in_pxd,
3110 module_name = self.module_name,
3111 base_type = self.base_type,
3112 objstruct_cname = self.objstruct_name,
3113 typeobj_cname = self.typeobj_name,
3114 visibility = self.visibility,
3115 typedef_flag = self.typedef_flag,
3117 buffer_defaults = buffer_defaults)
3118 if home_scope is not env and self.visibility == 'extern':
3119 env.add_imported_entry(self.class_name, self.entry, pos)
3120 self.scope = scope = self.entry.type.scope
3121 if scope is not None:
3122 scope.directives = env.directives
3124 if self.doc and Options.docstrings:
3125 scope.doc = embed_position(self.pos, self.doc)
3128 self.body.analyse_declarations(scope)
3132 scope.implemented = 1
3133 env.allocate_vtable_names(self.entry)
3135 def analyse_expressions(self, env):
3137 scope = self.entry.type.scope
3138 self.body.analyse_expressions(scope)
3140 def generate_function_definitions(self, env, code):
3142 self.body.generate_function_definitions(
3143 self.entry.type.scope, code)
3145 def generate_execution_code(self, code):
3146 # This is needed to generate evaluation code for
3147 # default values of method arguments.
3149 self.body.generate_execution_code(code)
3151 def annotate(self, code):
3153 self.body.annotate(code)
3156 class PropertyNode(StatNode):
3157 # Definition of a property in an extension type.
3160 # doc EncodedString or None Doc string
3163 child_attrs = ["body"]
3165 def analyse_declarations(self, env):
3166 entry = env.declare_property(self.name, self.doc, self.pos)
3168 entry.scope.directives = env.directives
3169 self.body.analyse_declarations(entry.scope)
3171 def analyse_expressions(self, env):
3172 self.body.analyse_expressions(env)
3174 def generate_function_definitions(self, env, code):
3175 self.body.generate_function_definitions(env, code)
3177 def generate_execution_code(self, code):
3180 def annotate(self, code):
3181 self.body.annotate(code)
3184 class GlobalNode(StatNode):
3185 # Global variable declaration.
3191 def analyse_declarations(self, env):
3192 for name in self.names:
3193 env.declare_global(name, self.pos)
3195 def analyse_expressions(self, env):
3198 def generate_execution_code(self, code):
3202 class ExprStatNode(StatNode):
3203 # Expression used as a statement.
3207 child_attrs = ["expr"]
3209 def analyse_declarations(self, env):
3211 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3212 func = self.expr.function.as_cython_attribute()
3213 if func == u'declare':
3214 args, kwds = self.expr.explicit_args_kwds()
3216 error(self.expr.pos, "Variable names must be specified.")
3217 for var, type_node in kwds.key_value_pairs:
3218 type = type_node.analyse_as_type(env)
3220 error(type_node.pos, "Unknown type")
3222 env.declare_var(var.value, type, var.pos, is_cdef = True)
3223 self.__class__ = PassStatNode
3225 def analyse_expressions(self, env):
3226 self.expr.analyse_expressions(env)
3228 def generate_execution_code(self, code):
3229 self.expr.generate_evaluation_code(code)
3230 if not self.expr.is_temp and self.expr.result():
3231 code.putln("%s;" % self.expr.result())
3232 self.expr.generate_disposal_code(code)
3233 self.expr.free_temps(code)
3235 def generate_function_definitions(self, env, code):
3236 self.expr.generate_function_definitions(env, code)
3238 def annotate(self, code):
3239 self.expr.annotate(code)
3242 class AssignmentNode(StatNode):
3243 # Abstract base class for assignment nodes.
3245 # The analyse_expressions and generate_execution_code
3246 # phases of assignments are split into two sub-phases
3247 # each, to enable all the right hand sides of a
3248 # parallel assignment to be evaluated before assigning
3249 # to any of the left hand sides.
3251 def analyse_expressions(self, env):
3252 self.analyse_types(env)
3254 # def analyse_expressions(self, env):
3255 # self.analyse_expressions_1(env)
3256 # self.analyse_expressions_2(env)
3258 def generate_execution_code(self, code):
3259 self.generate_rhs_evaluation_code(code)
3260 self.generate_assignment_code(code)
3263 class SingleAssignmentNode(AssignmentNode):
3264 # The simplest case:
3268 # lhs ExprNode Left hand side
3269 # rhs ExprNode Right hand side
3270 # first bool Is this guaranteed the first assignment to lhs?
3272 child_attrs = ["lhs", "rhs"]
3274 declaration_only = False
3276 def analyse_declarations(self, env):
3279 # handle declarations of the form x = cython.foo()
3280 if isinstance(self.rhs, ExprNodes.CallNode):
3281 func_name = self.rhs.function.as_cython_attribute()
3283 args, kwds = self.rhs.explicit_args_kwds()
3285 if func_name in ['declare', 'typedef']:
3286 if len(args) > 2 or kwds is not None:
3287 error(rhs.pos, "Can only declare one type at a time.")
3289 type = args[0].analyse_as_type(env)
3291 error(args[0].pos, "Unknown type")
3294 if func_name == 'declare':
3295 if isinstance(lhs, ExprNodes.NameNode):
3296 vars = [(lhs.name, lhs.pos)]
3297 elif isinstance(lhs, ExprNodes.TupleNode):
3298 vars = [(var.name, var.pos) for var in lhs.args]
3300 error(lhs.pos, "Invalid declaration")
3302 for var, pos in vars:
3303 env.declare_var(var, type, pos, is_cdef = True)
3308 self.declaration_only = True
3310 self.declaration_only = True
3311 if not isinstance(lhs, ExprNodes.NameNode):
3312 error(lhs.pos, "Invalid declaration.")
3313 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3315 elif func_name in ['struct', 'union']:
3316 self.declaration_only = True
3317 if len(args) > 0 or kwds is None:
3318 error(rhs.pos, "Struct or union members must be given by name.")
3321 for member, type_node in kwds.key_value_pairs:
3322 type = type_node.analyse_as_type(env)
3324 error(type_node.pos, "Unknown type")
3326 members.append((member.value, type, member.pos))
3327 if len(members) < len(kwds.key_value_pairs):
3329 if not isinstance(self.lhs, ExprNodes.NameNode):
3330 error(self.lhs.pos, "Invalid declaration.")
3331 name = self.lhs.name
3332 scope = StructOrUnionScope(name)
3333 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3334 for member, type, pos in members:
3335 scope.declare_var(member, type, pos)
3337 if self.declaration_only:
3340 self.lhs.analyse_target_declaration(env)
3342 def analyse_types(self, env, use_temp = 0):
3343 self.rhs.analyse_types(env)
3344 self.lhs.analyse_target_types(env)
3345 self.lhs.gil_assignment_check(env)
3346 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3348 self.rhs = self.rhs.coerce_to_temp(env)
3350 def generate_rhs_evaluation_code(self, code):
3351 self.rhs.generate_evaluation_code(code)
3353 def generate_assignment_code(self, code):
3354 self.lhs.generate_assignment_code(self.rhs, code)
3356 def generate_function_definitions(self, env, code):
3357 self.rhs.generate_function_definitions(env, code)
3359 def annotate(self, code):
3360 self.lhs.annotate(code)
3361 self.rhs.annotate(code)
3364 class CascadedAssignmentNode(AssignmentNode):
3365 # An assignment with multiple left hand sides:
3369 # lhs_list [ExprNode] Left hand sides
3370 # rhs ExprNode Right hand sides
3374 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3376 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3377 coerced_rhs_list = None
3379 def analyse_declarations(self, env):
3380 for lhs in self.lhs_list:
3381 lhs.analyse_target_declaration(env)
3383 def analyse_types(self, env, use_temp = 0):
3384 self.rhs.analyse_types(env)
3385 if not self.rhs.is_simple():
3387 self.rhs = self.rhs.coerce_to_temp(env)
3389 self.rhs = self.rhs.coerce_to_simple(env)
3390 from ExprNodes import CloneNode
3391 self.coerced_rhs_list = []
3392 for lhs in self.lhs_list:
3393 lhs.analyse_target_types(env)
3394 lhs.gil_assignment_check(env)
3395 rhs = CloneNode(self.rhs)
3396 rhs = rhs.coerce_to(lhs.type, env)
3397 self.coerced_rhs_list.append(rhs)
3399 def generate_rhs_evaluation_code(self, code):
3400 self.rhs.generate_evaluation_code(code)
3402 def generate_assignment_code(self, code):
3403 for i in range(len(self.lhs_list)):
3404 lhs = self.lhs_list[i]
3405 rhs = self.coerced_rhs_list[i]
3406 rhs.generate_evaluation_code(code)
3407 lhs.generate_assignment_code(rhs, code)
3408 # Assignment has disposed of the cloned RHS
3409 self.rhs.generate_disposal_code(code)
3410 self.rhs.free_temps(code)
3412 def generate_function_definitions(self, env, code):
3413 self.rhs.generate_function_definitions(env, code)
3415 def annotate(self, code):
3416 for i in range(len(self.lhs_list)):
3417 lhs = self.lhs_list[i].annotate(code)
3418 rhs = self.coerced_rhs_list[i].annotate(code)
3419 self.rhs.annotate(code)
3422 class ParallelAssignmentNode(AssignmentNode):
3423 # A combined packing/unpacking assignment:
3427 # This has been rearranged by the parser into
3429 # a = d ; b = e ; c = f
3431 # but we must evaluate all the right hand sides
3432 # before assigning to any of the left hand sides.
3434 # stats [AssignmentNode] The constituent assignments
3436 child_attrs = ["stats"]
3438 def analyse_declarations(self, env):
3439 for stat in self.stats:
3440 stat.analyse_declarations(env)
3442 def analyse_expressions(self, env):
3443 for stat in self.stats:
3444 stat.analyse_types(env, use_temp = 1)
3446 # def analyse_expressions(self, env):
3447 # for stat in self.stats:
3448 # stat.analyse_expressions_1(env, use_temp = 1)
3449 # for stat in self.stats:
3450 # stat.analyse_expressions_2(env)
3452 def generate_execution_code(self, code):
3453 for stat in self.stats:
3454 stat.generate_rhs_evaluation_code(code)
3455 for stat in self.stats:
3456 stat.generate_assignment_code(code)
3458 def generate_function_definitions(self, env, code):
3459 for stat in self.stats:
3460 stat.generate_function_definitions(env, code)
3462 def annotate(self, code):
3463 for stat in self.stats:
3467 class InPlaceAssignmentNode(AssignmentNode):
3468 # An in place arithmetic operand:
3474 # lhs ExprNode Left hand side
3475 # rhs ExprNode Right hand side
3476 # op char one of "+-*/%^&|"
3477 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3479 # This code is a bit tricky because in order to obey Python
3480 # semantics the sub-expressions (e.g. indices) of the lhs must
3481 # not be evaluated twice. So we must re-use the values calculated
3482 # in evaluation phase for the assignment phase as well.
3483 # Fortunately, the type of the lhs node is fairly constrained
3484 # (it must be a NameNode, AttributeNode, or IndexNode).
3486 child_attrs = ["lhs", "rhs"]
3489 def analyse_declarations(self, env):
3490 self.lhs.analyse_target_declaration(env)
3492 def analyse_types(self, env):
3493 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3494 self.rhs.analyse_types(env)
3495 self.lhs.analyse_target_types(env)
3497 if self.lhs.type.is_pyobject:
3498 self.rhs = self.rhs.coerce_to_pyobject(env)
3499 elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3500 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3501 if self.lhs.type.is_pyobject:
3502 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3503 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3505 def generate_execution_code(self, code):
3507 self.rhs.generate_evaluation_code(code)
3508 self.dup.generate_subexpr_evaluation_code(code)
3509 if self.dup.is_temp:
3510 self.dup.allocate_temp_result(code)
3511 # self.dup.generate_result_code is run only if it is not buffer access
3512 if self.operator == "**":
3516 if self.lhs.type.is_pyobject:
3517 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3518 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3519 self.dup.generate_result_code(code)
3520 self.result_value_temp.allocate(code)
3522 "%s = %s(%s, %s%s); %s" % (
3523 self.result_value.result(),
3524 self.py_operation_function(),
3525 self.dup.py_result(),
3526 self.rhs.py_result(),
3528 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3529 code.put_gotref(self.result_value.py_result())
3530 self.result_value.generate_evaluation_code(code) # May be a type check...
3531 self.rhs.generate_disposal_code(code)
3532 self.rhs.free_temps(code)
3533 self.dup.generate_disposal_code(code)
3534 self.dup.free_temps(code)
3535 self.lhs.generate_assignment_code(self.result_value, code)
3536 self.result_value_temp.release(code)
3538 c_op = self.operator
3542 error(self.pos, "No C inplace power operator")
3543 elif self.lhs.type.is_complex:
3544 error(self.pos, "Inplace operators not implemented for complex types.")
3546 # have to do assignment directly to avoid side-effects
3547 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3548 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3550 self.dup.generate_result_code(code)
3551 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3552 self.rhs.generate_disposal_code(code)
3553 self.rhs.free_temps(code)
3554 if self.dup.is_temp:
3555 self.dup.generate_subexpr_disposal_code(code)
3556 self.dup.free_subexpr_temps(code)
3558 def create_dup_node(self, env):
3561 self.dup.analyse_types(env)
3562 if isinstance(self.lhs, ExprNodes.NameNode):
3563 target_lhs = ExprNodes.NameNode(self.dup.pos,
3564 name = self.dup.name,
3565 is_temp = self.dup.is_temp,
3566 entry = self.dup.entry)
3567 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3568 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3569 obj = ExprNodes.CloneNode(self.lhs.obj),
3570 attribute = self.dup.attribute,
3571 is_temp = self.dup.is_temp)
3572 elif isinstance(self.lhs, ExprNodes.IndexNode):
3574 index = ExprNodes.CloneNode(self.lhs.index)
3577 if self.lhs.indices:
3578 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3581 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3582 base = ExprNodes.CloneNode(self.dup.base),
3585 is_temp = self.dup.is_temp)
3587 assert False, "Unsupported node: %s" % type(self.lhs)
3588 self.lhs = target_lhs
3591 def py_operation_function(self):
3592 return self.py_functions[self.operator]
3595 "|": "PyNumber_InPlaceOr",
3596 "^": "PyNumber_InPlaceXor",
3597 "&": "PyNumber_InPlaceAnd",
3598 "+": "PyNumber_InPlaceAdd",
3599 "-": "PyNumber_InPlaceSubtract",
3600 "*": "PyNumber_InPlaceMultiply",
3601 "/": "__Pyx_PyNumber_InPlaceDivide",
3602 "%": "PyNumber_InPlaceRemainder",
3603 "<<": "PyNumber_InPlaceLshift",
3604 ">>": "PyNumber_InPlaceRshift",
3605 "**": "PyNumber_InPlacePower",
3606 "//": "PyNumber_InPlaceFloorDivide",
3609 def annotate(self, code):
3610 self.lhs.annotate(code)
3611 self.rhs.annotate(code)
3612 self.dup.annotate(code)
3614 def create_binop_node(self):
3616 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3619 class PrintStatNode(StatNode):
3622 # arg_tuple TupleNode
3623 # stream ExprNode or None (stdout)
3624 # append_newline boolean
3626 child_attrs = ["arg_tuple", "stream"]
3628 def analyse_expressions(self, env):
3630 self.stream.analyse_expressions(env)
3631 self.stream = self.stream.coerce_to_pyobject(env)
3632 self.arg_tuple.analyse_expressions(env)
3633 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3634 env.use_utility_code(printing_utility_code)
3635 if len(self.arg_tuple.args) == 1 and self.append_newline:
3636 env.use_utility_code(printing_one_utility_code)
3638 nogil_check = Node.gil_error
3639 gil_message = "Python print statement"
3641 def generate_execution_code(self, code):
3643 self.stream.generate_evaluation_code(code)
3644 stream_result = self.stream.py_result()
3647 if len(self.arg_tuple.args) == 1 and self.append_newline:
3648 arg = self.arg_tuple.args[0]
3649 arg.generate_evaluation_code(code)
3652 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3655 code.error_goto(self.pos)))
3656 arg.generate_disposal_code(code)
3657 arg.free_temps(code)
3659 self.arg_tuple.generate_evaluation_code(code)
3661 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3663 self.arg_tuple.py_result(),
3664 self.append_newline,
3665 code.error_goto(self.pos)))
3666 self.arg_tuple.generate_disposal_code(code)
3667 self.arg_tuple.free_temps(code)
3670 self.stream.generate_disposal_code(code)
3671 self.stream.free_temps(code)
3673 def generate_function_definitions(self, env, code):
3675 self.stream.generate_function_definitions(env, code)
3676 self.arg_tuple.generate_function_definitions(env, code)
3678 def annotate(self, code):
3680 self.stream.annotate(code)
3681 self.arg_tuple.annotate(code)
3684 class ExecStatNode(StatNode):
3689 child_attrs = ["args"]
3691 def analyse_expressions(self, env):
3692 for i, arg in enumerate(self.args):
3693 arg.analyse_expressions(env)
3694 arg = arg.coerce_to_pyobject(env)
3696 env.use_utility_code(Builtin.pyexec_utility_code)
3698 nogil_check = Node.gil_error
3699 gil_message = "Python exec statement"
3701 def generate_execution_code(self, code):
3703 for arg in self.args:
3704 arg.generate_evaluation_code(code)
3705 args.append( arg.py_result() )
3706 args = tuple(args + ['0', '0'][:3-len(args)])
3707 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3708 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3709 (temp_result,) + args))
3710 for arg in self.args:
3711 arg.generate_disposal_code(code)
3712 arg.free_temps(code)
3714 code.error_goto_if_null(temp_result, self.pos))
3715 code.put_gotref(temp_result)
3716 code.put_decref_clear(temp_result, py_object_type)
3717 code.funcstate.release_temp(temp_result)
3719 def annotate(self, code):
3720 for arg in self.args:
3724 class DelStatNode(StatNode):
3729 child_attrs = ["args"]
3731 def analyse_declarations(self, env):
3732 for arg in self.args:
3733 arg.analyse_target_declaration(env)
3735 def analyse_expressions(self, env):
3736 for arg in self.args:
3737 arg.analyse_target_expression(env, None)
3738 if arg.type.is_pyobject:
3740 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3742 elif arg.type.is_cpp_class:
3743 error(arg.pos, "Deletion of non-heap C++ object")
3745 error(arg.pos, "Deletion of non-Python, non-C++ object")
3746 #arg.release_target_temp(env)
3748 def nogil_check(self, env):
3749 for arg in self.args:
3750 if arg.type.is_pyobject:
3753 gil_message = "Deleting Python object"
3755 def generate_execution_code(self, code):
3756 for arg in self.args:
3757 if arg.type.is_pyobject:
3758 arg.generate_deletion_code(code)
3759 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3760 arg.generate_result_code(code)
3761 code.putln("delete %s;" % arg.result())
3762 # else error reported earlier
3764 def annotate(self, code):
3765 for arg in self.args:
3769 class PassStatNode(StatNode):
3774 def analyse_expressions(self, env):
3777 def generate_execution_code(self, code):
3781 class BreakStatNode(StatNode):
3785 def analyse_expressions(self, env):
3788 def generate_execution_code(self, code):
3789 if not code.break_label:
3790 error(self.pos, "break statement not inside loop")
3792 code.put_goto(code.break_label)
3795 class ContinueStatNode(StatNode):
3799 def analyse_expressions(self, env):
3802 def generate_execution_code(self, code):
3803 if code.funcstate.in_try_finally:
3804 error(self.pos, "continue statement inside try of try...finally")
3805 elif not code.continue_label:
3806 error(self.pos, "continue statement not inside loop")
3808 code.put_goto(code.continue_label)
3811 class ReturnStatNode(StatNode):
3814 # value ExprNode or None
3815 # return_type PyrexType
3817 child_attrs = ["value"]
3819 def analyse_expressions(self, env):
3820 return_type = env.return_type
3821 self.return_type = return_type
3823 error(self.pos, "Return not inside a function body")
3826 self.value.analyse_types(env)
3827 if return_type.is_void or return_type.is_returncode:
3828 error(self.value.pos,
3829 "Return with value in void function")
3831 self.value = self.value.coerce_to(env.return_type, env)
3833 if (not return_type.is_void
3834 and not return_type.is_pyobject
3835 and not return_type.is_returncode):
3836 error(self.pos, "Return value required")
3838 def nogil_check(self, env):
3839 if self.return_type.is_pyobject:
3842 gil_message = "Returning Python object"
3844 def generate_execution_code(self, code):
3845 code.mark_pos(self.pos)
3846 if not self.return_type:
3847 # error reported earlier
3849 if self.return_type.is_pyobject:
3850 code.put_xdecref(Naming.retval_cname,
3853 self.value.generate_evaluation_code(code)
3854 self.value.make_owned_reference(code)
3857 Naming.retval_cname,
3858 self.value.result_as(self.return_type)))
3859 self.value.generate_post_assignment_code(code)
3860 self.value.free_temps(code)
3862 if self.return_type.is_pyobject:
3863 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3864 elif self.return_type.is_returncode:
3867 Naming.retval_cname,
3868 self.return_type.default_value))
3869 for cname, type in code.funcstate.temps_holding_reference():
3870 code.put_decref_clear(cname, type)
3871 code.put_goto(code.return_label)
3873 def generate_function_definitions(self, env, code):
3874 if self.value is not None:
3875 self.value.generate_function_definitions(env, code)
3877 def annotate(self, code):
3879 self.value.annotate(code)
3882 class RaiseStatNode(StatNode):
3885 # exc_type ExprNode or None
3886 # exc_value ExprNode or None
3887 # exc_tb ExprNode or None
3889 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3891 def analyse_expressions(self, env):
3893 self.exc_type.analyse_types(env)
3894 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3896 self.exc_value.analyse_types(env)
3897 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3899 self.exc_tb.analyse_types(env)
3900 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3901 env.use_utility_code(raise_utility_code)
3903 nogil_check = Node.gil_error
3904 gil_message = "Raising exception"
3906 def generate_execution_code(self, code):
3908 self.exc_type.generate_evaluation_code(code)
3909 type_code = self.exc_type.py_result()
3913 self.exc_value.generate_evaluation_code(code)
3914 value_code = self.exc_value.py_result()
3918 self.exc_tb.generate_evaluation_code(code)
3919 tb_code = self.exc_tb.py_result()
3923 "__Pyx_Raise(%s, %s, %s);" % (
3927 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3929 obj.generate_disposal_code(code)
3930 obj.free_temps(code)
3932 code.error_goto(self.pos))
3934 def generate_function_definitions(self, env, code):
3935 if self.exc_type is not None:
3936 self.exc_type.generate_function_definitions(env, code)
3937 if self.exc_value is not None:
3938 self.exc_value.generate_function_definitions(env, code)
3939 if self.exc_tb is not None:
3940 self.exc_tb.generate_function_definitions(env, code)
3942 def annotate(self, code):
3944 self.exc_type.annotate(code)
3946 self.exc_value.annotate(code)
3948 self.exc_tb.annotate(code)
3951 class ReraiseStatNode(StatNode):
3955 def analyse_expressions(self, env):
3956 env.use_utility_code(restore_exception_utility_code)
3958 nogil_check = Node.gil_error
3959 gil_message = "Raising exception"
3961 def generate_execution_code(self, code):
3962 vars = code.funcstate.exc_vars
3964 for varname in vars:
3965 code.put_giveref(varname)
3966 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3967 for varname in vars:
3968 code.put("%s = 0; " % varname)
3970 code.putln(code.error_goto(self.pos))
3972 error(self.pos, "Reraise not inside except clause")
3975 class AssertStatNode(StatNode):
3979 # value ExprNode or None
3981 child_attrs = ["cond", "value"]
3983 def analyse_expressions(self, env):
3984 self.cond = self.cond.analyse_boolean_expression(env)
3986 self.value.analyse_types(env)
3987 self.value = self.value.coerce_to_pyobject(env)
3989 nogil_check = Node.gil_error
3990 gil_message = "Raising exception"
3992 def generate_execution_code(self, code):
3993 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3994 self.cond.generate_evaluation_code(code)
3996 "if (unlikely(!%s)) {" %
3999 self.value.generate_evaluation_code(code)
4001 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4002 self.value.py_result())
4003 self.value.generate_disposal_code(code)
4004 self.value.free_temps(code)
4007 "PyErr_SetNone(PyExc_AssertionError);")
4009 code.error_goto(self.pos))
4012 self.cond.generate_disposal_code(code)
4013 self.cond.free_temps(code)
4014 code.putln("#endif")
4016 def generate_function_definitions(self, env, code):
4017 self.cond.generate_function_definitions(env, code)
4018 if self.value is not None:
4019 self.value.generate_function_definitions(env, code)
4021 def annotate(self, code):
4022 self.cond.annotate(code)
4024 self.value.annotate(code)
4027 class IfStatNode(StatNode):
4030 # if_clauses [IfClauseNode]
4031 # else_clause StatNode or None
4033 child_attrs = ["if_clauses", "else_clause"]
4035 def analyse_control_flow(self, env):
4036 env.start_branching(self.pos)
4037 for if_clause in self.if_clauses:
4038 if_clause.analyse_control_flow(env)
4039 env.next_branch(if_clause.end_pos())
4040 if self.else_clause:
4041 self.else_clause.analyse_control_flow(env)
4042 env.finish_branching(self.end_pos())
4044 def analyse_declarations(self, env):
4045 for if_clause in self.if_clauses:
4046 if_clause.analyse_declarations(env)
4047 if self.else_clause:
4048 self.else_clause.analyse_declarations(env)
4050 def analyse_expressions(self, env):
4051 for if_clause in self.if_clauses:
4052 if_clause.analyse_expressions(env)
4053 if self.else_clause:
4054 self.else_clause.analyse_expressions(env)
4056 def generate_execution_code(self, code):
4057 code.mark_pos(self.pos)
4058 end_label = code.new_label()
4059 for if_clause in self.if_clauses:
4060 if_clause.generate_execution_code(code, end_label)
4061 if self.else_clause:
4062 code.putln("/*else*/ {")
4063 self.else_clause.generate_execution_code(code)
4065 code.put_label(end_label)
4067 def generate_function_definitions(self, env, code):
4068 for clause in self.if_clauses:
4069 clause.generate_function_definitions(env, code)
4070 if self.else_clause is not None:
4071 self.else_clause.generate_function_definitions(env, code)
4073 def annotate(self, code):
4074 for if_clause in self.if_clauses:
4075 if_clause.annotate(code)
4076 if self.else_clause:
4077 self.else_clause.annotate(code)
4080 class IfClauseNode(Node):
4081 # if or elif clause in an if statement
4083 # condition ExprNode
4086 child_attrs = ["condition", "body"]
4088 def analyse_control_flow(self, env):
4089 self.body.analyse_control_flow(env)
4091 def analyse_declarations(self, env):
4092 self.condition.analyse_declarations(env)
4093 self.body.analyse_declarations(env)
4095 def analyse_expressions(self, env):
4097 self.condition.analyse_temp_boolean_expression(env)
4098 self.body.analyse_expressions(env)
4100 def get_constant_condition_result(self):
4101 if self.condition.has_constant_result():
4102 return bool(self.condition.constant_result)
4106 def generate_execution_code(self, code, end_label):
4107 self.condition.generate_evaluation_code(code)
4110 self.condition.result())
4111 self.condition.generate_disposal_code(code)
4112 self.condition.free_temps(code)
4113 self.body.generate_execution_code(code)
4114 code.put_goto(end_label)
4117 def generate_function_definitions(self, env, code):
4118 self.condition.generate_function_definitions(env, code)
4119 self.body.generate_function_definitions(env, code)
4121 def annotate(self, code):
4122 self.condition.annotate(code)
4123 self.body.annotate(code)
4126 class SwitchCaseNode(StatNode):
4127 # Generated in the optimization of an if-elif-else node
4129 # conditions [ExprNode]
4132 child_attrs = ['conditions', 'body']
4134 def generate_execution_code(self, code):
4135 for cond in self.conditions:
4136 code.mark_pos(cond.pos)
4137 cond.generate_evaluation_code(code)
4138 code.putln("case %s:" % cond.result())
4139 self.body.generate_execution_code(code)
4140 code.putln("break;")
4142 def generate_function_definitions(self, env, code):
4143 for cond in self.conditions:
4144 cond.generate_function_definitions(env, code)
4145 self.body.generate_function_definitions(env, code)
4147 def annotate(self, code):
4148 for cond in self.conditions:
4150 self.body.annotate(code)
4152 class SwitchStatNode(StatNode):
4153 # Generated in the optimization of an if-elif-else node
4156 # cases [SwitchCaseNode]
4157 # else_clause StatNode or None
4159 child_attrs = ['test', 'cases', 'else_clause']
4161 def generate_execution_code(self, code):
4162 code.putln("switch (%s) {" % self.test.result())
4163 for case in self.cases:
4164 case.generate_execution_code(code)
4165 if self.else_clause is not None:
4166 code.putln("default:")
4167 self.else_clause.generate_execution_code(code)
4168 code.putln("break;")
4171 def generate_function_definitions(self, env, code):
4172 self.test.generate_function_definitions(env, code)
4173 for case in self.cases:
4174 case.generate_function_definitions(env, code)
4175 if self.else_clause is not None:
4176 self.else_clause.generate_function_definitions(env, code)
4178 def annotate(self, code):
4179 self.test.annotate(code)
4180 for case in self.cases:
4182 if self.else_clause is not None:
4183 self.else_clause.annotate(code)
4185 class LoopNode(object):
4187 def analyse_control_flow(self, env):
4188 env.start_branching(self.pos)
4189 self.body.analyse_control_flow(env)
4190 env.next_branch(self.body.end_pos())
4191 if self.else_clause:
4192 self.else_clause.analyse_control_flow(env)
4193 env.finish_branching(self.end_pos())
4196 class WhileStatNode(LoopNode, StatNode):
4199 # condition ExprNode
4201 # else_clause StatNode
4203 child_attrs = ["condition", "body", "else_clause"]
4205 def analyse_declarations(self, env):
4206 self.body.analyse_declarations(env)
4207 if self.else_clause:
4208 self.else_clause.analyse_declarations(env)
4210 def analyse_expressions(self, env):
4212 self.condition.analyse_temp_boolean_expression(env)
4213 self.body.analyse_expressions(env)
4214 if self.else_clause:
4215 self.else_clause.analyse_expressions(env)
4217 def generate_execution_code(self, code):
4218 old_loop_labels = code.new_loop_labels()
4221 self.condition.generate_evaluation_code(code)
4222 self.condition.generate_disposal_code(code)
4225 self.condition.result())
4226 self.condition.free_temps(code)
4227 self.body.generate_execution_code(code)
4228 code.put_label(code.continue_label)
4230 break_label = code.break_label
4231 code.set_loop_labels(old_loop_labels)
4232 if self.else_clause:
4233 code.putln("/*else*/ {")
4234 self.else_clause.generate_execution_code(code)
4236 code.put_label(break_label)
4238 def generate_function_definitions(self, env, code):
4239 self.condition.generate_function_definitions(env, code)
4240 self.body.generate_function_definitions(env, code)
4241 if self.else_clause is not None:
4242 self.else_clause.generate_function_definitions(env, code)
4244 def annotate(self, code):
4245 self.condition.annotate(code)
4246 self.body.annotate(code)
4247 if self.else_clause:
4248 self.else_clause.annotate(code)
4251 def ForStatNode(pos, **kw):
4252 if 'iterator' in kw:
4253 return ForInStatNode(pos, **kw)
4255 return ForFromStatNode(pos, **kw)
4257 class ForInStatNode(LoopNode, StatNode):
4261 # iterator IteratorNode
4263 # else_clause StatNode
4264 # item NextNode used internally
4266 child_attrs = ["target", "iterator", "body", "else_clause"]
4269 def analyse_declarations(self, env):
4270 self.target.analyse_target_declaration(env)
4271 self.body.analyse_declarations(env)
4272 if self.else_clause:
4273 self.else_clause.analyse_declarations(env)
4275 def analyse_expressions(self, env):
4277 self.target.analyse_target_types(env)
4278 self.iterator.analyse_expressions(env)
4279 self.item = ExprNodes.NextNode(self.iterator, env)
4280 self.item = self.item.coerce_to(self.target.type, env)
4281 self.body.analyse_expressions(env)
4282 if self.else_clause:
4283 self.else_clause.analyse_expressions(env)
4285 def generate_execution_code(self, code):
4286 old_loop_labels = code.new_loop_labels()
4287 self.iterator.allocate_counter_temp(code)
4288 self.iterator.generate_evaluation_code(code)
4291 self.item.generate_evaluation_code(code)
4292 self.target.generate_assignment_code(self.item, code)
4293 self.body.generate_execution_code(code)
4294 code.put_label(code.continue_label)
4297 break_label = code.break_label
4298 code.set_loop_labels(old_loop_labels)
4300 if self.else_clause:
4301 # in nested loops, the 'else' block can contain a
4302 # 'continue' statement for the outer loop, but we may need
4303 # to generate cleanup code before taking that path, so we
4305 orig_continue_label = code.continue_label
4306 code.continue_label = code.new_label('outer_continue')
4308 code.putln("/*else*/ {")
4309 self.else_clause.generate_execution_code(code)
4312 if code.label_used(code.continue_label):
4313 code.put_goto(break_label)
4314 code.put_label(code.continue_label)
4315 self.iterator.generate_disposal_code(code)
4316 code.put_goto(orig_continue_label)
4317 code.set_loop_labels(old_loop_labels)
4319 if code.label_used(break_label):
4320 code.put_label(break_label)
4321 self.iterator.release_counter_temp(code)
4322 self.iterator.generate_disposal_code(code)
4323 self.iterator.free_temps(code)
4325 def generate_function_definitions(self, env, code):
4326 self.target.generate_function_definitions(env, code)
4327 self.iterator.generate_function_definitions(env, code)
4328 self.body.generate_function_definitions(env, code)
4329 if self.else_clause is not None:
4330 self.else_clause.generate_function_definitions(env, code)
4332 def annotate(self, code):
4333 self.target.annotate(code)
4334 self.iterator.annotate(code)
4335 self.body.annotate(code)
4336 if self.else_clause:
4337 self.else_clause.annotate(code)
4338 self.item.annotate(code)
4341 class ForFromStatNode(LoopNode, StatNode):
4342 # for name from expr rel name rel expr
4349 # step ExprNode or None
4351 # else_clause StatNode or None
4357 # loopvar_node ExprNode (usually a NameNode or temp node)
4358 # py_loopvar_node PyTempNode or None
4359 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4361 is_py_target = False
4363 py_loopvar_node = None
4366 gil_message = "For-loop using object bounds or target"
4368 def nogil_check(self, env):
4369 for x in (self.target, self.bound1, self.bound2):
4370 if x.type.is_pyobject:
4373 def analyse_declarations(self, env):
4374 self.target.analyse_target_declaration(env)
4375 self.body.analyse_declarations(env)
4376 if self.else_clause:
4377 self.else_clause.analyse_declarations(env)
4379 def analyse_expressions(self, env):
4381 self.target.analyse_target_types(env)
4382 self.bound1.analyse_types(env)
4383 self.bound2.analyse_types(env)
4384 if self.step is not None:
4385 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4386 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4387 self.step.analyse_types(env)
4389 target_type = self.target.type
4390 if self.target.type.is_numeric:
4391 loop_type = self.target.type
4393 loop_type = PyrexTypes.c_int_type
4394 if not self.bound1.type.is_pyobject:
4395 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4396 if not self.bound2.type.is_pyobject:
4397 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4398 if self.step is not None and not self.step.type.is_pyobject:
4399 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4400 self.bound1 = self.bound1.coerce_to(loop_type, env)
4401 self.bound2 = self.bound2.coerce_to(loop_type, env)
4402 if not self.bound2.is_literal:
4403 self.bound2 = self.bound2.coerce_to_temp(env)
4404 if self.step is not None:
4405 self.step = self.step.coerce_to(loop_type, env)
4406 if not self.step.is_literal:
4407 self.step = self.step.coerce_to_temp(env)
4409 target_type = self.target.type
4410 if not (target_type.is_pyobject or target_type.is_numeric):
4411 error(self.target.pos,
4412 "for-from loop variable must be c numeric type or Python object")
4413 if target_type.is_numeric:
4414 self.is_py_target = False
4415 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4416 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4417 self.loopvar_node = self.target
4418 self.py_loopvar_node = None
4420 self.is_py_target = True
4421 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4422 self.loopvar_node = c_loopvar_node
4423 self.py_loopvar_node = \
4424 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4425 self.body.analyse_expressions(env)
4426 if self.else_clause:
4427 self.else_clause.analyse_expressions(env)
4429 def generate_execution_code(self, code):
4430 old_loop_labels = code.new_loop_labels()
4431 from_range = self.from_range
4432 self.bound1.generate_evaluation_code(code)
4433 self.bound2.generate_evaluation_code(code)
4434 offset, incop = self.relation_table[self.relation1]
4435 if self.step is not None:
4436 self.step.generate_evaluation_code(code)
4437 step = self.step.result()
4438 incop = "%s=%s" % (incop[0], step)
4440 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4441 self.loopvar_node.allocate(code)
4442 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4443 self.py_loopvar_node.allocate(code)
4445 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4447 loopvar_name = self.loopvar_node.result()
4449 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4451 self.bound1.result(), offset,
4452 loopvar_name, self.relation2, self.bound2.result(),
4453 loopvar_name, incop))
4454 if self.py_loopvar_node:
4455 self.py_loopvar_node.generate_evaluation_code(code)
4456 self.target.generate_assignment_code(self.py_loopvar_node, code)
4458 code.putln("%s = %s;" % (
4459 self.target.result(), loopvar_name))
4460 self.body.generate_execution_code(code)
4461 code.put_label(code.continue_label)
4462 if self.py_loopvar_node:
4463 # This mess is to make for..from loops with python targets behave
4464 # exactly like those with C targets with regards to re-assignment
4465 # of the loop variable.
4467 if self.target.entry.is_pyglobal:
4468 # We know target is a NameNode, this is the only ugly case.
4469 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4470 target_node.allocate(code)
4471 interned_cname = code.intern_identifier(self.target.entry.name)
4472 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4473 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4474 target_node.result(),
4475 Naming.module_cname,
4477 code.error_goto_if_null(target_node.result(), self.target.pos)))
4478 code.put_gotref(target_node.result())
4480 target_node = self.target
4481 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4482 from_py_node.temp_code = loopvar_name
4483 from_py_node.generate_result_code(code)
4484 if self.target.entry.is_pyglobal:
4485 code.put_decref(target_node.result(), target_node.type)
4486 target_node.release(code)
4488 if self.py_loopvar_node:
4489 # This is potentially wasteful, but we don't want the semantics to
4490 # depend on whether or not the loop is a python type.
4491 self.py_loopvar_node.generate_evaluation_code(code)
4492 self.target.generate_assignment_code(self.py_loopvar_node, code)
4494 code.funcstate.release_temp(loopvar_name)
4495 break_label = code.break_label
4496 code.set_loop_labels(old_loop_labels)
4497 if self.else_clause:
4498 code.putln("/*else*/ {")
4499 self.else_clause.generate_execution_code(code)
4501 code.put_label(break_label)
4502 self.bound1.generate_disposal_code(code)
4503 self.bound1.free_temps(code)
4504 self.bound2.generate_disposal_code(code)
4505 self.bound2.free_temps(code)
4506 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4507 self.loopvar_node.release(code)
4508 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4509 self.py_loopvar_node.release(code)
4510 if self.step is not None:
4511 self.step.generate_disposal_code(code)
4512 self.step.free_temps(code)
4515 # {relop : (initial offset, increment op)}
4522 def generate_function_definitions(self, env, code):
4523 self.target.generate_function_definitions(env, code)
4524 self.bound1.generate_function_definitions(env, code)
4525 self.bound2.generate_function_definitions(env, code)
4526 if self.step is not None:
4527 self.step.generate_function_definitions(env, code)
4528 self.body.generate_function_definitions(env, code)
4529 if self.else_clause is not None:
4530 self.else_clause.generate_function_definitions(env, code)
4532 def annotate(self, code):
4533 self.target.annotate(code)
4534 self.bound1.annotate(code)
4535 self.bound2.annotate(code)
4537 self.step.annotate(code)
4538 self.body.annotate(code)
4539 if self.else_clause:
4540 self.else_clause.annotate(code)
4543 class WithStatNode(StatNode):
4545 Represents a Python with statement.
4547 This is only used at parse tree level; and is not present in
4548 analysis or generation phases.
4550 # manager The with statement manager object
4551 # target Node (lhs expression)
4553 child_attrs = ["manager", "target", "body"]
4555 class TryExceptStatNode(StatNode):
4556 # try .. except statement
4559 # except_clauses [ExceptClauseNode]
4560 # else_clause StatNode or None
4562 child_attrs = ["body", "except_clauses", "else_clause"]
4564 def analyse_control_flow(self, env):
4565 env.start_branching(self.pos)
4566 self.body.analyse_control_flow(env)
4567 successful_try = env.control_flow # grab this for later
4568 env.next_branch(self.body.end_pos())
4569 env.finish_branching(self.body.end_pos())
4571 env.start_branching(self.except_clauses[0].pos)
4572 for except_clause in self.except_clauses:
4573 except_clause.analyse_control_flow(env)
4574 env.next_branch(except_clause.end_pos())
4576 # the else cause it executed only when the try clause finishes
4577 env.control_flow.incoming = successful_try
4578 if self.else_clause:
4579 self.else_clause.analyse_control_flow(env)
4580 env.finish_branching(self.end_pos())
4582 def analyse_declarations(self, env):
4583 self.body.analyse_declarations(env)
4584 for except_clause in self.except_clauses:
4585 except_clause.analyse_declarations(env)
4586 if self.else_clause:
4587 self.else_clause.analyse_declarations(env)
4588 env.use_utility_code(reset_exception_utility_code)
4590 def analyse_expressions(self, env):
4591 self.body.analyse_expressions(env)
4592 default_clause_seen = 0
4593 for except_clause in self.except_clauses:
4594 except_clause.analyse_expressions(env)
4595 if default_clause_seen:
4596 error(except_clause.pos, "default 'except:' must be last")
4597 if not except_clause.pattern:
4598 default_clause_seen = 1
4599 self.has_default_clause = default_clause_seen
4600 if self.else_clause:
4601 self.else_clause.analyse_expressions(env)
4603 nogil_check = Node.gil_error
4604 gil_message = "Try-except statement"
4606 def generate_execution_code(self, code):
4607 old_return_label = code.return_label
4608 old_break_label = code.break_label
4609 old_continue_label = code.continue_label
4610 old_error_label = code.new_error_label()
4611 our_error_label = code.error_label
4612 except_end_label = code.new_label('exception_handled')
4613 except_error_label = code.new_label('except_error')
4614 except_return_label = code.new_label('except_return')
4615 try_return_label = code.new_label('try_return')
4616 try_break_label = code.new_label('try_break')
4617 try_continue_label = code.new_label('try_continue')
4618 try_end_label = code.new_label('try_end')
4621 code.putln("PyObject %s;" %
4622 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4623 code.putln("__Pyx_ExceptionSave(%s);" %
4624 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4625 for var in Naming.exc_save_vars:
4626 code.put_xgotref(var)
4629 code.return_label = try_return_label
4630 code.break_label = try_break_label
4631 code.continue_label = try_continue_label
4632 self.body.generate_execution_code(code)
4635 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4636 code.error_label = except_error_label
4637 code.return_label = except_return_label
4638 if self.else_clause:
4641 self.else_clause.generate_execution_code(code)
4644 for var in Naming.exc_save_vars:
4645 code.put_xdecref_clear(var, py_object_type)
4646 code.put_goto(try_end_label)
4647 if code.label_used(try_return_label):
4648 code.put_label(try_return_label)
4649 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4650 code.putln("__Pyx_ExceptionReset(%s);" %
4651 ', '.join(Naming.exc_save_vars))
4652 code.put_goto(old_return_label)
4653 code.put_label(our_error_label)
4654 for temp_name, type in temps_to_clean_up:
4655 code.put_xdecref_clear(temp_name, type)
4656 for except_clause in self.except_clauses:
4657 except_clause.generate_handling_code(code, except_end_label)
4659 error_label_used = code.label_used(except_error_label)
4660 if error_label_used or not self.has_default_clause:
4661 if error_label_used:
4662 code.put_label(except_error_label)
4663 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4664 code.putln("__Pyx_ExceptionReset(%s);" %
4665 ', '.join(Naming.exc_save_vars))
4666 code.put_goto(old_error_label)
4668 for exit_label, old_label in zip(
4669 [try_break_label, try_continue_label, except_return_label],
4670 [old_break_label, old_continue_label, old_return_label]):
4672 if code.label_used(exit_label):
4673 code.put_label(exit_label)
4674 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4675 code.putln("__Pyx_ExceptionReset(%s);" %
4676 ', '.join(Naming.exc_save_vars))
4677 code.put_goto(old_label)
4679 if code.label_used(except_end_label):
4680 code.put_label(except_end_label)
4681 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4682 code.putln("__Pyx_ExceptionReset(%s);" %
4683 ', '.join(Naming.exc_save_vars))
4684 code.put_label(try_end_label)
4687 code.return_label = old_return_label
4688 code.break_label = old_break_label
4689 code.continue_label = old_continue_label
4690 code.error_label = old_error_label
4692 def generate_function_definitions(self, env, code):
4693 self.body.generate_function_definitions(env, code)
4694 for except_clause in self.except_clauses:
4695 except_clause.generate_function_definitions(env, code)
4696 if self.else_clause is not None:
4697 self.else_clause.generate_function_definitions(env, code)
4699 def annotate(self, code):
4700 self.body.annotate(code)
4701 for except_node in self.except_clauses:
4702 except_node.annotate(code)
4703 if self.else_clause:
4704 self.else_clause.annotate(code)
4707 class ExceptClauseNode(Node):
4708 # Part of try ... except statement.
4711 # target ExprNode or None
4713 # excinfo_target NameNode or None optional target for exception info
4714 # match_flag string result of exception match
4715 # exc_value ExcValueNode used internally
4716 # function_name string qualified name of enclosing function
4717 # exc_vars (string * 3) local exception variables
4719 # excinfo_target is never set by the parser, but can be set by a transform
4720 # in order to extract more extensive information about the exception as a
4721 # sys.exc_info()-style tuple into a target variable
4723 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4726 excinfo_target = None
4728 def analyse_declarations(self, env):
4730 self.target.analyse_target_declaration(env)
4731 if self.excinfo_target is not None:
4732 self.excinfo_target.analyse_target_declaration(env)
4733 self.body.analyse_declarations(env)
4735 def analyse_expressions(self, env):
4737 genv = env.global_scope()
4738 self.function_name = env.qualified_name
4740 self.pattern.analyse_expressions(env)
4741 self.pattern = self.pattern.coerce_to_pyobject(env)
4744 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4745 self.target.analyse_target_expression(env, self.exc_value)
4746 if self.excinfo_target is not None:
4748 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4749 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4750 self.excinfo_tuple.analyse_expressions(env)
4751 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4753 self.body.analyse_expressions(env)
4755 def generate_handling_code(self, code, end_label):
4756 code.mark_pos(self.pos)
4758 self.pattern.generate_evaluation_code(code)
4760 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4762 "%s = PyErr_ExceptionMatches(%s);" % (
4764 self.pattern.py_result()))
4765 self.pattern.generate_disposal_code(code)
4766 self.pattern.free_temps(code)
4770 code.funcstate.release_temp(match_flag)
4772 code.putln("/*except:*/ {")
4774 if not getattr(self.body, 'stats', True) and \
4775 self.excinfo_target is None and self.target is None:
4776 # most simple case: no exception variable, empty body (pass)
4777 # => reset the exception state, done
4778 code.putln("PyErr_Restore(0,0,0);")
4779 code.put_goto(end_label)
4783 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4786 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4787 # We always have to fetch the exception value even if
4788 # there is no target, because this also normalises the
4789 # exception and stores it in the thread state.
4790 code.globalstate.use_utility_code(get_exception_utility_code)
4791 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4792 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4793 code.error_goto(self.pos)))
4797 self.exc_value.set_var(exc_vars[1])
4798 self.exc_value.generate_evaluation_code(code)
4799 self.target.generate_assignment_code(self.exc_value, code)
4800 if self.excinfo_target is not None:
4801 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4802 node.set_var(tempvar)
4803 self.excinfo_tuple.generate_evaluation_code(code)
4804 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4806 old_break_label, old_continue_label = code.break_label, code.continue_label
4807 code.break_label = code.new_label('except_break')
4808 code.continue_label = code.new_label('except_continue')
4810 old_exc_vars = code.funcstate.exc_vars
4811 code.funcstate.exc_vars = exc_vars
4812 self.body.generate_execution_code(code)
4813 code.funcstate.exc_vars = old_exc_vars
4814 for var in exc_vars:
4815 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4816 code.put_goto(end_label)
4818 if code.label_used(code.break_label):
4819 code.put_label(code.break_label)
4820 for var in exc_vars:
4821 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4822 code.put_goto(old_break_label)
4823 code.break_label = old_break_label
4825 if code.label_used(code.continue_label):
4826 code.put_label(code.continue_label)
4827 for var in exc_vars:
4828 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4829 code.put_goto(old_continue_label)
4830 code.continue_label = old_continue_label
4832 for temp in exc_vars:
4833 code.funcstate.release_temp(temp)
4838 def generate_function_definitions(self, env, code):
4839 if self.target is not None:
4840 self.target.generate_function_definitions(env, code)
4841 self.body.generate_function_definitions(env, code)
4843 def annotate(self, code):
4845 self.pattern.annotate(code)
4847 self.target.annotate(code)
4848 self.body.annotate(code)
4851 class TryFinallyStatNode(StatNode):
4852 # try ... finally statement
4855 # finally_clause StatNode
4857 # The plan is that we funnel all continue, break
4858 # return and error gotos into the beginning of the
4859 # finally block, setting a variable to remember which
4860 # one we're doing. At the end of the finally block, we
4861 # switch on the variable to figure out where to go.
4862 # In addition, if we're doing an error, we save the
4863 # exception on entry to the finally block and restore
4866 child_attrs = ["body", "finally_clause"]
4868 preserve_exception = 1
4870 disallow_continue_in_try_finally = 0
4871 # There doesn't seem to be any point in disallowing
4872 # continue in the try block, since we have no problem
4875 def create_analysed(pos, env, body, finally_clause):
4876 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4878 create_analysed = staticmethod(create_analysed)
4880 def analyse_control_flow(self, env):
4881 env.start_branching(self.pos)
4882 self.body.analyse_control_flow(env)
4883 env.next_branch(self.body.end_pos())
4884 env.finish_branching(self.body.end_pos())
4885 self.finally_clause.analyse_control_flow(env)
4887 def analyse_declarations(self, env):
4888 self.body.analyse_declarations(env)
4889 self.finally_clause.analyse_declarations(env)
4891 def analyse_expressions(self, env):
4892 self.body.analyse_expressions(env)
4893 self.finally_clause.analyse_expressions(env)
4895 nogil_check = Node.gil_error
4896 gil_message = "Try-finally statement"
4898 def generate_execution_code(self, code):
4899 old_error_label = code.error_label
4900 old_labels = code.all_new_labels()
4901 new_labels = code.get_all_labels()
4902 new_error_label = code.error_label
4903 catch_label = code.new_label()
4906 if self.disallow_continue_in_try_finally:
4907 was_in_try_finally = code.funcstate.in_try_finally
4908 code.funcstate.in_try_finally = 1
4909 self.body.generate_execution_code(code)
4910 if self.disallow_continue_in_try_finally:
4911 code.funcstate.in_try_finally = was_in_try_finally
4914 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4915 code.mark_pos(self.finally_clause.pos)
4919 error_label_used = 0
4920 for i, new_label in enumerate(new_labels):
4921 if new_label in code.labels_used:
4922 cases_used.append(i)
4923 if new_label == new_error_label:
4924 error_label_used = 1
4925 error_label_case = i
4929 if error_label_used and self.preserve_exception:
4931 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4933 "int %s;" % Naming.exc_lineno_name)
4934 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4935 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4936 code.putln(exc_var_init_zero)
4938 exc_var_init_zero = None
4939 code.use_label(catch_label)
4941 "__pyx_why = 0; goto %s;" % catch_label)
4942 for i in cases_used:
4943 new_label = new_labels[i]
4944 #if new_label and new_label != "<try>":
4945 if new_label == new_error_label and self.preserve_exception:
4946 self.put_error_catcher(code,
4947 new_error_label, i+1, catch_label, temps_to_clean_up)
4949 code.put('%s: ' % new_label)
4950 if exc_var_init_zero:
4951 code.putln(exc_var_init_zero)
4952 code.putln("__pyx_why = %s; goto %s;" % (
4955 code.put_label(catch_label)
4956 code.set_all_labels(old_labels)
4957 if error_label_used:
4958 code.new_error_label()
4959 finally_error_label = code.error_label
4960 self.finally_clause.generate_execution_code(code)
4961 if error_label_used:
4962 if finally_error_label in code.labels_used and self.preserve_exception:
4963 over_label = code.new_label()
4964 code.put_goto(over_label);
4965 code.put_label(finally_error_label)
4966 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4967 for var in Naming.exc_vars:
4968 code.putln("Py_XDECREF(%s);" % var)
4970 code.put_goto(old_error_label)
4971 code.put_label(over_label)
4972 code.error_label = old_error_label
4975 "switch (__pyx_why) {")
4976 for i in cases_used:
4977 old_label = old_labels[i]
4978 if old_label == old_error_label and self.preserve_exception:
4979 self.put_error_uncatcher(code, i+1, old_error_label)
4981 code.use_label(old_label)
4983 "case %s: goto %s;" % (
4991 def generate_function_definitions(self, env, code):
4992 self.body.generate_function_definitions(env, code)
4993 self.finally_clause.generate_function_definitions(env, code)
4995 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4996 code.globalstate.use_utility_code(restore_exception_utility_code)
5003 for temp_name, type in temps_to_clean_up:
5004 code.put_xdecref_clear(temp_name, type)
5006 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5010 Naming.exc_lineno_name, Naming.lineno_cname))
5011 code.put_goto(catch_label)
5014 def put_error_uncatcher(self, code, i, error_label):
5015 code.globalstate.use_utility_code(restore_exception_utility_code)
5020 "__Pyx_ErrRestore(%s, %s, %s);" %
5024 Naming.lineno_cname, Naming.exc_lineno_name))
5025 for var in Naming.exc_vars:
5029 code.put_goto(error_label)
5033 def annotate(self, code):
5034 self.body.annotate(code)
5035 self.finally_clause.annotate(code)
5038 class GILStatNode(TryFinallyStatNode):
5039 # 'with gil' or 'with nogil' statement
5041 # state string 'gil' or 'nogil'
5045 preserve_exception = 0
5047 def __init__(self, pos, state, body):
5049 TryFinallyStatNode.__init__(self, pos,
5051 finally_clause = GILExitNode(pos, state = state))
5053 def analyse_expressions(self, env):
5054 env.use_utility_code(force_init_threads_utility_code)
5055 was_nogil = env.nogil
5057 TryFinallyStatNode.analyse_expressions(self, env)
5058 env.nogil = was_nogil
5062 def generate_execution_code(self, code):
5063 code.mark_pos(self.pos)
5064 if self.state == 'gil':
5065 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5067 code.putln("{ PyThreadState *_save;")
5068 code.putln("Py_UNBLOCK_THREADS")
5069 TryFinallyStatNode.generate_execution_code(self, code)
5073 class GILExitNode(StatNode):
5074 # Used as the 'finally' block in a GILStatNode
5076 # state string 'gil' or 'nogil'
5080 def analyse_expressions(self, env):
5083 def generate_execution_code(self, code):
5084 if self.state == 'gil':
5085 code.putln("PyGILState_Release();")
5087 code.putln("Py_BLOCK_THREADS")
5090 class CImportStatNode(StatNode):
5093 # module_name string Qualified name of module being imported
5094 # as_name string or None Name specified in "as" clause, if any
5098 def analyse_declarations(self, env):
5099 if not env.is_module_scope:
5100 error(self.pos, "cimport only allowed at module level")
5102 module_scope = env.find_module(self.module_name, self.pos)
5103 if "." in self.module_name:
5104 names = [EncodedString(name) for name in self.module_name.split(".")]
5106 top_module_scope = env.context.find_submodule(top_name)
5107 module_scope = top_module_scope
5108 for name in names[1:]:
5109 submodule_scope = module_scope.find_submodule(name)
5110 module_scope.declare_module(name, submodule_scope, self.pos)
5111 module_scope = submodule_scope
5113 env.declare_module(self.as_name, module_scope, self.pos)
5115 env.declare_module(top_name, top_module_scope, self.pos)
5117 name = self.as_name or self.module_name
5118 env.declare_module(name, module_scope, self.pos)
5120 def analyse_expressions(self, env):
5123 def generate_execution_code(self, code):
5127 class FromCImportStatNode(StatNode):
5128 # from ... cimport statement
5130 # module_name string Qualified name of module
5131 # imported_names [(pos, name, as_name, kind)] Names to be imported
5135 def analyse_declarations(self, env):
5136 if not env.is_module_scope:
5137 error(self.pos, "cimport only allowed at module level")
5139 module_scope = env.find_module(self.module_name, self.pos)
5140 env.add_imported_module(module_scope)
5141 for pos, name, as_name, kind in self.imported_names:
5143 for local_name, entry in module_scope.entries.items():
5144 env.add_imported_entry(local_name, entry, pos)
5146 entry = module_scope.lookup(name)
5148 if kind and not self.declaration_matches(entry, kind):
5149 entry.redeclared(pos)
5151 if kind == 'struct' or kind == 'union':
5152 entry = module_scope.declare_struct_or_union(name,
5153 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5154 elif kind == 'class':
5155 entry = module_scope.declare_c_class(name, pos = pos,
5156 module_name = self.module_name)
5158 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5159 if submodule_scope.parent_module is module_scope:
5160 env.declare_module(as_name or name, submodule_scope, self.pos)
5162 error(pos, "Name '%s' not declared in module '%s'"
5163 % (name, self.module_name))
5166 local_name = as_name or name
5167 env.add_imported_entry(local_name, entry, pos)
5169 def declaration_matches(self, entry, kind):
5170 if not entry.is_type:
5174 if not type.is_extension_type:
5177 if not type.is_struct_or_union:
5179 if kind != type.kind:
5183 def analyse_expressions(self, env):
5186 def generate_execution_code(self, code):
5190 class FromImportStatNode(StatNode):
5191 # from ... import statement
5194 # items [(string, NameNode)]
5195 # interned_items [(string, NameNode, ExprNode)]
5196 # item PyTempNode used internally
5197 # import_star boolean used internally
5199 child_attrs = ["module"]
5202 def analyse_declarations(self, env):
5203 for name, target in self.items:
5205 if not env.is_module_scope:
5206 error(self.pos, "import * only allowed at module level")
5208 env.has_import_star = 1
5209 self.import_star = 1
5211 target.analyse_target_declaration(env)
5213 def analyse_expressions(self, env):
5215 self.module.analyse_expressions(env)
5216 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5217 self.interned_items = []
5218 for name, target in self.items:
5220 for _, entry in env.entries.items():
5221 if not entry.is_type and entry.type.is_extension_type:
5222 env.use_utility_code(ExprNodes.type_test_utility_code)
5225 entry = env.lookup(target.name)
5226 # check whether or not entry is already cimported
5227 if (entry.is_type and entry.type.name == name
5228 and hasattr(entry.type, 'module_name')):
5229 if entry.type.module_name == self.module.module_name.value:
5230 # cimported with absolute name
5233 # cimported with relative name
5234 module = env.find_module(self.module.module_name.value,
5236 if entry.type.module_name == module.qualified_name:
5238 except AttributeError:
5240 target.analyse_target_expression(env, None)
5241 if target.type is py_object_type:
5244 coerced_item = self.item.coerce_to(target.type, env)
5245 self.interned_items.append((name, target, coerced_item))
5247 def generate_execution_code(self, code):
5248 self.module.generate_evaluation_code(code)
5249 if self.import_star:
5251 'if (%s(%s) < 0) %s;' % (
5253 self.module.py_result(),
5254 code.error_goto(self.pos)))
5255 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5256 self.item.set_cname(item_temp)
5257 for name, target, coerced_item in self.interned_items:
5258 cname = code.intern_identifier(name)
5260 '%s = PyObject_GetAttr(%s, %s); %s' % (
5262 self.module.py_result(),
5264 code.error_goto_if_null(item_temp, self.pos)))
5265 code.put_gotref(item_temp)
5266 if coerced_item is None:
5267 target.generate_assignment_code(self.item, code)
5269 coerced_item.allocate_temp_result(code)
5270 coerced_item.generate_result_code(code)
5271 target.generate_assignment_code(coerced_item, code)
5272 code.put_decref_clear(item_temp, py_object_type)
5273 code.funcstate.release_temp(item_temp)
5274 self.module.generate_disposal_code(code)
5275 self.module.free_temps(code)
5279 #------------------------------------------------------------------------------------
5281 # Runtime support code
5283 #------------------------------------------------------------------------------------
5285 utility_function_predeclarations = \
5287 /* inline attribute */
5288 #ifndef CYTHON_INLINE
5289 #if defined(__GNUC__)
5290 #define CYTHON_INLINE __inline__
5291 #elif defined(_MSC_VER)
5292 #define CYTHON_INLINE __inline
5293 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5294 #define CYTHON_INLINE inline
5296 #define CYTHON_INLINE
5300 /* unused attribute */
5301 #ifndef CYTHON_UNUSED
5302 # if defined(__GNUC__)
5303 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5304 # define CYTHON_UNUSED __attribute__ ((__unused__))
5306 # define CYTHON_UNUSED
5308 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5309 # define CYTHON_UNUSED __attribute__ ((__unused__))
5311 # define CYTHON_UNUSED
5315 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*/
5319 if Options.gcc_branch_hints:
5320 branch_prediction_macros = \
5323 /* Test for GCC > 2.95 */
5324 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5325 #define likely(x) __builtin_expect(!!(x), 1)
5326 #define unlikely(x) __builtin_expect(!!(x), 0)
5327 #else /* __GNUC__ > 2 ... */
5328 #define likely(x) (x)
5329 #define unlikely(x) (x)
5330 #endif /* __GNUC__ > 2 ... */
5331 #else /* __GNUC__ */
5332 #define likely(x) (x)
5333 #define unlikely(x) (x)
5334 #endif /* __GNUC__ */
5337 branch_prediction_macros = \
5339 #define likely(x) (x)
5340 #define unlikely(x) (x)
5343 #get_name_predeclaration = \
5344 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5346 #get_name_interned_predeclaration = \
5347 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5349 #------------------------------------------------------------------------------------
5351 printing_utility_code = UtilityCode(
5353 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5354 #if PY_MAJOR_VERSION >= 3
5355 static PyObject* %s = 0;
5356 static PyObject* %s = 0;
5358 """ % (Naming.print_function, Naming.print_function_kwargs),
5360 #if PY_MAJOR_VERSION >= 3
5364 """ % (Naming.print_function, Naming.print_function_kwargs),
5366 #if PY_MAJOR_VERSION < 3
5367 static PyObject *__Pyx_GetStdout(void) {
5368 PyObject *f = PySys_GetObject((char *)"stdout");
5370 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5375 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5380 if (!(f = __Pyx_GetStdout()))
5383 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5384 if (PyFile_SoftSpace(f, 1)) {
5385 if (PyFile_WriteString(" ", f) < 0)
5388 v = PyTuple_GET_ITEM(arg_tuple, i);
5389 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5391 if (PyString_Check(v)) {
5392 char *s = PyString_AsString(v);
5393 Py_ssize_t len = PyString_Size(v);
5395 isspace(Py_CHARMASK(s[len-1])) &&
5397 PyFile_SoftSpace(f, 0);
5401 if (PyFile_WriteString("\n", f) < 0)
5403 PyFile_SoftSpace(f, 0);
5408 #else /* Python 3 has a print function */
5410 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5411 PyObject* kwargs = 0;
5412 PyObject* result = 0;
5413 PyObject* end_string;
5414 if (unlikely(!%(PRINT_FUNCTION)s)) {
5415 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5416 if (!%(PRINT_FUNCTION)s)
5420 kwargs = PyDict_New();
5421 if (unlikely(!kwargs))
5423 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5426 end_string = PyUnicode_FromStringAndSize(" ", 1);
5427 if (unlikely(!end_string))
5429 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5430 Py_DECREF(end_string);
5433 Py_DECREF(end_string);
5435 } else if (!newline) {
5436 if (unlikely(!%(PRINT_KWARGS)s)) {
5437 %(PRINT_KWARGS)s = PyDict_New();
5438 if (unlikely(!%(PRINT_KWARGS)s))
5440 end_string = PyUnicode_FromStringAndSize(" ", 1);
5441 if (unlikely(!end_string))
5443 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5444 Py_DECREF(end_string);
5447 Py_DECREF(end_string);
5449 kwargs = %(PRINT_KWARGS)s;
5451 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5452 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5459 if (kwargs != %(PRINT_KWARGS)s)
5465 """ % {'BUILTINS' : Naming.builtins_cname,
5466 'PRINT_FUNCTION' : Naming.print_function,
5467 'PRINT_KWARGS' : Naming.print_function_kwargs}
5471 printing_one_utility_code = UtilityCode(
5473 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5476 #if PY_MAJOR_VERSION < 3
5478 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5480 if (!(f = __Pyx_GetStdout()))
5483 if (PyFile_SoftSpace(f, 0)) {
5484 if (PyFile_WriteString(" ", f) < 0)
5487 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5489 if (PyFile_WriteString("\n", f) < 0)
5492 /* the line below is just to avoid compiler
5493 * compiler warnings about unused functions */
5494 return __Pyx_Print(f, NULL, 0);
5497 #else /* Python 3 has a print function */
5499 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5501 PyObject* arg_tuple = PyTuple_New(1);
5502 if (unlikely(!arg_tuple))
5505 PyTuple_SET_ITEM(arg_tuple, 0, o);
5506 res = __Pyx_Print(stream, arg_tuple, 1);
5507 Py_DECREF(arg_tuple);
5513 requires=[printing_utility_code])
5517 #------------------------------------------------------------------------------------
5519 # Exception raising code
5521 # Exceptions are raised by __Pyx_Raise() and stored as plain
5522 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5523 # 'except' statement, curexc_* is moved over to exc_* by
5524 # __Pyx_GetException()
5526 restore_exception_utility_code = UtilityCode(
5528 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5529 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5532 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5533 PyObject *tmp_type, *tmp_value, *tmp_tb;
5534 PyThreadState *tstate = PyThreadState_GET();
5536 tmp_type = tstate->curexc_type;
5537 tmp_value = tstate->curexc_value;
5538 tmp_tb = tstate->curexc_traceback;
5539 tstate->curexc_type = type;
5540 tstate->curexc_value = value;
5541 tstate->curexc_traceback = tb;
5542 Py_XDECREF(tmp_type);
5543 Py_XDECREF(tmp_value);
5547 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5548 PyThreadState *tstate = PyThreadState_GET();
5549 *type = tstate->curexc_type;
5550 *value = tstate->curexc_value;
5551 *tb = tstate->curexc_traceback;
5553 tstate->curexc_type = 0;
5554 tstate->curexc_value = 0;
5555 tstate->curexc_traceback = 0;
5560 # The following function is based on do_raise() from ceval.c. There
5561 # are separate versions for Python2 and Python3 as exception handling
5562 # has changed quite a lot between the two versions.
5564 raise_utility_code = UtilityCode(
5566 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5569 #if PY_MAJOR_VERSION < 3
5570 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5574 /* First, check the traceback argument, replacing None with NULL. */
5575 if (tb == Py_None) {
5579 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5580 PyErr_SetString(PyExc_TypeError,
5581 "raise: arg 3 must be a traceback or None");
5584 /* Next, replace a missing value with None */
5585 if (value == NULL) {
5589 #if PY_VERSION_HEX < 0x02050000
5590 if (!PyClass_Check(type))
5592 if (!PyType_Check(type))
5595 /* Raising an instance. The value should be a dummy. */
5596 if (value != Py_None) {
5597 PyErr_SetString(PyExc_TypeError,
5598 "instance exception may not have a separate value");
5601 /* Normalize to raise <class>, <instance> */
5604 #if PY_VERSION_HEX < 0x02050000
5605 if (PyInstance_Check(type)) {
5606 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5611 PyErr_SetString(PyExc_TypeError,
5612 "raise: exception must be an old-style class or instance");
5616 type = (PyObject*) Py_TYPE(type);
5618 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5619 PyErr_SetString(PyExc_TypeError,
5620 "raise: exception class must be a subclass of BaseException");
5626 __Pyx_ErrRestore(type, value, tb);
5635 #else /* Python 3+ */
5637 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5638 if (tb == Py_None) {
5640 } else if (tb && !PyTraceBack_Check(tb)) {
5641 PyErr_SetString(PyExc_TypeError,
5642 "raise: arg 3 must be a traceback or None");
5645 if (value == Py_None)
5648 if (PyExceptionInstance_Check(type)) {
5650 PyErr_SetString(PyExc_TypeError,
5651 "instance exception may not have a separate value");
5655 type = (PyObject*) Py_TYPE(value);
5656 } else if (!PyExceptionClass_Check(type)) {
5657 PyErr_SetString(PyExc_TypeError,
5658 "raise: exception class must be a subclass of BaseException");
5662 PyErr_SetObject(type, value);
5665 PyThreadState *tstate = PyThreadState_GET();
5666 PyObject* tmp_tb = tstate->curexc_traceback;
5669 tstate->curexc_traceback = tb;
5679 requires=[restore_exception_utility_code])
5681 #------------------------------------------------------------------------------------
5683 get_exception_utility_code = UtilityCode(
5685 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5688 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5689 PyObject *local_type, *local_value, *local_tb;
5690 PyObject *tmp_type, *tmp_value, *tmp_tb;
5691 PyThreadState *tstate = PyThreadState_GET();
5692 local_type = tstate->curexc_type;
5693 local_value = tstate->curexc_value;
5694 local_tb = tstate->curexc_traceback;
5695 tstate->curexc_type = 0;
5696 tstate->curexc_value = 0;
5697 tstate->curexc_traceback = 0;
5698 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5699 if (unlikely(tstate->curexc_type))
5701 #if PY_MAJOR_VERSION >= 3
5702 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5706 *value = local_value;
5708 Py_INCREF(local_type);
5709 Py_INCREF(local_value);
5710 Py_INCREF(local_tb);
5711 tmp_type = tstate->exc_type;
5712 tmp_value = tstate->exc_value;
5713 tmp_tb = tstate->exc_traceback;
5714 tstate->exc_type = local_type;
5715 tstate->exc_value = local_value;
5716 tstate->exc_traceback = local_tb;
5717 /* Make sure tstate is in a consistent state when we XDECREF
5718 these objects (XDECREF may run arbitrary code). */
5719 Py_XDECREF(tmp_type);
5720 Py_XDECREF(tmp_value);
5727 Py_XDECREF(local_type);
5728 Py_XDECREF(local_value);
5729 Py_XDECREF(local_tb);
5735 #------------------------------------------------------------------------------------
5737 get_exception_tuple_utility_code = UtilityCode(proto="""
5738 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5740 # I doubt that calling __Pyx_GetException() here is correct as it moves
5741 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5742 # exception handlers later on from receiving it.
5744 static PyObject *__Pyx_GetExceptionTuple(void) {
5745 PyObject *type = NULL, *value = NULL, *tb = NULL;
5746 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5747 PyObject* exc_info = PyTuple_New(3);
5752 PyTuple_SET_ITEM(exc_info, 0, type);
5753 PyTuple_SET_ITEM(exc_info, 1, value);
5754 PyTuple_SET_ITEM(exc_info, 2, tb);
5761 requires=[get_exception_utility_code])
5763 #------------------------------------------------------------------------------------
5765 reset_exception_utility_code = UtilityCode(
5767 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5768 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5771 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5772 PyThreadState *tstate = PyThreadState_GET();
5773 *type = tstate->exc_type;
5774 *value = tstate->exc_value;
5775 *tb = tstate->exc_traceback;
5781 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5782 PyObject *tmp_type, *tmp_value, *tmp_tb;
5783 PyThreadState *tstate = PyThreadState_GET();
5784 tmp_type = tstate->exc_type;
5785 tmp_value = tstate->exc_value;
5786 tmp_tb = tstate->exc_traceback;
5787 tstate->exc_type = type;
5788 tstate->exc_value = value;
5789 tstate->exc_traceback = tb;
5790 Py_XDECREF(tmp_type);
5791 Py_XDECREF(tmp_value);
5796 #------------------------------------------------------------------------------------
5798 arg_type_test_utility_code = UtilityCode(
5800 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5801 const char *name, int exact); /*proto*/
5804 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5805 const char *name, int exact)
5808 PyErr_Format(PyExc_SystemError, "Missing type object");
5811 if (none_allowed && obj == Py_None) return 1;
5813 if (Py_TYPE(obj) == type) return 1;
5816 if (PyObject_TypeCheck(obj, type)) return 1;
5818 PyErr_Format(PyExc_TypeError,
5819 "Argument '%s' has incorrect type (expected %s, got %s)",
5820 name, type->tp_name, Py_TYPE(obj)->tp_name);
5825 #------------------------------------------------------------------------------------
5827 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5828 # many or too few positional arguments were found. This handles
5829 # Py_ssize_t formatting correctly.
5831 raise_argtuple_invalid_utility_code = UtilityCode(
5833 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5834 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5837 static void __Pyx_RaiseArgtupleInvalid(
5838 const char* func_name,
5842 Py_ssize_t num_found)
5844 Py_ssize_t num_expected;
5845 const char *number, *more_or_less;
5847 if (num_found < num_min) {
5848 num_expected = num_min;
5849 more_or_less = "at least";
5851 num_expected = num_max;
5852 more_or_less = "at most";
5855 more_or_less = "exactly";
5857 number = (num_expected == 1) ? "" : "s";
5858 PyErr_Format(PyExc_TypeError,
5859 #if PY_VERSION_HEX < 0x02050000
5860 "%s() takes %s %d positional argument%s (%d given)",
5862 "%s() takes %s %zd positional argument%s (%zd given)",
5864 func_name, more_or_less, num_expected, number, num_found);
5868 raise_keyword_required_utility_code = UtilityCode(
5870 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5873 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5874 const char* func_name,
5877 PyErr_Format(PyExc_TypeError,
5878 #if PY_MAJOR_VERSION >= 3
5879 "%s() needs keyword-only argument %U", func_name, kw_name);
5881 "%s() needs keyword-only argument %s", func_name,
5882 PyString_AS_STRING(kw_name));
5887 raise_double_keywords_utility_code = UtilityCode(
5889 static void __Pyx_RaiseDoubleKeywordsError(
5890 const char* func_name, PyObject* kw_name); /*proto*/
5893 static void __Pyx_RaiseDoubleKeywordsError(
5894 const char* func_name,
5897 PyErr_Format(PyExc_TypeError,
5898 #if PY_MAJOR_VERSION >= 3
5899 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5901 "%s() got multiple values for keyword argument '%s'", func_name,
5902 PyString_AS_STRING(kw_name));
5907 #------------------------------------------------------------------------------------
5909 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5910 # were passed to a function, or if any keywords were passed to a
5911 # function that does not accept them.
5913 keyword_string_check_utility_code = UtilityCode(
5915 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5916 const char* function_name, int kw_allowed); /*proto*/
5919 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5921 const char* function_name,
5926 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5927 #if PY_MAJOR_VERSION < 3
5928 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5930 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5932 goto invalid_keyword_type;
5934 if ((!kw_allowed) && unlikely(key))
5935 goto invalid_keyword;
5937 invalid_keyword_type:
5938 PyErr_Format(PyExc_TypeError,
5939 "%s() keywords must be strings", function_name);
5942 PyErr_Format(PyExc_TypeError,
5943 #if PY_MAJOR_VERSION < 3
5944 "%s() got an unexpected keyword argument '%s'",
5945 function_name, PyString_AsString(key));
5947 "%s() got an unexpected keyword argument '%U'",
5948 function_name, key);
5954 #------------------------------------------------------------------------------------
5956 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5957 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5958 # keywords will raise an invalid keyword error.
5960 # Three kinds of errors are checked: 1) non-string keywords, 2)
5961 # unexpected keywords and 3) overlap with positional arguments.
5963 # If num_posargs is greater 0, it denotes the number of positional
5964 # arguments that were passed and that must therefore not appear
5965 # amongst the keywords as well.
5967 # This method does not check for required keyword arguments.
5970 parse_keywords_utility_code = UtilityCode(
5972 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5973 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5974 const char* function_name); /*proto*/
5977 static int __Pyx_ParseOptionalKeywords(
5979 PyObject **argnames[],
5982 Py_ssize_t num_pos_args,
5983 const char* function_name)
5985 PyObject *key = 0, *value = 0;
5988 PyObject*** first_kw_arg = argnames + num_pos_args;
5990 while (PyDict_Next(kwds, &pos, &key, &value)) {
5991 name = first_kw_arg;
5992 while (*name && (**name != key)) name++;
5994 values[name-argnames] = value;
5996 #if PY_MAJOR_VERSION < 3
5997 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5999 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6001 goto invalid_keyword_type;
6003 for (name = first_kw_arg; *name; name++) {
6004 #if PY_MAJOR_VERSION >= 3
6005 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6006 PyUnicode_Compare(**name, key) == 0) break;
6008 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6009 _PyString_Eq(**name, key)) break;
6013 values[name-argnames] = value;
6015 /* unexpected keyword found */
6016 for (name=argnames; name != first_kw_arg; name++) {
6017 if (**name == key) goto arg_passed_twice;
6018 #if PY_MAJOR_VERSION >= 3
6019 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6020 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6022 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6023 _PyString_Eq(**name, key)) goto arg_passed_twice;
6027 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6029 goto invalid_keyword;
6037 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6039 invalid_keyword_type:
6040 PyErr_Format(PyExc_TypeError,
6041 "%s() keywords must be strings", function_name);
6044 PyErr_Format(PyExc_TypeError,
6045 #if PY_MAJOR_VERSION < 3
6046 "%s() got an unexpected keyword argument '%s'",
6047 function_name, PyString_AsString(key));
6049 "%s() got an unexpected keyword argument '%U'",
6050 function_name, key);
6057 #------------------------------------------------------------------------------------
6059 traceback_utility_code = UtilityCode(
6061 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6064 #include "compile.h"
6065 #include "frameobject.h"
6066 #include "traceback.h"
6068 static void __Pyx_AddTraceback(const char *funcname) {
6069 PyObject *py_srcfile = 0;
6070 PyObject *py_funcname = 0;
6071 PyObject *py_globals = 0;
6072 PyCodeObject *py_code = 0;
6073 PyFrameObject *py_frame = 0;
6075 #if PY_MAJOR_VERSION < 3
6076 py_srcfile = PyString_FromString(%(FILENAME)s);
6078 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6080 if (!py_srcfile) goto bad;
6082 #if PY_MAJOR_VERSION < 3
6083 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6085 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6089 #if PY_MAJOR_VERSION < 3
6090 py_funcname = PyString_FromString(funcname);
6092 py_funcname = PyUnicode_FromString(funcname);
6095 if (!py_funcname) goto bad;
6096 py_globals = PyModule_GetDict(%(GLOBALS)s);
6097 if (!py_globals) goto bad;
6098 py_code = PyCode_New(
6099 0, /*int argcount,*/
6100 #if PY_MAJOR_VERSION >= 3
6101 0, /*int kwonlyargcount,*/
6104 0, /*int stacksize,*/
6106 %(EMPTY_BYTES)s, /*PyObject *code,*/
6107 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6108 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6109 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6110 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6111 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6112 py_srcfile, /*PyObject *filename,*/
6113 py_funcname, /*PyObject *name,*/
6114 %(LINENO)s, /*int firstlineno,*/
6115 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6117 if (!py_code) goto bad;
6118 py_frame = PyFrame_New(
6119 PyThreadState_GET(), /*PyThreadState *tstate,*/
6120 py_code, /*PyCodeObject *code,*/
6121 py_globals, /*PyObject *globals,*/
6122 0 /*PyObject *locals*/
6124 if (!py_frame) goto bad;
6125 py_frame->f_lineno = %(LINENO)s;
6126 PyTraceBack_Here(py_frame);
6128 Py_XDECREF(py_srcfile);
6129 Py_XDECREF(py_funcname);
6130 Py_XDECREF(py_code);
6131 Py_XDECREF(py_frame);
6134 'FILENAME': Naming.filename_cname,
6135 'LINENO': Naming.lineno_cname,
6136 'CFILENAME': Naming.cfilenm_cname,
6137 'CLINENO': Naming.clineno_cname,
6138 'GLOBALS': Naming.module_cname,
6139 'EMPTY_TUPLE' : Naming.empty_tuple,
6140 'EMPTY_BYTES' : Naming.empty_bytes,
6143 #------------------------------------------------------------------------------------
6145 unraisable_exception_utility_code = UtilityCode(
6147 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6150 static void __Pyx_WriteUnraisable(const char *name) {
6151 PyObject *old_exc, *old_val, *old_tb;
6153 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6154 #if PY_MAJOR_VERSION < 3
6155 ctx = PyString_FromString(name);
6157 ctx = PyUnicode_FromString(name);
6159 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6161 PyErr_WriteUnraisable(Py_None);
6163 PyErr_WriteUnraisable(ctx);
6168 requires=[restore_exception_utility_code])
6170 #------------------------------------------------------------------------------------
6172 set_vtable_utility_code = UtilityCode(
6174 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6177 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6178 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6179 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6181 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6185 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6195 #------------------------------------------------------------------------------------
6197 get_vtable_utility_code = UtilityCode(
6199 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6202 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6203 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6206 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6207 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6209 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6211 if (!*(void **)vtabptr)
6221 #------------------------------------------------------------------------------------
6223 init_string_tab_utility_code = UtilityCode(
6225 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6228 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6230 #if PY_MAJOR_VERSION < 3
6231 if (t->is_unicode) {
6232 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6233 } else if (t->intern) {
6234 *t->p = PyString_InternFromString(t->s);
6236 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6238 #else /* Python 3+ has unicode identifiers */
6239 if (t->is_unicode | t->is_str) {
6241 *t->p = PyUnicode_InternFromString(t->s);
6242 } else if (t->encoding) {
6243 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6245 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6248 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6259 #------------------------------------------------------------------------------------
6261 force_init_threads_utility_code = UtilityCode(
6263 #ifndef __PYX_FORCE_INIT_THREADS
6264 #if PY_VERSION_HEX < 0x02040200
6265 #define __PYX_FORCE_INIT_THREADS 1
6267 #define __PYX_FORCE_INIT_THREADS 0
6272 #------------------------------------------------------------------------------------
6274 # Note that cPython ignores PyTrace_EXCEPTION,
6275 # but maybe some other profilers don't.
6277 profile_utility_code = UtilityCode(proto="""
6278 #ifndef CYTHON_PROFILE
6279 #define CYTHON_PROFILE 1
6282 #ifndef CYTHON_PROFILE_REUSE_FRAME
6283 #define CYTHON_PROFILE_REUSE_FRAME 0
6288 #include "compile.h"
6289 #include "frameobject.h"
6290 #include "traceback.h"
6292 #if CYTHON_PROFILE_REUSE_FRAME
6293 #define CYTHON_FRAME_MODIFIER static
6294 #define CYTHON_FRAME_DEL
6296 #define CYTHON_FRAME_MODIFIER
6297 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6300 #define __Pyx_TraceDeclarations \\
6301 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6302 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6303 int __Pyx_use_tracing = 0;
6305 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6306 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6307 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6310 #define __Pyx_TraceException() \\
6311 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6312 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6314 PyThreadState_GET()->c_profilefunc( \\
6315 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6316 Py_DECREF(exc_info); \\
6320 #define __Pyx_TraceReturn(result) \\
6321 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6322 PyThreadState_GET()->c_profilefunc( \\
6323 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6324 CYTHON_FRAME_DEL; \\
6327 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6328 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6332 #define __Pyx_TraceDeclarations
6333 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6334 #define __Pyx_TraceException()
6335 #define __Pyx_TraceReturn(result)
6337 #endif /* CYTHON_PROFILE */
6340 "FRAME": Naming.frame_cname,
6341 "FRAME_CODE": Naming.frame_code_cname,
6347 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6348 PyFrameObject** frame,
6349 const char *funcname,
6350 const char *srcfile,
6352 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6353 if (*code == NULL) {
6354 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6355 if (*code == NULL) return 0;
6357 *frame = PyFrame_New(
6358 PyThreadState_GET(), /*PyThreadState *tstate*/
6359 *code, /*PyCodeObject *code*/
6360 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6361 0 /*PyObject *locals*/
6363 if (*frame == NULL) return 0;
6366 (*frame)->f_tstate = PyThreadState_GET();
6368 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6371 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6372 PyObject *py_srcfile = 0;
6373 PyObject *py_funcname = 0;
6374 PyCodeObject *py_code = 0;
6376 #if PY_MAJOR_VERSION < 3
6377 py_funcname = PyString_FromString(funcname);
6378 py_srcfile = PyString_FromString(srcfile);
6380 py_funcname = PyUnicode_FromString(funcname);
6381 py_srcfile = PyUnicode_FromString(srcfile);
6383 if (!py_funcname | !py_srcfile) goto bad;
6385 py_code = PyCode_New(
6386 0, /*int argcount,*/
6387 #if PY_MAJOR_VERSION >= 3
6388 0, /*int kwonlyargcount,*/
6391 0, /*int stacksize,*/
6393 %(EMPTY_BYTES)s, /*PyObject *code,*/
6394 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6395 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6396 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6397 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6398 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6399 py_srcfile, /*PyObject *filename,*/
6400 py_funcname, /*PyObject *name,*/
6401 firstlineno, /*int firstlineno,*/
6402 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6406 Py_XDECREF(py_srcfile);
6407 Py_XDECREF(py_funcname);
6412 #endif /* CYTHON_PROFILE */
6414 'EMPTY_TUPLE' : Naming.empty_tuple,
6415 'EMPTY_BYTES' : Naming.empty_bytes,
6416 "MODULE": Naming.module_cname,