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