3 # Pyrex - Parse tree nodes
6 import sys, os, time, copy
12 from sets import Set as set
16 from Errors import error, warning, InternalError
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
30 absolute_path_length = 0
32 def relative_position(pos):
34 We embed the relative filename in the generated C file, since we
35 don't want to have to regnerate and compile all the source code
36 whenever the Python install directory moves (which could happen,
37 e.g,. when distributing binaries.)
40 a position tuple -- (absolute filename, line number column position)
48 global absolute_path_length
49 if absolute_path_length==0:
50 absolute_path_length = len(os.path.abspath(os.getcwd()))
51 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
53 def embed_position(pos, docstring):
54 if not Options.embed_pos_in_docstring:
56 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
59 return EncodedString(pos_line)
61 # make sure we can encode the filename in the docstring encoding
62 # otherwise make the docstring a unicode string
63 encoding = docstring.encoding
64 if encoding is not None:
66 encoded_bytes = pos_line.encode(encoding)
67 except UnicodeEncodeError:
71 # reuse the string encoding of the original docstring
72 doc = EncodedString(pos_line)
74 doc = EncodedString(pos_line + u'\n' + docstring)
75 doc.encoding = encoding
79 from Code import CCodeWriter
80 from types import FunctionType
82 def write_func_call(func):
84 if len(args) > 1 and isinstance(args[1], CCodeWriter):
85 # here we annotate the code with this function call
86 # but only if new code is generated
88 marker = ' /* %s -> %s.%s %s */' % (
89 ' ' * code.call_level,
90 node.__class__.__name__,
93 pristine = code.buffer.stream.tell()
95 start = code.buffer.stream.tell()
97 res = func(*args, **kwds)
99 if start == code.buffer.stream.tell():
100 code.buffer.stream.seek(pristine)
102 marker = marker.replace('->', '<-')
106 return func(*args, **kwds)
109 class VerboseCodeWriter(type):
110 # Set this as a metaclass to trace function calls in code.
111 # This slows down code generation and makes much larger files.
112 def __new__(cls, name, bases, attrs):
114 for mname, m in attrs.items():
115 if isinstance(m, FunctionType):
116 attrs[mname] = write_func_call(m)
117 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
121 # pos (string, int, int) Source file position
122 # is_name boolean Is a NameNode
123 # is_literal boolean Is a ConstNode
125 if DebugFlags.debug_trace_code_generation:
126 __metaclass__ = VerboseCodeWriter
132 # All descandants should set child_attrs to a list of the attributes
133 # containing nodes considered "children" in the tree. Each such attribute
134 # can either contain a single node or a list of nodes. See Visitor.py.
137 def __init__(self, pos, **kw):
139 self.__dict__.update(kw)
141 gil_message = "Operation"
145 def gil_error(self, env=None):
146 error(self.pos, "%s not allowed without gil" % self.gil_message)
148 cpp_message = "Operation"
150 def cpp_check(self, env):
155 error(self.pos, "%s only allowed in c++" % self.cpp_message)
157 def clone_node(self):
158 """Clone the node. This is defined as a shallow copy, except for member lists
159 amongst the child attributes (from get_child_accessors) which are also
160 copied. Lists containing child nodes are thus seen as a way for the node
161 to hold multiple children directly; the list is not treated as a seperate
162 level in the tree."""
163 result = copy.copy(self)
164 for attrname in result.child_attrs:
165 value = getattr(result, attrname)
166 if isinstance(value, list):
167 setattr(result, attrname, [x for x in value])
172 # There are 4 phases of parse tree processing, applied in order to
173 # all the statements in a given scope-block:
175 # (0) analyse_control_flow
176 # Create the control flow tree into which state can be asserted and
179 # (1) analyse_declarations
180 # Make symbol table entries for all declarations at the current
181 # level, both explicit (def, cdef, etc.) and implicit (assignment
182 # to an otherwise undeclared name).
184 # (2) analyse_expressions
185 # Determine the result types of expressions and fill in the
186 # 'type' attribute of each ExprNode. Insert coercion nodes into the
187 # tree where needed to convert to and from Python objects.
188 # Allocate temporary locals for intermediate results. Fill
189 # in the 'result_code' attribute of each ExprNode with a C code
193 # Emit C code for all declarations, statements and expressions.
194 # Recursively applies the 3 processing phases to the bodies of
198 def analyse_control_flow(self, env):
201 def analyse_declarations(self, env):
204 def analyse_expressions(self, env):
205 raise InternalError("analyse_expressions not implemented for %s" % \
206 self.__class__.__name__)
208 def generate_code(self, code):
209 raise InternalError("generate_code not implemented for %s" % \
210 self.__class__.__name__)
212 def annotate(self, code):
213 # mro does the wrong thing
214 if isinstance(self, BlockNode):
215 self.body.annotate(code)
220 except AttributeError:
222 if not self.child_attrs:
225 for attr in self.child_attrs:
226 child = getattr(self, attr)
227 # Sometimes lists, sometimes nodes
230 elif isinstance(child, list):
232 pos = max(pos, c.end_pos())
234 pos = max(pos, child.end_pos())
238 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
240 return "<...nesting level cutoff...>"
241 if encountered is None:
243 if id(self) in encountered:
244 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
245 encountered.add(id(self))
247 def dump_child(x, level):
248 if isinstance(x, Node):
249 return x.dump(level, filter_out, cutoff-1, encountered)
250 elif isinstance(x, list):
251 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
256 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
258 return "<%s (%d)>" % (self.__class__.__name__, id(self))
261 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
262 for key, value in attrs:
263 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
264 res += "%s>" % indent
267 class CompilerDirectivesNode(Node):
269 Sets compiler directives for the children nodes
271 # directives {string:value} A dictionary holding the right value for
272 # *all* possible directives.
274 child_attrs = ["body"]
276 def analyse_control_flow(self, env):
278 env.directives = self.directives
279 self.body.analyse_control_flow(env)
282 def analyse_declarations(self, env):
284 env.directives = self.directives
285 self.body.analyse_declarations(env)
288 def analyse_expressions(self, env):
290 env.directives = self.directives
291 self.body.analyse_expressions(env)
294 def generate_function_definitions(self, env, code):
295 env_old = env.directives
296 code_old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.generate_function_definitions(env, code)
299 env.directives = env_old
300 code.globalstate.directives = code_old
302 def generate_execution_code(self, code):
303 old = code.globalstate.directives
304 code.globalstate.directives = self.directives
305 self.body.generate_execution_code(code)
306 code.globalstate.directives = old
308 def annotate(self, code):
309 old = code.globalstate.directives
310 code.globalstate.directives = self.directives
311 self.body.annotate(code)
312 code.globalstate.directives = old
314 class BlockNode(object):
315 # Mixin class for nodes representing a declaration block.
317 def generate_cached_builtins_decls(self, env, code):
318 entries = env.global_scope().undeclared_cached_builtins
319 for entry in entries:
320 code.globalstate.add_cached_builtin_decl(entry)
324 class StatListNode(Node):
325 # stats a list of StatNode
327 child_attrs = ["stats"]
329 def create_analysed(pos, env, *args, **kw):
330 node = StatListNode(pos, *args, **kw)
331 return node # No node-specific analysis necesarry
332 create_analysed = staticmethod(create_analysed)
334 def analyse_control_flow(self, env):
335 for stat in self.stats:
336 stat.analyse_control_flow(env)
338 def analyse_declarations(self, env):
339 #print "StatListNode.analyse_declarations" ###
340 for stat in self.stats:
341 stat.analyse_declarations(env)
343 def analyse_expressions(self, env):
344 #print "StatListNode.analyse_expressions" ###
345 for stat in self.stats:
346 stat.analyse_expressions(env)
348 def generate_function_definitions(self, env, code):
349 #print "StatListNode.generate_function_definitions" ###
350 for stat in self.stats:
351 stat.generate_function_definitions(env, code)
353 def generate_execution_code(self, code):
354 #print "StatListNode.generate_execution_code" ###
355 for stat in self.stats:
356 code.mark_pos(stat.pos)
357 stat.generate_execution_code(code)
359 def annotate(self, code):
360 for stat in self.stats:
364 class StatNode(Node):
366 # Code generation for statements is split into the following subphases:
368 # (1) generate_function_definitions
369 # Emit C code for the definitions of any structs,
370 # unions, enums and functions defined in the current
373 # (2) generate_execution_code
374 # Emit C code for executable statements.
377 def generate_function_definitions(self, env, code):
380 def generate_execution_code(self, code):
381 raise InternalError("generate_execution_code not implemented for %s" % \
382 self.__class__.__name__)
385 class CDefExternNode(StatNode):
386 # include_file string or None
389 child_attrs = ["body"]
391 def analyse_declarations(self, env):
392 if self.include_file:
393 env.add_include_file(self.include_file)
394 old_cinclude_flag = env.in_cinclude
396 self.body.analyse_declarations(env)
397 env.in_cinclude = old_cinclude_flag
399 def analyse_expressions(self, env):
402 def generate_execution_code(self, code):
405 def annotate(self, code):
406 self.body.annotate(code)
409 class CDeclaratorNode(Node):
410 # Part of a C declaration.
412 # Processing during analyse_declarations phase:
415 # Returns (name, type) pair where name is the
416 # CNameDeclaratorNode of the name being declared
417 # and type is the type it is being declared as.
419 # calling_convention string Calling convention of CFuncDeclaratorNode
420 # for which this is a base
424 calling_convention = ""
427 class CNameDeclaratorNode(CDeclaratorNode):
428 # name string The Pyrex name being declared
429 # cname string or None C name, if specified
430 # default ExprNode or None the value assigned on declaration
432 child_attrs = ['default']
436 def analyse(self, base_type, env, nonempty = 0):
437 if nonempty and self.name == '':
438 # May have mistaken the name for the type.
439 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440 error(self.pos, "Missing argument name")
441 elif base_type.is_void:
442 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
444 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445 base_type = py_object_type
446 self.type = base_type
447 return self, base_type
449 class CPtrDeclaratorNode(CDeclaratorNode):
450 # base CDeclaratorNode
452 child_attrs = ["base"]
454 def analyse(self, base_type, env, nonempty = 0):
455 if base_type.is_pyobject:
457 "Pointer base type cannot be a Python object")
458 ptr_type = PyrexTypes.c_ptr_type(base_type)
459 return self.base.analyse(ptr_type, env, nonempty = nonempty)
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462 # base CDeclaratorNode
464 child_attrs = ["base"]
466 def analyse(self, base_type, env, nonempty = 0):
467 if base_type.is_pyobject:
469 "Reference base type cannot be a Python object")
470 ref_type = PyrexTypes.c_ref_type(base_type)
471 return self.base.analyse(ref_type, env, nonempty = nonempty)
473 class CArrayDeclaratorNode(CDeclaratorNode):
474 # base CDeclaratorNode
477 child_attrs = ["base", "dimension"]
479 def analyse(self, base_type, env, nonempty = 0):
480 if base_type.is_cpp_class:
481 from ExprNodes import TupleNode
482 if isinstance(self.dimension, TupleNode):
483 args = self.dimension.args
485 args = self.dimension,
486 values = [v.analyse_as_type(env) for v in args]
488 ix = values.index(None)
489 error(args[ix].pos, "Template parameter not a type.")
491 base_type = base_type.specialize_here(self.pos, values)
492 return self.base.analyse(base_type, env, nonempty = nonempty)
494 self.dimension.analyse_const_expression(env)
495 if not self.dimension.type.is_int:
496 error(self.dimension.pos, "Array dimension not integer")
497 size = self.dimension.get_constant_c_result_code()
506 if not base_type.is_complete():
508 "Array element type '%s' is incomplete" % base_type)
509 if base_type.is_pyobject:
511 "Array element cannot be a Python object")
512 if base_type.is_cfunction:
514 "Array element cannot be a function")
515 array_type = PyrexTypes.c_array_type(base_type, size)
516 return self.base.analyse(array_type, env, nonempty = nonempty)
519 class CFuncDeclaratorNode(CDeclaratorNode):
520 # base CDeclaratorNode
521 # args [CArgDeclNode]
522 # has_varargs boolean
523 # exception_value ConstNode
524 # exception_check boolean True if PyErr_Occurred check needed
525 # nogil boolean Can be called without gil
526 # with_gil boolean Acquire gil around function body
528 child_attrs = ["base", "args", "exception_value"]
531 optional_arg_count = 0
533 def analyse(self, return_type, env, nonempty = 0):
537 for arg_node in self.args:
538 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
539 name = name_declarator.name
540 if name_declarator.cname:
542 "Function argument cannot have C name specification")
543 # Turn *[] argument into **
545 type = PyrexTypes.c_ptr_type(type.base_type)
546 # Catch attempted C-style func(void) decl
548 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
549 func_type_args.append(
550 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
552 self.optional_arg_count += 1
553 elif self.optional_arg_count:
554 error(self.pos, "Non-default argument follows default argument")
556 if self.optional_arg_count:
557 scope = StructOrUnionScope()
558 arg_count_member = '%sn' % Naming.pyrex_prefix
559 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
560 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
561 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
562 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
563 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
568 cname = struct_cname)
569 self.op_args_struct.defined_in_pxd = 1
570 self.op_args_struct.used = 1
574 if self.exception_check == '+':
575 env.add_include_file('stdexcept')
576 if return_type.is_pyobject \
577 and (self.exception_value or self.exception_check) \
578 and self.exception_check != '+':
580 "Exception clause not allowed for function returning Python object")
582 if self.exception_value:
583 self.exception_value.analyse_const_expression(env)
584 if self.exception_check == '+':
585 self.exception_value.analyse_types(env)
586 exc_val_type = self.exception_value.type
587 if not exc_val_type.is_error and \
588 not exc_val_type.is_pyobject and \
589 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
590 error(self.exception_value.pos,
591 "Exception value must be a Python exception or cdef function with no arguments.")
592 exc_val = self.exception_value
594 if self.exception_value.analyse_const_expression(env):
595 exc_val = self.exception_value.get_constant_c_result_code()
597 raise InternalError("get_constant_c_result_code not implemented for %s" %
598 self.exception_value.__class__.__name__)
599 if not return_type.assignable_from(self.exception_value.type):
600 error(self.exception_value.pos,
601 "Exception value incompatible with function return type")
602 exc_check = self.exception_check
603 if return_type.is_array:
605 "Function cannot return an array")
606 if return_type.is_cfunction:
608 "Function cannot return a function")
609 func_type = PyrexTypes.CFuncType(
610 return_type, func_type_args, self.has_varargs,
611 optional_arg_count = self.optional_arg_count,
612 exception_value = exc_val, exception_check = exc_check,
613 calling_convention = self.base.calling_convention,
614 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
615 if self.optional_arg_count:
616 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
617 callspec = env.directives['callspec']
619 current = func_type.calling_convention
620 if current and current != callspec:
621 error(self.pos, "cannot have both '%s' and '%s' "
622 "calling conventions" % (current, callspec))
623 func_type.calling_convention = callspec
624 return self.base.analyse(func_type, env)
627 class CArgDeclNode(Node):
628 # Item in a function declaration argument list.
630 # base_type CBaseTypeNode
631 # declarator CDeclaratorNode
632 # not_none boolean Tagged with 'not None'
633 # or_none boolean Tagged with 'or None'
634 # accept_none boolean Resolved boolean for not_none/or_none
635 # default ExprNode or None
636 # default_value PyObjectConst constant for default value
637 # annotation ExprNode or None Py3 function arg annotation
638 # is_self_arg boolean Is the "self" arg of an extension type method
639 # is_type_arg boolean Is the "class" arg of an extension type classmethod
640 # is_kw_only boolean Is a keyword-only argument
642 child_attrs = ["base_type", "declarator", "default"]
648 name_declarator = None
652 def analyse(self, env, nonempty = 0):
653 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
654 if self.type is None:
655 # The parser may missinterpret names as types...
657 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
659 self.declarator.name = self.base_type.name
660 self.base_type.name = None
661 self.base_type.is_basic_c_type = False
664 could_be_name = False
665 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
666 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
667 self.declarator.name = self.base_type.arg_name
668 # The parser is unable to resolve the ambiguity of [] as part of the
669 # type (e.g. in buffers) or empty declarator (as with arrays).
670 # This is only arises for empty multi-dimensional arrays.
671 if (base_type.is_array
672 and isinstance(self.base_type, TemplatedTypeNode)
673 and isinstance(self.declarator, CArrayDeclaratorNode)):
674 declarator = self.declarator
675 while isinstance(declarator.base, CArrayDeclaratorNode):
676 declarator = declarator.base
677 declarator.base = self.base_type.array_declarator
678 base_type = base_type.base_type
679 return self.declarator.analyse(base_type, env, nonempty = nonempty)
681 return self.name_declarator, self.type
683 def calculate_default_value_code(self, code):
684 if self.default_value is None:
686 if self.default.is_literal:
687 # will not output any code, just assign the result_code
688 self.default.generate_evaluation_code(code)
689 return self.type.cast_code(self.default.result())
690 self.default_value = code.get_argument_default_const(self.type)
691 return self.default_value
693 def annotate(self, code):
695 self.default.annotate(code)
698 class CBaseTypeNode(Node):
699 # Abstract base class for C base type nodes.
701 # Processing during analyse_declarations phase:
708 def analyse_as_type(self, env):
709 return self.analyse(env)
711 class CAnalysedBaseTypeNode(Node):
716 def analyse(self, env, could_be_name = False):
719 class CSimpleBaseTypeNode(CBaseTypeNode):
721 # module_path [string] Qualifying name components
722 # is_basic_c_type boolean
726 # is_self_arg boolean Is self argument of C method
727 # ##is_type_arg boolean Is type argument of class method
730 arg_name = None # in case the argument name was interpreted as a type
732 def analyse(self, env, could_be_name = False):
733 # Return type descriptor.
734 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
736 if self.is_basic_c_type:
737 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
739 error(self.pos, "Unrecognised type modifier combination")
740 elif self.name == "object" and not self.module_path:
741 type = py_object_type
742 elif self.name is None:
743 if self.is_self_arg and env.is_c_class_scope:
744 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
745 type = env.parent_type
746 ## elif self.is_type_arg and env.is_c_class_scope:
747 ## type = Builtin.type_type
749 type = py_object_type
752 scope = env.find_imported_module(self.module_path, self.pos)
756 if scope.is_c_class_scope:
757 scope = scope.global_scope()
758 entry = scope.lookup(self.name)
759 if entry and entry.is_type:
762 if self.is_self_arg and env.is_c_class_scope:
763 type = env.parent_type
764 ## elif self.is_type_arg and env.is_c_class_scope:
765 ## type = Builtin.type_type
767 type = py_object_type
768 self.arg_name = self.name
771 if not self.name in self.templates:
772 error(self.pos, "'%s' is not a type identifier" % self.name)
773 type = PyrexTypes.TemplatePlaceholderType(self.name)
775 error(self.pos, "'%s' is not a type identifier" % self.name)
777 if not type.is_numeric or type.is_complex:
778 error(self.pos, "can only complexify c numeric types")
779 type = PyrexTypes.CComplexType(type)
780 type.create_declaration_utility_code(env)
784 return PyrexTypes.error_type
786 class CNestedBaseTypeNode(CBaseTypeNode):
787 # For C++ classes that live inside other C++ classes.
790 # base_type CBaseTypeNode
792 child_attrs = ['base_type']
794 def analyse(self, env, could_be_name = None):
795 base_type = self.base_type.analyse(env)
796 if base_type is PyrexTypes.error_type:
797 return PyrexTypes.error_type
798 if not base_type.is_cpp_class:
799 error(self.pos, "'%s' is not a valid type scope" % base_type)
800 return PyrexTypes.error_type
801 type_entry = base_type.scope.lookup_here(self.name)
802 if not type_entry or not type_entry.is_type:
803 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
804 return PyrexTypes.error_type
805 return type_entry.type
807 class TemplatedTypeNode(CBaseTypeNode):
809 # positional_args [ExprNode] List of positional arguments
810 # keyword_args DictNode Keyword arguments
811 # base_type_node CBaseTypeNode
814 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
817 child_attrs = ["base_type_node", "positional_args",
818 "keyword_args", "dtype_node"]
824 def analyse(self, env, could_be_name = False, base_type = None):
825 if base_type is None:
826 base_type = self.base_type_node.analyse(env)
827 if base_type.is_error: return base_type
829 if base_type.is_cpp_class:
831 if self.keyword_args and self.keyword_args.key_value_pairs:
832 error(self.pos, "c++ templates cannot take keyword arguments");
833 self.type = PyrexTypes.error_type
836 for template_node in self.positional_args:
837 type = template_node.analyse_as_type(env)
839 error(template_node.pos, "unknown type in template argument")
841 template_types.append(type)
842 self.type = base_type.specialize_here(self.pos, template_types)
844 elif base_type.is_pyobject:
848 options = Buffer.analyse_buffer_options(
851 self.positional_args,
853 base_type.buffer_defaults)
855 if sys.version_info[0] < 3:
856 # Py 2.x enforces byte strings as keyword arguments ...
857 options = dict([ (name.encode('ASCII'), value)
858 for name, value in options.iteritems() ])
860 self.type = PyrexTypes.BufferType(base_type, **options)
864 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
865 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
866 error(self.pos, "invalid array declaration")
867 self.type = PyrexTypes.error_type
869 # It would be nice to merge this class with CArrayDeclaratorNode,
870 # but arrays are part of the declaration, not the type...
871 if not self.positional_args:
874 dimension = self.positional_args[0]
875 self.array_declarator = CArrayDeclaratorNode(self.pos,
876 base = empty_declarator,
877 dimension = dimension)
878 self.type = self.array_declarator.analyse(base_type, env)[1]
882 class CComplexBaseTypeNode(CBaseTypeNode):
883 # base_type CBaseTypeNode
884 # declarator CDeclaratorNode
886 child_attrs = ["base_type", "declarator"]
888 def analyse(self, env, could_be_name = False):
889 base = self.base_type.analyse(env, could_be_name)
890 _, type = self.declarator.analyse(base, env)
894 class CVarDefNode(StatNode):
895 # C variable definition or forward/extern function declaration.
897 # visibility 'private' or 'public' or 'extern'
898 # base_type CBaseTypeNode
899 # declarators [CDeclaratorNode]
904 # decorators [cython.locals(...)] or None
905 # directive_locals { string : NameNode } locals defined by cython.locals(...)
907 child_attrs = ["base_type", "declarators"]
911 directive_locals = {}
913 def analyse_declarations(self, env, dest_scope = None):
916 self.dest_scope = dest_scope
917 base_type = self.base_type.analyse(env)
919 # If the field is an external typedef, we cannot be sure about the type,
920 # so do conversion ourself rather than rely on the CPython mechanism (through
921 # a property; made in AnalyseDeclarationsTransform).
922 if (dest_scope.is_c_class_scope
923 and self.visibility in ('public', 'readonly')):
927 need_property = False
928 visibility = self.visibility
930 for declarator in self.declarators:
931 name_declarator, type = declarator.analyse(base_type, env)
932 if not type.is_complete():
933 if not (self.visibility == 'extern' and type.is_array):
934 error(declarator.pos,
935 "Variable type '%s' is incomplete" % type)
936 if self.visibility == 'extern' and type.is_pyobject:
937 error(declarator.pos,
938 "Python object cannot be declared extern")
939 name = name_declarator.name
940 cname = name_declarator.cname
942 error(declarator.pos, "Missing name in declaration.")
944 if type.is_cfunction:
945 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
948 if entry is not None:
949 entry.directive_locals = self.directive_locals
951 if self.directive_locals:
952 s.error("Decorators can only be followed by functions")
953 if self.in_pxd and self.visibility != 'extern':
955 "Only 'extern' C variable declaration allowed in .pxd file")
956 entry = dest_scope.declare_var(name, type, declarator.pos,
957 cname = cname, visibility = visibility, is_cdef = 1)
959 self.properties.append(entry)
962 class CStructOrUnionDefNode(StatNode):
964 # cname string or None
965 # kind "struct" or "union"
966 # typedef_flag boolean
967 # visibility "public" or "private"
969 # attributes [CVarDefNode] or None
973 child_attrs = ["attributes"]
975 def analyse_declarations(self, env):
977 if self.visibility == 'extern' and self.packed:
978 error(self.pos, "Cannot declare extern struct as 'packed'")
979 if self.attributes is not None:
980 scope = StructOrUnionScope(self.name)
981 self.entry = env.declare_struct_or_union(
982 self.name, self.kind, scope, self.typedef_flag, self.pos,
983 self.cname, visibility = self.visibility, packed = self.packed)
984 if self.attributes is not None:
985 if self.in_pxd and not env.in_cinclude:
986 self.entry.defined_in_pxd = 1
987 for attr in self.attributes:
988 attr.analyse_declarations(env, scope)
989 if self.visibility != 'extern':
990 need_typedef_indirection = False
991 for attr in scope.var_entries:
994 type = type.base_type
995 if type == self.entry.type:
996 error(attr.pos, "Struct cannot contain itself as a member.")
997 if self.typedef_flag:
999 type = type.base_type
1000 if type == self.entry.type:
1001 need_typedef_indirection = True
1002 if need_typedef_indirection:
1003 # C can't handle typedef structs that refer to themselves.
1004 struct_entry = self.entry
1005 self.entry = env.declare_typedef(
1006 self.name, struct_entry.type, self.pos,
1007 cname = self.cname, visibility='ignore')
1008 struct_entry.type.typedef_flag = False
1009 # FIXME: this might be considered a hack ;-)
1010 struct_entry.cname = struct_entry.type.cname = \
1011 '_' + self.entry.type.typedef_cname
1013 def analyse_expressions(self, env):
1016 def generate_execution_code(self, code):
1020 class CppClassNode(CStructOrUnionDefNode):
1023 # cname string or None
1024 # visibility "extern"
1026 # attributes [CVarDefNode] or None
1028 # base_classes [string]
1029 # templates [string] or None
1031 def analyse_declarations(self, env):
1033 if self.attributes is not None:
1034 scope = CppClassScope(self.name, env)
1035 base_class_types = []
1036 for base_class_name in self.base_classes:
1037 base_class_entry = env.lookup(base_class_name)
1038 if base_class_entry is None:
1039 error(self.pos, "'%s' not found" % base_class_name)
1040 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1041 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1043 base_class_types.append(base_class_entry.type)
1044 if self.templates is None:
1045 template_types = None
1047 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1048 self.entry = env.declare_cpp_class(
1049 self.name, scope, self.pos,
1050 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1051 self.entry.is_cpp_class = 1
1052 if self.attributes is not None:
1053 if self.in_pxd and not env.in_cinclude:
1054 self.entry.defined_in_pxd = 1
1055 for attr in self.attributes:
1056 attr.analyse_declarations(scope)
1058 class CEnumDefNode(StatNode):
1059 # name string or None
1060 # cname string or None
1061 # items [CEnumDefItemNode]
1062 # typedef_flag boolean
1063 # visibility "public" or "private"
1067 child_attrs = ["items"]
1069 def analyse_declarations(self, env):
1070 self.entry = env.declare_enum(self.name, self.pos,
1071 cname = self.cname, typedef_flag = self.typedef_flag,
1072 visibility = self.visibility)
1073 if self.items is not None:
1074 if self.in_pxd and not env.in_cinclude:
1075 self.entry.defined_in_pxd = 1
1076 for item in self.items:
1077 item.analyse_declarations(env, self.entry)
1079 def analyse_expressions(self, env):
1082 def generate_execution_code(self, code):
1083 if self.visibility == 'public':
1084 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1085 for item in self.entry.enum_values:
1086 code.putln("%s = PyInt_FromLong(%s); %s" % (
1089 code.error_goto_if_null(temp, item.pos)))
1090 code.put_gotref(temp)
1091 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1092 Naming.module_cname,
1095 code.error_goto(item.pos)))
1096 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1097 code.funcstate.release_temp(temp)
1100 class CEnumDefItemNode(StatNode):
1102 # cname string or None
1103 # value ExprNode or None
1105 child_attrs = ["value"]
1107 def analyse_declarations(self, env, enum_entry):
1109 self.value.analyse_const_expression(env)
1110 if not self.value.type.is_int:
1111 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1112 self.value.analyse_const_expression(env)
1113 entry = env.declare_const(self.name, enum_entry.type,
1114 self.value, self.pos, cname = self.cname,
1115 visibility = enum_entry.visibility)
1116 enum_entry.enum_values.append(entry)
1119 class CTypeDefNode(StatNode):
1120 # base_type CBaseTypeNode
1121 # declarator CDeclaratorNode
1122 # visibility "public" or "private"
1125 child_attrs = ["base_type", "declarator"]
1127 def analyse_declarations(self, env):
1128 base = self.base_type.analyse(env)
1129 name_declarator, type = self.declarator.analyse(base, env)
1130 name = name_declarator.name
1131 cname = name_declarator.cname
1132 entry = env.declare_typedef(name, type, self.pos,
1133 cname = cname, visibility = self.visibility)
1134 if self.in_pxd and not env.in_cinclude:
1135 entry.defined_in_pxd = 1
1137 def analyse_expressions(self, env):
1139 def generate_execution_code(self, code):
1143 class FuncDefNode(StatNode, BlockNode):
1144 # Base class for function definition nodes.
1146 # return_type PyrexType
1147 # #filename string C name of filename string const
1148 # entry Symtab.Entry
1149 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1150 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1154 needs_closure = False
1157 def analyse_default_values(self, env):
1158 genv = env.global_scope()
1160 for arg in self.args:
1164 arg.default.analyse_types(env)
1165 arg.default = arg.default.coerce_to(arg.type, genv)
1168 "This argument cannot have a default value")
1173 error(arg.pos, "Non-default argument following default argument")
1175 def need_gil_acquisition(self, lenv):
1178 def create_local_scope(self, env):
1180 while genv.is_py_class_scope or genv.is_c_class_scope:
1181 genv = env.outer_scope
1182 if self.needs_closure:
1183 lenv = ClosureScope(name=self.entry.name,
1185 scope_name=self.entry.cname)
1187 lenv = LocalScope(name=self.entry.name,
1190 lenv.return_type = self.return_type
1191 type = self.entry.type
1192 if type.is_cfunction:
1193 lenv.nogil = type.nogil and not type.with_gil
1194 self.local_scope = lenv
1195 lenv.directives = env.directives
1198 def generate_function_definitions(self, env, code):
1201 lenv = self.local_scope
1202 if lenv.is_closure_scope:
1203 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1204 Naming.outer_scope_cname)
1206 outer_scope_cname = Naming.outer_scope_cname
1207 lenv.mangle_closure_cnames(outer_scope_cname)
1208 # Generate closure function definitions
1209 self.body.generate_function_definitions(lenv, code)
1210 # generate lambda function definitions
1211 for node in lenv.lambda_defs:
1212 node.generate_function_definitions(lenv, code)
1214 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1215 self.entry.scope.is_c_class_scope)
1216 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1217 self.entry.scope.is_c_class_scope)
1218 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1220 if 'cython_unused' not in self.modifiers:
1221 self.modifiers = self.modifiers + ['cython_unused']
1223 profile = code.globalstate.directives['profile']
1226 error(self.pos, "Cannot profile nogil function.")
1227 code.globalstate.use_utility_code(profile_utility_code)
1229 # Generate C code for header and body of function
1230 code.enter_cfunc_scope()
1231 code.return_from_error_cleanup_label = code.new_label()
1233 # ----- Top-level constants used by this function
1234 code.mark_pos(self.pos)
1235 self.generate_cached_builtins_decls(lenv, code)
1236 # ----- Function header
1238 with_pymethdef = self.needs_assignment_synthesis(env, code)
1240 self.py_func.generate_function_header(code,
1241 with_pymethdef = with_pymethdef,
1243 self.generate_function_header(code,
1244 with_pymethdef = with_pymethdef)
1245 # ----- Local variable declarations
1246 if lenv.is_closure_scope:
1247 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1249 elif env.is_closure_scope:
1250 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1252 self.generate_argument_declarations(lenv, code)
1253 for entry in lenv.var_entries:
1254 if not entry.in_closure:
1255 code.put_var_declaration(entry)
1257 if not self.return_type.is_void:
1258 if self.return_type.is_pyobject:
1262 (self.return_type.declaration_code(Naming.retval_cname),
1264 tempvardecl_code = code.insertion_point()
1265 self.generate_keyword_list(code)
1267 code.put_trace_declarations()
1268 # ----- Extern library function declarations
1269 lenv.generate_library_function_declarations(code)
1270 # ----- GIL acquisition
1271 acquire_gil = self.acquire_gil
1273 env.use_utility_code(force_init_threads_utility_code)
1274 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1275 # ----- set up refnanny
1277 code.put_setup_refcount_context(self.entry.name)
1278 # ----- Automatic lead-ins for certain special functions
1279 if is_getbuffer_slot:
1280 self.getbuffer_init(code)
1281 # ----- Create closure scope object
1282 if self.needs_closure:
1283 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1284 Naming.cur_scope_cname,
1285 lenv.scope_class.type.declaration_code(''),
1286 lenv.scope_class.type.typeptr_cname,
1287 lenv.scope_class.type.typeptr_cname,
1288 Naming.empty_tuple))
1289 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1290 if is_getbuffer_slot:
1291 self.getbuffer_error_cleanup(code)
1293 code.put_finish_refcount_context()
1294 # FIXME: what if the error return value is a Python value?
1295 code.putln("return %s;" % self.error_value())
1297 code.put_gotref(Naming.cur_scope_cname)
1298 # Note that it is unsafe to decref the scope at this point.
1299 if env.is_closure_scope:
1300 code.putln("%s = (%s)%s;" % (
1302 env.scope_class.type.declaration_code(''),
1304 if self.needs_closure:
1305 # inner closures own a reference to their outer parent
1306 code.put_incref(outer_scope_cname, env.scope_class.type)
1307 code.put_giveref(outer_scope_cname)
1308 # ----- Trace function call
1310 # this looks a bit late, but if we don't get here due to a
1311 # fatal error before hand, it's not really worth tracing
1312 code.put_trace_call(self.entry.name, self.pos)
1313 # ----- Fetch arguments
1314 self.generate_argument_parsing_code(env, code)
1315 # If an argument is assigned to in the body, we must
1316 # incref it to properly keep track of refcounts.
1317 for entry in lenv.arg_entries:
1318 if entry.type.is_pyobject:
1319 if entry.assignments and not entry.in_closure:
1320 code.put_var_incref(entry)
1321 # ----- Initialise local variables
1322 for entry in lenv.var_entries:
1323 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1324 code.put_init_var_to_py_none(entry)
1325 # ----- Initialise local buffer auxiliary variables
1326 for entry in lenv.var_entries + lenv.arg_entries:
1327 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1328 code.putln("%s.buf = NULL;" %
1329 entry.buffer_aux.buffer_info_var.cname)
1330 # ----- Check and convert arguments
1331 self.generate_argument_type_tests(code)
1332 # ----- Acquire buffer arguments
1333 for entry in lenv.arg_entries:
1334 if entry.type.is_buffer:
1335 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1337 # -------------------------
1338 # ----- Function body -----
1339 # -------------------------
1340 self.body.generate_execution_code(code)
1342 # ----- Default return value
1344 if self.return_type.is_pyobject:
1345 #if self.return_type.is_extension_type:
1346 # lhs = "(PyObject *)%s" % Naming.retval_cname
1348 lhs = Naming.retval_cname
1349 code.put_init_to_py_none(lhs, self.return_type)
1351 val = self.return_type.default_value
1353 code.putln("%s = %s;" % (Naming.retval_cname, val))
1354 # ----- Error cleanup
1355 if code.error_label in code.labels_used:
1356 code.put_goto(code.return_label)
1357 code.put_label(code.error_label)
1358 for cname, type in code.funcstate.all_managed_temps():
1359 code.put_xdecref(cname, type)
1361 # Clean up buffers -- this calls a Python function
1362 # so need to save and restore error state
1363 buffers_present = len(lenv.buffer_entries) > 0
1365 code.globalstate.use_utility_code(restore_exception_utility_code)
1366 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1367 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1368 for entry in lenv.buffer_entries:
1369 Buffer.put_release_buffer_code(code, entry)
1370 #code.putln("%s = 0;" % entry.cname)
1371 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1373 err_val = self.error_value()
1374 exc_check = self.caller_will_check_exceptions()
1375 if err_val is not None or exc_check:
1376 # TODO: Fix exception tracing (though currently unused by cProfile).
1377 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1378 # code.put_trace_exception()
1379 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1381 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1382 % self.entry.qualified_name, 0)
1384 '__Pyx_WriteUnraisable("%s");' %
1385 self.entry.qualified_name)
1386 env.use_utility_code(unraisable_exception_utility_code)
1387 env.use_utility_code(restore_exception_utility_code)
1388 default_retval = self.return_type.default_value
1389 if err_val is None and default_retval:
1390 err_val = default_retval
1391 if err_val is not None:
1392 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1394 if is_getbuffer_slot:
1395 self.getbuffer_error_cleanup(code)
1397 # If we are using the non-error cleanup section we should
1398 # jump past it if we have an error. The if-test below determine
1399 # whether this section is used.
1400 if buffers_present or is_getbuffer_slot:
1401 code.put_goto(code.return_from_error_cleanup_label)
1404 # ----- Non-error return cleanup
1405 code.put_label(code.return_label)
1406 for entry in lenv.buffer_entries:
1408 Buffer.put_release_buffer_code(code, entry)
1409 if is_getbuffer_slot:
1410 self.getbuffer_normal_cleanup(code)
1411 # ----- Return cleanup for both error and no-error return
1412 code.put_label(code.return_from_error_cleanup_label)
1413 if not Options.init_local_none:
1414 for entry in lenv.var_entries:
1415 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1416 entry.xdecref_cleanup = 1
1418 for entry in lenv.var_entries:
1419 if entry.type.is_pyobject:
1420 if entry.used and not entry.in_closure:
1421 code.put_var_decref(entry)
1422 elif entry.in_closure and self.needs_closure:
1423 code.put_giveref(entry.cname)
1424 # Decref any increfed args
1425 for entry in lenv.arg_entries:
1426 if entry.type.is_pyobject:
1427 if entry.in_closure:
1428 code.put_var_giveref(entry)
1429 elif entry.assignments:
1430 code.put_var_decref(entry)
1431 if self.needs_closure:
1432 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1435 # This code is duplicated in ModuleNode.generate_module_init_func
1437 default_retval = self.return_type.default_value
1438 err_val = self.error_value()
1439 if err_val is None and default_retval:
1440 err_val = default_retval
1441 if self.return_type.is_pyobject:
1442 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1444 if self.entry.is_special and self.entry.name == "__hash__":
1445 # Returning -1 for __hash__ is supposed to signal an error
1446 # We do as Python instances and coerce -1 into -2.
1447 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1448 Naming.retval_cname, Naming.retval_cname))
1451 if self.return_type.is_pyobject:
1452 code.put_trace_return(Naming.retval_cname)
1454 code.put_trace_return("Py_None")
1456 code.put_finish_refcount_context()
1459 code.putln("PyGILState_Release(_save);")
1461 if not self.return_type.is_void:
1462 code.putln("return %s;" % Naming.retval_cname)
1465 # ----- Go back and insert temp variable declarations
1466 tempvardecl_code.put_temp_declarations(code.funcstate)
1467 # ----- Python version
1468 code.exit_cfunc_scope()
1470 self.py_func.generate_function_definitions(env, code)
1471 self.generate_wrapper_functions(code)
1473 def declare_argument(self, env, arg):
1474 if arg.type.is_void:
1475 error(arg.pos, "Invalid use of 'void'")
1476 elif not arg.type.is_complete() and not arg.type.is_array:
1478 "Argument type '%s' is incomplete" % arg.type)
1479 return env.declare_arg(arg.name, arg.type, arg.pos)
1481 def generate_arg_type_test(self, arg, code):
1482 # Generate type test for one argument.
1483 if arg.type.typeobj_is_available():
1484 code.globalstate.use_utility_code(arg_type_test_utility_code)
1485 typeptr_cname = arg.type.typeptr_cname
1486 arg_code = "((PyObject *)%s)" % arg.entry.cname
1488 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1493 arg.type.is_builtin_type,
1494 code.error_goto(arg.pos)))
1496 error(arg.pos, "Cannot test type of extern C class "
1497 "without type object name specification")
1499 def generate_arg_none_check(self, arg, code):
1500 # Generate None check for one argument.
1501 code.globalstate.use_utility_code(arg_type_test_utility_code)
1502 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1503 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1505 code.error_goto(arg.pos)))
1508 def generate_wrapper_functions(self, code):
1511 def generate_execution_code(self, code):
1512 # Evaluate and store argument default values
1513 for arg in self.args:
1514 default = arg.default
1516 if not default.is_literal:
1517 default.generate_evaluation_code(code)
1518 default.make_owned_reference(code)
1519 result = default.result_as(arg.type)
1522 arg.calculate_default_value_code(code),
1524 if arg.type.is_pyobject:
1525 code.put_giveref(default.result())
1526 default.generate_post_assignment_code(code)
1527 default.free_temps(code)
1528 # For Python class methods, create and store function object
1530 self.assmt.generate_execution_code(code)
1533 # Special code for the __getbuffer__ function
1535 def getbuffer_init(self, code):
1536 info = self.local_scope.arg_entries[1].cname
1537 # Python 3.0 betas have a bug in memoryview which makes it call
1538 # getbuffer with a NULL parameter. For now we work around this;
1539 # the following line should be removed when this bug is fixed.
1540 code.putln("if (%s == NULL) return 0;" % info)
1541 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1542 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1544 def getbuffer_error_cleanup(self, code):
1545 info = self.local_scope.arg_entries[1].cname
1546 code.put_gotref("%s->obj" % info)
1547 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1550 def getbuffer_normal_cleanup(self, code):
1551 info = self.local_scope.arg_entries[1].cname
1552 code.putln("if (%s->obj == Py_None) {" % info)
1553 code.put_gotref("Py_None")
1554 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1557 class CFuncDefNode(FuncDefNode):
1558 # C function definition.
1560 # modifiers ['inline']
1561 # visibility 'private' or 'public' or 'extern'
1562 # base_type CBaseTypeNode
1563 # declarator CDeclaratorNode
1566 # decorators [DecoratorNode] list of decorators
1568 # with_gil boolean Acquire GIL around body
1570 # py_func wrapper for calling from Python
1571 # overridable whether or not this is a cpdef function
1572 # inline_in_pxd whether this is an inline function in a pxd file
1574 child_attrs = ["base_type", "declarator", "body", "py_func"]
1576 inline_in_pxd = False
1578 directive_locals = {}
1580 def unqualified_name(self):
1581 return self.entry.name
1583 def analyse_declarations(self, env):
1584 self.directive_locals.update(env.directives['locals'])
1585 base_type = self.base_type.analyse(env)
1586 # The 2 here is because we need both function and argument names.
1587 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1588 if not type.is_cfunction:
1590 "Suite attached to non-function declaration")
1591 # Remember the actual type according to the function header
1592 # written here, because the type in the symbol table entry
1593 # may be different if we're overriding a C method inherited
1594 # from the base type of an extension type.
1596 type.is_overridable = self.overridable
1597 declarator = self.declarator
1598 while not hasattr(declarator, 'args'):
1599 declarator = declarator.base
1600 self.args = declarator.args
1601 for formal_arg, type_arg in zip(self.args, type.args):
1602 formal_arg.type = type_arg.type
1603 formal_arg.name = type_arg.name
1604 formal_arg.cname = type_arg.cname
1605 name = name_declarator.name
1606 cname = name_declarator.cname
1607 self.entry = env.declare_cfunction(
1608 name, type, self.pos,
1609 cname = cname, visibility = self.visibility,
1610 defining = self.body is not None,
1611 api = self.api, modifiers = self.modifiers)
1612 self.entry.inline_func_in_pxd = self.inline_in_pxd
1613 self.return_type = type.return_type
1615 if self.overridable and not env.is_module_scope:
1616 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1617 # An error will be produced in the cdef function
1618 self.overridable = False
1620 if self.overridable:
1622 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1623 self.py_func = DefNode(pos = self.pos,
1624 name = self.entry.name,
1627 starstar_arg = None,
1629 body = py_func_body,
1631 self.py_func.is_module_scope = env.is_module_scope
1632 self.py_func.analyse_declarations(env)
1633 self.entry.as_variable = self.py_func.entry
1634 # Reset scope entry the above cfunction
1635 env.entries[name] = self.entry
1636 if not env.is_module_scope or Options.lookup_module_cpdef:
1637 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1638 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1639 self.create_local_scope(env)
1641 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1643 args = self.type.args
1644 if omit_optional_args:
1645 args = args[:len(args) - self.type.optional_arg_count]
1646 arg_names = [arg.name for arg in args]
1648 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1650 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1651 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1652 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1653 c_call = ExprNodes.SimpleCallNode(self.pos, function=cfunc, args=[ExprNodes.NameNode(self.pos, name=n) for n in arg_names[1-is_module_scope:]], wrapper_call=skip_dispatch)
1654 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1656 def declare_arguments(self, env):
1657 for arg in self.type.args:
1659 error(arg.pos, "Missing argument name")
1660 self.declare_argument(env, arg)
1662 def need_gil_acquisition(self, lenv):
1663 return self.type.with_gil
1665 def nogil_check(self, env):
1667 with_gil = type.with_gil
1668 if type.nogil and not with_gil:
1669 if type.return_type.is_pyobject:
1671 "Function with Python return type cannot be declared nogil")
1672 for entry in self.local_scope.var_entries:
1673 if entry.type.is_pyobject:
1674 error(self.pos, "Function declared nogil has Python locals or temporaries")
1676 def analyse_expressions(self, env):
1677 self.local_scope.directives = env.directives
1678 if self.py_func is not None:
1679 # this will also analyse the default values
1680 self.py_func.analyse_expressions(env)
1682 self.analyse_default_values(env)
1683 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1685 def needs_assignment_synthesis(self, env, code=None):
1688 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1691 visibility = self.entry.visibility
1692 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1693 arg_decls.append(arg.declaration_code())
1694 if with_dispatch and self.overridable:
1695 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1696 if type.optional_arg_count and with_opt_args:
1697 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1698 if type.has_varargs:
1699 arg_decls.append("...")
1701 arg_decls = ["void"]
1703 cname = self.entry.func_cname
1704 entity = type.function_header_code(cname, ', '.join(arg_decls))
1705 if visibility == 'public':
1706 dll_linkage = "DL_EXPORT"
1709 header = self.return_type.declaration_code(entity,
1710 dll_linkage = dll_linkage)
1711 if visibility == 'extern':
1712 storage_class = "%s " % Naming.extern_c_macro
1713 elif visibility == 'public':
1716 storage_class = "static "
1717 if 'inline' in self.modifiers:
1718 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1719 code.putln("%s%s %s {" % (
1721 ' '.join(self.modifiers).upper(), # macro forms
1724 def generate_argument_declarations(self, env, code):
1725 for arg in self.args:
1727 result = arg.calculate_default_value_code(code)
1728 code.putln('%s = %s;' % (
1729 arg.type.declaration_code(arg.cname), result))
1731 def generate_keyword_list(self, code):
1734 def generate_argument_parsing_code(self, env, code):
1736 if self.type.optional_arg_count:
1737 code.putln('if (%s) {' % Naming.optional_args_cname)
1738 for arg in self.args:
1740 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1741 declarator = arg.declarator
1742 while not hasattr(declarator, 'name'):
1743 declarator = declarator.base
1744 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1746 for _ in range(self.type.optional_arg_count):
1750 def generate_argument_conversion_code(self, code):
1753 def generate_argument_type_tests(self, code):
1754 # Generate type tests for args whose type in a parent
1755 # class is a supertype of the declared type.
1756 for arg in self.type.args:
1757 if arg.needs_type_test:
1758 self.generate_arg_type_test(arg, code)
1759 elif arg.type.is_pyobject and not arg.accept_none:
1760 self.generate_arg_none_check(arg, code)
1762 def error_value(self):
1763 if self.return_type.is_pyobject:
1767 return self.entry.type.exception_value
1769 def caller_will_check_exceptions(self):
1770 return self.entry.type.exception_check
1772 def generate_wrapper_functions(self, code):
1773 # If the C signature of a function has changed, we need to generate
1774 # wrappers to put in the slots here.
1777 func_type = entry.type
1778 while entry.prev_entry is not None:
1780 entry = entry.prev_entry
1781 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1783 self.generate_function_header(code,
1785 with_dispatch = entry.type.is_overridable,
1786 with_opt_args = entry.type.optional_arg_count,
1787 cname = entry.func_cname)
1788 if not self.return_type.is_void:
1790 args = self.type.args
1791 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1792 if entry.type.is_overridable:
1793 arglist.append(Naming.skip_dispatch_cname)
1794 elif func_type.is_overridable:
1796 if entry.type.optional_arg_count:
1797 arglist.append(Naming.optional_args_cname)
1798 elif func_type.optional_arg_count:
1799 arglist.append('NULL')
1800 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1804 class PyArgDeclNode(Node):
1805 # Argument which must be a Python object (used
1806 # for * and ** arguments).
1809 # entry Symtab.Entry
1810 # annotation ExprNode or None Py3 argument annotation
1813 def generate_function_definitions(self, env, code):
1814 self.entry.generate_function_definitions(env, code)
1816 class DecoratorNode(Node):
1819 # decorator NameNode or CallNode or AttributeNode
1820 child_attrs = ['decorator']
1823 class DefNode(FuncDefNode):
1824 # A Python function definition.
1826 # name string the Python name of the function
1827 # lambda_name string the internal name of a lambda 'function'
1828 # decorators [DecoratorNode] list of decorators
1829 # args [CArgDeclNode] formal arguments
1830 # star_arg PyArgDeclNode or None * argument
1831 # starstar_arg PyArgDeclNode or None ** argument
1832 # doc EncodedString or None
1834 # return_type_annotation
1835 # ExprNode or None the Py3 return type annotation
1837 # The following subnode is constructed internally
1838 # when the def statement is inside a Python class definition.
1840 # assmt AssignmentNode Function construction/assignment
1842 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1847 num_required_kw_args = 0
1848 reqd_kw_flags_cname = "0"
1851 return_type_annotation = None
1856 def __init__(self, pos, **kwds):
1857 FuncDefNode.__init__(self, pos, **kwds)
1859 for arg in self.args:
1866 self.num_kwonly_args = k
1867 self.num_required_kw_args = rk
1868 self.num_required_args = r
1870 def as_cfunction(self, cfunc=None, scope=None):
1872 error(self.star_arg.pos, "cdef function cannot have star argument")
1873 if self.starstar_arg:
1874 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1877 for formal_arg in self.args:
1878 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1879 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1881 type = py_object_type,
1882 pos = formal_arg.pos))
1883 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1885 has_varargs = False,
1886 exception_value = None,
1887 exception_check = False,
1890 is_overridable = True)
1891 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1893 cfunc_type = cfunc.type
1894 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1895 error(self.pos, "wrong number of arguments")
1896 error(cfunc.pos, "previous declaration here")
1897 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1898 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1899 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1900 formal_arg.type = type_arg.type
1901 formal_arg.name_declarator = name_declarator
1903 if cfunc_type.exception_value is None:
1904 exception_value = None
1906 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1907 declarator = CFuncDeclaratorNode(self.pos,
1908 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1910 has_varargs = False,
1911 exception_check = cfunc_type.exception_check,
1912 exception_value = exception_value,
1913 with_gil = cfunc_type.with_gil,
1914 nogil = cfunc_type.nogil)
1915 return CFuncDefNode(self.pos,
1917 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1918 declarator = declarator,
1921 overridable = cfunc_type.is_overridable,
1923 with_gil = cfunc_type.with_gil,
1924 nogil = cfunc_type.nogil,
1925 visibility = 'private',
1927 directive_locals = getattr(cfunc, 'directive_locals', {}))
1929 def analyse_declarations(self, env):
1930 self.is_classmethod = self.is_staticmethod = False
1932 for decorator in self.decorators:
1933 func = decorator.decorator
1935 self.is_classmethod |= func.name == 'classmethod'
1936 self.is_staticmethod |= func.name == 'staticmethod'
1938 if self.is_classmethod and env.lookup_here('classmethod'):
1939 # classmethod() was overridden - not much we can do here ...
1940 self.is_classmethod = False
1941 if self.is_staticmethod and env.lookup_here('staticmethod'):
1942 # staticmethod() was overridden - not much we can do here ...
1943 self.is_staticmethod = False
1945 self.analyse_argument_types(env)
1946 if self.name == '<lambda>':
1947 self.declare_lambda_function(env)
1949 self.declare_pyfunction(env)
1950 self.analyse_signature(env)
1951 self.return_type = self.entry.signature.return_type()
1952 self.create_local_scope(env)
1954 def analyse_argument_types(self, env):
1955 directive_locals = self.directive_locals = env.directives['locals']
1956 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1957 for arg in self.args:
1958 if hasattr(arg, 'name'):
1960 name_declarator = None
1962 base_type = arg.base_type.analyse(env)
1963 name_declarator, type = \
1964 arg.declarator.analyse(base_type, env)
1965 arg.name = name_declarator.name
1966 if arg.name in directive_locals:
1967 type_node = directive_locals[arg.name]
1968 other_type = type_node.analyse_as_type(env)
1969 if other_type is None:
1970 error(type_node.pos, "Not a type")
1971 elif (type is not PyrexTypes.py_object_type
1972 and not type.same_as(other_type)):
1973 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1974 error(type_node.pos, "Previous declaration here")
1977 if name_declarator and name_declarator.cname:
1979 "Python function argument cannot have C name specification")
1980 arg.type = type.as_argument_type()
1982 arg.needs_conversion = 0
1983 arg.needs_type_test = 0
1985 if arg.type.is_pyobject:
1987 arg.accept_none = True
1989 arg.accept_none = False
1990 elif arg.type.is_extension_type or arg.type.is_builtin_type:
1991 if arg.default and arg.default.constant_result is None:
1992 # special case: def func(MyType obj = None)
1993 arg.accept_none = True
1995 # default depends on compiler directive
1996 arg.accept_none = allow_none_for_extension_args
1998 # probably just a plain 'object'
1999 arg.accept_none = True
2001 arg.accept_none = True # won't be used, but must be there
2003 error(arg.pos, "Only Python type arguments can have 'not None'")
2005 error(arg.pos, "Only Python type arguments can have 'or None'")
2007 def analyse_signature(self, env):
2008 if self.entry.is_special:
2009 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2010 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2011 # Use the simpler calling signature for zero- and one-argument functions.
2012 if self.entry.signature is TypeSlots.pyfunction_signature:
2013 if len(self.args) == 0:
2014 self.entry.signature = TypeSlots.pyfunction_noargs
2015 elif len(self.args) == 1:
2016 if self.args[0].default is None and not self.args[0].kw_only:
2017 self.entry.signature = TypeSlots.pyfunction_onearg
2018 elif self.entry.signature is TypeSlots.pymethod_signature:
2019 if len(self.args) == 1:
2020 self.entry.signature = TypeSlots.unaryfunc
2021 elif len(self.args) == 2:
2022 if self.args[1].default is None and not self.args[1].kw_only:
2023 self.entry.signature = TypeSlots.ibinaryfunc
2025 sig = self.entry.signature
2026 nfixed = sig.num_fixed_args()
2027 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2028 and len(self.args) == 0 and self.star_arg:
2029 # this is the only case where a diverging number of
2030 # arguments is not an error - when we have no explicit
2031 # 'self' parameter as in method(*args)
2032 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2033 self.self_in_stararg = 1
2036 for i in range(min(nfixed, len(self.args))):
2039 if sig.is_self_arg(i) and not self.is_staticmethod:
2040 if self.is_classmethod:
2042 arg.hdr_type = arg.type = Builtin.type_type
2045 arg.hdr_type = arg.type = env.parent_type
2046 arg.needs_conversion = 0
2048 arg.hdr_type = sig.fixed_arg_type(i)
2049 if not arg.type.same_as(arg.hdr_type):
2050 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2051 arg.needs_type_test = 1
2053 arg.needs_conversion = 1
2054 if arg.needs_conversion:
2055 arg.hdr_cname = Naming.arg_prefix + arg.name
2057 arg.hdr_cname = Naming.var_prefix + arg.name
2059 if nfixed > len(self.args):
2060 self.bad_signature()
2062 elif nfixed < len(self.args):
2063 if not sig.has_generic_args:
2064 self.bad_signature()
2065 for arg in self.args:
2066 if arg.is_generic and \
2067 (arg.type.is_extension_type or arg.type.is_builtin_type):
2068 arg.needs_type_test = 1
2070 def bad_signature(self):
2071 sig = self.entry.signature
2072 expected_str = "%d" % sig.num_fixed_args()
2073 if sig.has_generic_args:
2074 expected_str = expected_str + " or more"
2076 if name.startswith("__") and name.endswith("__"):
2077 desc = "Special method"
2081 "%s %s has wrong number of arguments "
2082 "(%d declared, %s expected)" % (
2083 desc, self.name, len(self.args), expected_str))
2085 def signature_has_nongeneric_args(self):
2086 argcount = len(self.args)
2087 if argcount == 0 or (
2088 argcount == 1 and (self.args[0].is_self_arg or
2089 self.args[0].is_type_arg)):
2093 def signature_has_generic_args(self):
2094 return self.entry.signature.has_generic_args
2096 def declare_pyfunction(self, env):
2097 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2099 entry = env.lookup_here(name)
2100 if entry and entry.type.is_cfunction and not self.is_wrapper:
2101 warning(self.pos, "Overriding cdef method with def method.", 5)
2102 entry = env.declare_pyfunction(name, self.pos)
2104 prefix = env.scope_prefix
2105 entry.func_cname = \
2106 Naming.pyfunc_prefix + prefix + name
2107 entry.pymethdef_cname = \
2108 Naming.pymethdef_prefix + prefix + name
2109 if Options.docstrings:
2110 entry.doc = embed_position(self.pos, self.doc)
2112 Naming.funcdoc_prefix + prefix + name
2116 def declare_lambda_function(self, env):
2118 prefix = env.scope_prefix
2120 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2121 entry = env.declare_lambda_function(func_cname, self.pos)
2122 entry.pymethdef_cname = \
2123 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2124 entry.qualified_name = env.qualify_name(self.lambda_name)
2128 def declare_arguments(self, env):
2129 for arg in self.args:
2131 error(arg.pos, "Missing argument name")
2133 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2134 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2135 if arg.needs_conversion:
2136 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2137 if arg.type.is_pyobject:
2138 arg.entry.init = "0"
2139 arg.entry.init_to_none = 0
2141 arg.entry = self.declare_argument(env, arg)
2143 arg.entry.is_self_arg = arg.is_self_arg
2145 if arg.is_self_arg or arg.is_type_arg or \
2146 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2147 arg.entry.is_declared_generic = 1
2148 self.declare_python_arg(env, self.star_arg)
2149 self.declare_python_arg(env, self.starstar_arg)
2151 def declare_python_arg(self, env, arg):
2153 if env.directives['infer_types'] != False:
2154 type = PyrexTypes.unspecified_type
2156 type = py_object_type
2157 entry = env.declare_var(arg.name, type, arg.pos)
2160 entry.init_to_none = 0
2161 entry.xdecref_cleanup = 1
2163 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2165 def analyse_expressions(self, env):
2166 self.local_scope.directives = env.directives
2167 self.analyse_default_values(env)
2168 if self.needs_assignment_synthesis(env):
2169 # Shouldn't we be doing this at the module level too?
2170 self.synthesize_assignment_node(env)
2172 def needs_assignment_synthesis(self, env, code=None):
2173 # Should enable for module level as well, that will require more testing...
2174 if env.is_module_scope:
2176 return env.directives['binding']
2178 return code.globalstate.directives['binding']
2179 return env.is_py_class_scope or env.is_closure_scope
2181 def synthesize_assignment_node(self, env):
2183 if env.is_py_class_scope:
2184 rhs = ExprNodes.UnboundMethodNode(self.pos,
2185 function = ExprNodes.PyCFunctionNode(self.pos,
2186 pymethdef_cname = self.entry.pymethdef_cname))
2187 elif env.is_closure_scope:
2188 rhs = ExprNodes.InnerFunctionNode(
2189 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2191 rhs = ExprNodes.PyCFunctionNode(
2192 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2193 self.assmt = SingleAssignmentNode(self.pos,
2194 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2196 self.assmt.analyse_declarations(env)
2197 self.assmt.analyse_expressions(env)
2199 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2201 sig = self.entry.signature
2202 if sig.has_dummy_arg or self.self_in_stararg:
2203 arg_code_list.append(
2204 "PyObject *%s" % Naming.self_cname)
2205 for arg in self.args:
2206 if not arg.is_generic:
2207 if arg.is_self_arg or arg.is_type_arg:
2208 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2210 arg_code_list.append(
2211 arg.hdr_type.declaration_code(arg.hdr_cname))
2212 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2213 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2214 if sig.has_generic_args:
2215 arg_code_list.append(
2216 "PyObject *%s, PyObject *%s"
2217 % (Naming.args_cname, Naming.kwds_cname))
2218 arg_code = ", ".join(arg_code_list)
2219 dc = self.return_type.declaration_code(self.entry.func_cname)
2220 mf = " ".join(self.modifiers).upper()
2222 header = "static %s%s(%s)" % (mf, dc, arg_code)
2223 code.putln("%s; /*proto*/" % header)
2226 if (Options.docstrings and self.entry.doc and
2227 (not self.entry.is_special or
2228 self.entry.signature.method_flags()) and
2229 not self.entry.scope.is_property_scope
2231 docstr = self.entry.doc
2232 if docstr.is_unicode:
2233 docstr = docstr.utf8encode()
2235 'static char %s[] = "%s";' % (
2236 self.entry.doc_cname,
2237 split_string_literal(escape_byte_string(docstr))))
2240 "static PyMethodDef %s = " %
2241 self.entry.pymethdef_cname)
2242 code.put_pymethoddef(self.entry, ";")
2243 code.putln("%s {" % header)
2245 def generate_argument_declarations(self, env, code):
2246 for arg in self.args:
2247 if arg.is_generic: # or arg.needs_conversion:
2248 if arg.needs_conversion:
2249 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2250 elif not arg.entry.in_closure:
2251 code.put_var_declaration(arg.entry)
2253 def generate_keyword_list(self, code):
2254 if self.signature_has_generic_args() and \
2255 self.signature_has_nongeneric_args():
2257 "static PyObject **%s[] = {" %
2258 Naming.pykwdlist_cname)
2259 for arg in self.args:
2261 pystring_cname = code.intern_identifier(arg.name)
2262 code.put('&%s,' % pystring_cname)
2265 def generate_argument_parsing_code(self, env, code):
2266 # Generate PyArg_ParseTuple call for generic
2267 # arguments, if any.
2268 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2269 # get rid of unused argument warning
2270 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2272 old_error_label = code.new_error_label()
2273 our_error_label = code.error_label
2274 end_label = code.new_label("argument_unpacking_done")
2276 has_kwonly_args = self.num_kwonly_args > 0
2277 has_star_or_kw_args = self.star_arg is not None \
2278 or self.starstar_arg is not None or has_kwonly_args
2280 for arg in self.args:
2281 if not arg.type.is_pyobject:
2282 done = arg.type.create_from_py_utility_code(env)
2283 if not done: pass # will fail later
2285 if not self.signature_has_generic_args():
2286 if has_star_or_kw_args:
2287 error(self.pos, "This method cannot have * or keyword arguments")
2288 self.generate_argument_conversion_code(code)
2290 elif not self.signature_has_nongeneric_args():
2291 # func(*args) or func(**kw) or func(*args, **kw)
2292 self.generate_stararg_copy_code(code)
2295 positional_args = []
2297 for arg in self.args:
2298 arg_entry = arg.entry
2301 if not arg.is_self_arg and not arg.is_type_arg:
2303 kw_only_args.append(arg)
2305 positional_args.append(arg)
2307 kw_only_args.append(arg)
2308 elif not arg.is_self_arg and not arg.is_type_arg:
2309 positional_args.append(arg)
2311 self.generate_tuple_and_keyword_parsing_code(
2312 positional_args, kw_only_args, end_label, code)
2314 code.error_label = old_error_label
2315 if code.label_used(our_error_label):
2316 if not code.label_used(end_label):
2317 code.put_goto(end_label)
2318 code.put_label(our_error_label)
2319 if has_star_or_kw_args:
2320 self.generate_arg_decref(self.star_arg, code)
2321 if self.starstar_arg:
2322 if self.starstar_arg.entry.xdecref_cleanup:
2323 code.put_var_xdecref(self.starstar_arg.entry)
2325 code.put_var_decref(self.starstar_arg.entry)
2326 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2327 # The arguments are put into the closure one after the
2328 # other, so when type errors are found, all references in
2329 # the closure instance must be properly ref-counted to
2330 # facilitate generic closure instance deallocation. In
2331 # the case of an argument type error, it's best to just
2332 # DECREF+clear the already handled references, as this
2333 # frees their references as early as possible.
2334 for arg in self.args:
2335 if arg.type.is_pyobject and arg.entry.in_closure:
2336 code.put_var_xdecref_clear(arg.entry)
2337 if self.needs_closure:
2338 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2339 code.put_finish_refcount_context()
2340 code.putln("return %s;" % self.error_value())
2341 if code.label_used(end_label):
2342 code.put_label(end_label)
2344 def generate_arg_assignment(self, arg, item, code):
2345 if arg.type.is_pyobject:
2347 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2349 code.putln("%s = %s;" % (entry.cname, item))
2350 if entry.in_closure:
2351 code.put_var_incref(entry)
2353 func = arg.type.from_py_function
2355 code.putln("%s = %s(%s); %s" % (
2359 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2361 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2363 def generate_arg_xdecref(self, arg, code):
2365 code.put_var_xdecref(arg.entry)
2367 def generate_arg_decref(self, arg, code):
2369 code.put_var_decref(arg.entry)
2371 def generate_stararg_copy_code(self, code):
2372 if not self.star_arg:
2373 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2374 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2376 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2377 self.name, Naming.args_cname, self.error_value()))
2380 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2382 if self.starstar_arg:
2384 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2386 kwarg_check = "%s" % Naming.kwds_cname
2388 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2389 Naming.kwds_cname, Naming.kwds_cname)
2391 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2392 kwarg_check, Naming.kwds_cname, self.name,
2393 bool(self.starstar_arg), self.error_value()))
2395 if self.starstar_arg:
2396 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2397 self.starstar_arg.entry.cname,
2400 code.putln("if (unlikely(!%s)) return %s;" % (
2401 self.starstar_arg.entry.cname, self.error_value()))
2402 self.starstar_arg.entry.xdecref_cleanup = 0
2403 code.put_gotref(self.starstar_arg.entry.cname)
2405 if self.self_in_stararg:
2406 # need to create a new tuple with 'self' inserted as first item
2407 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2408 self.star_arg.entry.cname,
2410 self.star_arg.entry.cname))
2411 if self.starstar_arg:
2413 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2414 code.putln("return %s;" % self.error_value())
2417 code.putln("return %s;" % self.error_value())
2418 code.put_gotref(self.star_arg.entry.cname)
2419 code.put_incref(Naming.self_cname, py_object_type)
2420 code.put_giveref(Naming.self_cname)
2421 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2422 self.star_arg.entry.cname, Naming.self_cname))
2423 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2424 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2425 temp, temp, Naming.args_cname, temp))
2426 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2427 Naming.args_cname, temp))
2428 code.put_incref("item", py_object_type)
2429 code.put_giveref("item")
2430 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2431 self.star_arg.entry.cname, temp))
2433 code.funcstate.release_temp(temp)
2434 self.star_arg.entry.xdecref_cleanup = 0
2436 code.put_incref(Naming.args_cname, py_object_type)
2437 code.putln("%s = %s;" % (
2438 self.star_arg.entry.cname,
2440 self.star_arg.entry.xdecref_cleanup = 0
2442 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2443 kw_only_args, success_label, code):
2444 argtuple_error_label = code.new_label("argtuple_error")
2446 min_positional_args = self.num_required_args - self.num_required_kw_args
2447 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2448 min_positional_args -= 1
2449 max_positional_args = len(positional_args)
2450 has_fixed_positional_count = not self.star_arg and \
2451 min_positional_args == max_positional_args
2453 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2454 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2455 if self.num_required_kw_args:
2456 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2458 if self.starstar_arg or self.star_arg:
2459 self.generate_stararg_init_code(max_positional_args, code)
2461 # --- optimised code when we receive keyword arguments
2462 if self.num_required_kw_args:
2463 likely_hint = "likely"
2465 likely_hint = "unlikely"
2466 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2467 self.generate_keyword_unpacking_code(
2468 min_positional_args, max_positional_args,
2469 has_fixed_positional_count,
2470 positional_args, kw_only_args, argtuple_error_label, code)
2472 # --- optimised code when we do not receive any keyword arguments
2473 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2474 # Python raises arg tuple related errors first, so we must
2475 # check the length here
2476 if min_positional_args == max_positional_args and not self.star_arg:
2480 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2481 Naming.args_cname, compare, min_positional_args))
2482 code.put_goto(argtuple_error_label)
2484 if self.num_required_kw_args:
2485 # pure error case: keywords required but not passed
2486 if max_positional_args > min_positional_args and not self.star_arg:
2487 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2488 Naming.args_cname, max_positional_args))
2489 code.put_goto(argtuple_error_label)
2490 code.putln('} else {')
2491 for i, arg in enumerate(kw_only_args):
2493 pystring_cname = code.intern_identifier(arg.name)
2494 # required keyword-only argument missing
2495 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2498 code.putln(code.error_goto(self.pos))
2501 elif min_positional_args == max_positional_args:
2502 # parse the exact number of positional arguments from the
2504 code.putln('} else {')
2505 for i, arg in enumerate(positional_args):
2506 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2507 self.generate_arg_assignment(arg, item, code)
2508 self.generate_arg_default_assignments(code)
2511 # parse the positional arguments from the variable length
2513 code.putln('} else {')
2514 self.generate_arg_default_assignments(code)
2515 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2517 code.putln('default:')
2518 reversed_args = list(enumerate(positional_args))[::-1]
2519 for i, arg in reversed_args:
2520 if i >= min_positional_args-1:
2521 if min_positional_args > 1:
2522 code.putln('case %2d:' % (i+1)) # pure code beautification
2524 code.put('case %2d: ' % (i+1))
2525 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2526 self.generate_arg_assignment(arg, item, code)
2527 if min_positional_args == 0:
2528 code.put('case 0: ')
2529 code.putln('break;')
2531 if min_positional_args:
2532 for i in range(min_positional_args-1, -1, -1):
2533 code.putln('case %2d:' % i)
2534 code.put_goto(argtuple_error_label)
2536 code.put('default: ')
2537 code.put_goto(argtuple_error_label)
2542 if code.label_used(argtuple_error_label):
2543 code.put_goto(success_label)
2544 code.put_label(argtuple_error_label)
2545 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2546 self.name, has_fixed_positional_count,
2547 min_positional_args, max_positional_args,
2549 code.putln(code.error_goto(self.pos))
2551 def generate_arg_default_assignments(self, code):
2552 for arg in self.args:
2553 if arg.is_generic and arg.default:
2557 arg.calculate_default_value_code(code)))
2559 def generate_stararg_init_code(self, max_positional_args, code):
2560 if self.starstar_arg:
2561 self.starstar_arg.entry.xdecref_cleanup = 0
2562 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2563 self.starstar_arg.entry.cname,
2564 self.starstar_arg.entry.cname,
2565 self.error_value()))
2566 code.put_gotref(self.starstar_arg.entry.cname)
2568 self.star_arg.entry.xdecref_cleanup = 0
2569 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2571 max_positional_args))
2572 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2573 self.star_arg.entry.cname, Naming.args_cname,
2574 max_positional_args, Naming.args_cname))
2575 code.put_gotref(self.star_arg.entry.cname)
2576 if self.starstar_arg:
2578 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2579 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2580 code.putln('return %s;' % self.error_value())
2583 code.putln("if (unlikely(!%s)) return %s;" % (
2584 self.star_arg.entry.cname, self.error_value()))
2585 code.putln('} else {')
2586 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2587 code.put_incref(Naming.empty_tuple, py_object_type)
2590 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2591 has_fixed_positional_count, positional_args,
2592 kw_only_args, argtuple_error_label, code):
2593 all_args = tuple(positional_args) + tuple(kw_only_args)
2594 max_args = len(all_args)
2596 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2598 # the 'values' array collects borrowed references to arguments
2599 # before doing any type coercion etc.
2600 code.putln("PyObject* values[%d] = {%s};" % (
2601 max_args, ','.join('0'*max_args)))
2603 # assign borrowed Python default values to the values array,
2604 # so that they can be overwritten by received arguments below
2605 for i, arg in enumerate(all_args):
2606 if arg.default and arg.type.is_pyobject:
2607 default_value = arg.calculate_default_value_code(code)
2608 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2610 # parse the args tuple and check that it's not too long
2611 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2613 code.putln('default:')
2614 for i in range(max_positional_args-1, -1, -1):
2615 code.put('case %2d: ' % (i+1))
2616 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2617 i, Naming.args_cname, i))
2618 code.putln('case 0: break;')
2619 if not self.star_arg:
2620 code.put('default: ') # more arguments than allowed
2621 code.put_goto(argtuple_error_label)
2624 # now fill up the positional/required arguments with values
2626 if self.num_required_args or max_positional_args > 0:
2627 last_required_arg = -1
2628 for i, arg in enumerate(all_args):
2630 last_required_arg = i
2631 if last_required_arg < max_positional_args:
2632 last_required_arg = max_positional_args-1
2633 num_required_args = self.num_required_args
2634 if max_positional_args > 0:
2635 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2636 for i, arg in enumerate(all_args[:last_required_arg+1]):
2637 if max_positional_args > 0 and i <= max_positional_args:
2638 if self.star_arg and i == max_positional_args:
2639 code.putln('default:')
2641 code.putln('case %2d:' % i)
2642 pystring_cname = code.intern_identifier(arg.name)
2645 # handled separately below
2647 code.putln('if (kw_args > 0) {')
2648 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2649 Naming.kwds_cname, pystring_cname))
2650 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2653 num_required_args -= 1
2654 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2655 i, Naming.kwds_cname, pystring_cname))
2656 code.putln('if (likely(values[%d])) kw_args--;' % i);
2657 if i < min_positional_args:
2659 # special case: we know arg 0 is missing
2661 code.put_goto(argtuple_error_label)
2663 # print the correct number of values (args or
2664 # kwargs) that were passed into positional
2665 # arguments up to this point
2666 code.putln('else {')
2667 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2668 self.name, has_fixed_positional_count,
2669 min_positional_args, max_positional_args, i))
2670 code.putln(code.error_goto(self.pos))
2673 code.putln('else {')
2674 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2675 self.name, pystring_cname))
2676 code.putln(code.error_goto(self.pos))
2678 if max_positional_args > 0:
2681 if kw_only_args and not self.starstar_arg:
2682 # unpack optional keyword-only arguments
2683 # checking for interned strings in a dict is faster than iterating
2684 # but it's too likely that we must iterate if we expect **kwargs
2686 for i, arg in enumerate(all_args[max_positional_args:]):
2687 if not arg.kw_only or not arg.default:
2689 optional_args.append((i+max_positional_args, arg))
2691 # this mimics an unrolled loop so that we can "break" out of it
2692 code.putln('while (kw_args > 0) {')
2693 code.putln('PyObject* value;')
2694 for i, arg in optional_args:
2695 pystring_cname = code.intern_identifier(arg.name)
2697 'value = PyDict_GetItem(%s, %s);' % (
2698 Naming.kwds_cname, pystring_cname))
2700 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2701 code.putln('break;')
2704 code.putln('if (unlikely(kw_args > 0)) {')
2705 # non-positional/-required kw args left in dict: default args,
2706 # kw-only args, **kwargs or error
2708 # This is sort of a catch-all: except for checking required
2709 # arguments, this will always do the right thing for unpacking
2710 # keyword arguments, so that we can concentrate on optimising
2711 # common cases above.
2712 if max_positional_args == 0:
2715 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2716 Naming.args_cname, max_positional_args,
2717 Naming.args_cname, max_positional_args))
2718 pos_arg_count = "used_pos_args"
2720 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2721 code.globalstate.use_utility_code(parse_keywords_utility_code)
2723 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2725 Naming.pykwdlist_cname,
2726 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2729 code.putln(code.error_goto(self.pos))
2732 # convert arg values to their final type and assign them
2733 for i, arg in enumerate(all_args):
2734 if arg.default and not arg.type.is_pyobject:
2735 code.putln("if (values[%d]) {" % i)
2736 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2737 if arg.default and not arg.type.is_pyobject:
2738 code.putln('} else {')
2742 arg.calculate_default_value_code(code)))
2745 def generate_argument_conversion_code(self, code):
2746 # Generate code to convert arguments from signature type to
2747 # declared type, if needed. Also copies signature arguments
2748 # into closure fields.
2749 for arg in self.args:
2750 if arg.needs_conversion:
2751 self.generate_arg_conversion(arg, code)
2752 elif arg.entry.in_closure:
2753 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2754 if arg.type.is_pyobject:
2755 code.put_var_incref(arg.entry)
2757 def generate_arg_conversion(self, arg, code):
2758 # Generate conversion code for one argument.
2759 old_type = arg.hdr_type
2761 if old_type.is_pyobject:
2763 code.putln("if (%s) {" % arg.hdr_cname)
2765 code.putln("assert(%s); {" % arg.hdr_cname)
2766 self.generate_arg_conversion_from_pyobject(arg, code)
2768 elif new_type.is_pyobject:
2769 self.generate_arg_conversion_to_pyobject(arg, code)
2771 if new_type.assignable_from(old_type):
2773 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2776 "Cannot convert 1 argument from '%s' to '%s'" %
2777 (old_type, new_type))
2779 def generate_arg_conversion_from_pyobject(self, arg, code):
2781 func = new_type.from_py_function
2782 # copied from CoerceFromPyTypeNode
2784 lhs = arg.entry.cname
2785 rhs = "%s(%s)" % (func, arg.hdr_cname)
2786 if new_type.is_enum:
2787 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2788 code.putln("%s = %s; %s" % (
2791 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2794 "Cannot convert Python object argument to type '%s'"
2797 def generate_arg_conversion_to_pyobject(self, arg, code):
2798 old_type = arg.hdr_type
2799 func = old_type.to_py_function
2801 code.putln("%s = %s(%s); %s" % (
2805 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2806 code.put_var_gotref(arg.entry)
2809 "Cannot convert argument of type '%s' to Python object"
2812 def generate_argument_type_tests(self, code):
2813 # Generate type tests for args whose signature
2814 # type is PyObject * and whose declared type is
2815 # a subtype thereof.
2816 for arg in self.args:
2817 if arg.needs_type_test:
2818 self.generate_arg_type_test(arg, code)
2819 elif not arg.accept_none and arg.type.is_pyobject:
2820 self.generate_arg_none_check(arg, code)
2822 def error_value(self):
2823 return self.entry.signature.error_value
2825 def caller_will_check_exceptions(self):
2828 class OverrideCheckNode(StatNode):
2829 # A Node for dispatching to the def method if it
2838 child_attrs = ['body']
2842 def analyse_expressions(self, env):
2843 self.args = env.arg_entries
2844 if self.py_func.is_module_scope:
2849 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2850 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2851 call_node = ExprNodes.SimpleCallNode(self.pos,
2852 function=self.func_node,
2853 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2854 self.body = ReturnStatNode(self.pos, value=call_node)
2855 self.body.analyse_expressions(env)
2857 def generate_execution_code(self, code):
2858 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2859 # Check to see if we are an extension type
2860 if self.py_func.is_module_scope:
2861 self_arg = "((PyObject *)%s)" % Naming.module_cname
2863 self_arg = "((PyObject *)%s)" % self.args[0].cname
2864 code.putln("/* Check if called by wrapper */")
2865 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2866 code.putln("/* Check if overriden in Python */")
2867 if self.py_func.is_module_scope:
2868 code.putln("else {")
2870 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2871 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2872 self.func_node.set_cname(func_node_temp)
2873 # need to get attribute manually--scope would return cdef method
2874 err = code.error_goto_if_null(func_node_temp, self.pos)
2875 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2876 func_node_temp, self_arg, interned_attr_cname, err))
2877 code.put_gotref(func_node_temp)
2878 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2879 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2880 func_node_temp, self.py_func.entry.func_cname)
2881 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2882 self.body.generate_execution_code(code)
2884 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2885 code.funcstate.release_temp(func_node_temp)
2888 class ClassDefNode(StatNode, BlockNode):
2891 class PyClassDefNode(ClassDefNode):
2892 # A Python class definition.
2894 # name EncodedString Name of the class
2895 # doc string or None
2896 # body StatNode Attribute definition code
2897 # entry Symtab.Entry
2898 # scope PyClassScope
2899 # decorators [DecoratorNode] list of decorators or None
2901 # The following subnodes are constructed internally:
2903 # dict DictNode Class dictionary
2904 # classobj ClassNode Class object
2905 # target NameNode Variable to assign class object to
2907 child_attrs = ["body", "dict", "classobj", "target"]
2910 def __init__(self, pos, name, bases, doc, body, decorators = None):
2911 StatNode.__init__(self, pos)
2915 self.decorators = decorators
2917 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2918 if self.doc and Options.docstrings:
2919 doc = embed_position(self.pos, self.doc)
2920 # FIXME: correct string node?
2921 doc_node = ExprNodes.StringNode(pos, value = doc)
2924 self.classobj = ExprNodes.ClassNode(pos, name = name,
2925 bases = bases, dict = self.dict, doc = doc_node)
2926 self.target = ExprNodes.NameNode(pos, name = name)
2928 def as_cclass(self):
2930 Return this node as if it were declared as an extension class
2932 bases = self.classobj.bases.args
2934 base_class_name = None
2935 base_class_module = None
2936 elif len(bases) == 1:
2939 from ExprNodes import AttributeNode, NameNode
2940 while isinstance(base, AttributeNode):
2941 path.insert(0, base.attribute)
2943 if isinstance(base, NameNode):
2944 path.insert(0, base.name)
2945 base_class_name = path[-1]
2947 base_class_module = u'.'.join(path[:-1])
2949 base_class_module = None
2951 error(self.classobj.bases.args.pos, "Invalid base class")
2953 error(self.classobj.bases.args.pos, "C class may only have one base class")
2956 return CClassDefNode(self.pos,
2957 visibility = 'private',
2959 class_name = self.name,
2960 base_class_module = base_class_module,
2961 base_class_name = base_class_name,
2962 decorators = self.decorators,
2967 def create_scope(self, env):
2969 while env.is_py_class_scope or env.is_c_class_scope:
2970 env = env.outer_scope
2971 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2974 def analyse_declarations(self, env):
2975 self.target.analyse_target_declaration(env)
2976 cenv = self.create_scope(env)
2977 cenv.directives = env.directives
2978 cenv.class_obj_cname = self.target.entry.cname
2979 self.body.analyse_declarations(cenv)
2981 def analyse_expressions(self, env):
2982 self.dict.analyse_expressions(env)
2983 self.classobj.analyse_expressions(env)
2984 genv = env.global_scope()
2986 self.body.analyse_expressions(cenv)
2987 self.target.analyse_target_expression(env, self.classobj)
2989 def generate_function_definitions(self, env, code):
2990 self.body.generate_function_definitions(self.scope, code)
2992 def generate_execution_code(self, code):
2993 code.pyclass_stack.append(self)
2995 self.dict.generate_evaluation_code(code)
2996 self.classobj.generate_evaluation_code(code)
2997 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2998 self.body.generate_execution_code(code)
2999 self.target.generate_assignment_code(self.classobj, code)
3000 self.dict.generate_disposal_code(code)
3001 self.dict.free_temps(code)
3002 code.pyclass_stack.pop()
3005 class CClassDefNode(ClassDefNode):
3006 # An extension type definition.
3008 # visibility 'private' or 'public' or 'extern'
3009 # typedef_flag boolean
3011 # module_name string or None For import of extern type objects
3012 # class_name string Unqualified name of class
3013 # as_name string or None Name to declare as in this scope
3014 # base_class_module string or None Module containing the base class
3015 # base_class_name string or None Name of the base class
3016 # objstruct_name string or None Specified C name of object struct
3017 # typeobj_name string or None Specified C name of type object
3018 # in_pxd boolean Is in a .pxd file
3019 # decorators [DecoratorNode] list of decorators or None
3020 # doc string or None
3021 # body StatNode or None
3022 # entry Symtab.Entry
3023 # base_type PyExtensionType or None
3024 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3025 # buffer_defaults_pos
3027 child_attrs = ["body"]
3028 buffer_defaults_node = None
3029 buffer_defaults_pos = None
3030 typedef_flag = False
3032 objstruct_name = None
3036 def analyse_declarations(self, env):
3037 #print "CClassDefNode.analyse_declarations:", self.class_name
3038 #print "...visibility =", self.visibility
3039 #print "...module_name =", self.module_name
3042 if self.buffer_defaults_node:
3043 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3044 env, [], self.buffer_defaults_node,
3045 need_complete=False)
3047 buffer_defaults = None
3049 if env.in_cinclude and not self.objstruct_name:
3050 error(self.pos, "Object struct name specification required for "
3051 "C class defined in 'extern from' block")
3052 self.base_type = None
3053 # Now that module imports are cached, we need to
3054 # import the modules for extern classes.
3055 if self.module_name:
3057 for module in env.cimported_modules:
3058 if module.name == self.module_name:
3059 self.module = module
3060 if self.module is None:
3061 self.module = ModuleScope(self.module_name, None, env.context)
3062 self.module.has_extern_class = 1
3063 env.add_imported_module(self.module)
3065 if self.base_class_name:
3066 if self.base_class_module:
3067 base_class_scope = env.find_module(self.base_class_module, self.pos)
3069 base_class_scope = env
3070 if self.base_class_name == 'object':
3071 # extension classes are special and don't need to inherit from object
3072 if base_class_scope is None or base_class_scope.lookup('object') is None:
3073 self.base_class_name = None
3074 self.base_class_module = None
3075 base_class_scope = None
3076 if base_class_scope:
3077 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3078 if base_class_entry:
3079 if not base_class_entry.is_type:
3080 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3081 elif not base_class_entry.type.is_extension_type:
3082 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3083 elif not base_class_entry.type.is_complete():
3084 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
3086 self.base_type = base_class_entry.type
3087 has_body = self.body is not None
3088 if self.module_name and self.visibility != 'extern':
3089 module_path = self.module_name.split(".")
3090 home_scope = env.find_imported_module(module_path, self.pos)
3096 if self.visibility == 'extern':
3097 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3098 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3100 self.entry = home_scope.declare_c_class(
3101 name = self.class_name,
3103 defining = has_body and self.in_pxd,
3104 implementing = has_body and not self.in_pxd,
3105 module_name = self.module_name,
3106 base_type = self.base_type,
3107 objstruct_cname = self.objstruct_name,
3108 typeobj_cname = self.typeobj_name,
3109 visibility = self.visibility,
3110 typedef_flag = self.typedef_flag,
3112 buffer_defaults = buffer_defaults)
3113 if home_scope is not env and self.visibility == 'extern':
3114 env.add_imported_entry(self.class_name, self.entry, pos)
3115 self.scope = scope = self.entry.type.scope
3116 if scope is not None:
3117 scope.directives = env.directives
3119 if self.doc and Options.docstrings:
3120 scope.doc = embed_position(self.pos, self.doc)
3123 self.body.analyse_declarations(scope)
3127 scope.implemented = 1
3128 env.allocate_vtable_names(self.entry)
3130 def analyse_expressions(self, env):
3132 scope = self.entry.type.scope
3133 self.body.analyse_expressions(scope)
3135 def generate_function_definitions(self, env, code):
3137 self.body.generate_function_definitions(
3138 self.entry.type.scope, code)
3140 def generate_execution_code(self, code):
3141 # This is needed to generate evaluation code for
3142 # default values of method arguments.
3144 self.body.generate_execution_code(code)
3146 def annotate(self, code):
3148 self.body.annotate(code)
3151 class PropertyNode(StatNode):
3152 # Definition of a property in an extension type.
3155 # doc EncodedString or None Doc string
3158 child_attrs = ["body"]
3160 def analyse_declarations(self, env):
3161 entry = env.declare_property(self.name, self.doc, self.pos)
3163 entry.scope.directives = env.directives
3164 self.body.analyse_declarations(entry.scope)
3166 def analyse_expressions(self, env):
3167 self.body.analyse_expressions(env)
3169 def generate_function_definitions(self, env, code):
3170 self.body.generate_function_definitions(env, code)
3172 def generate_execution_code(self, code):
3175 def annotate(self, code):
3176 self.body.annotate(code)
3179 class GlobalNode(StatNode):
3180 # Global variable declaration.
3186 def analyse_declarations(self, env):
3187 for name in self.names:
3188 env.declare_global(name, self.pos)
3190 def analyse_expressions(self, env):
3193 def generate_execution_code(self, code):
3197 class ExprStatNode(StatNode):
3198 # Expression used as a statement.
3202 child_attrs = ["expr"]
3204 def analyse_declarations(self, env):
3206 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3207 func = self.expr.function.as_cython_attribute()
3208 if func == u'declare':
3209 args, kwds = self.expr.explicit_args_kwds()
3211 error(self.expr.pos, "Variable names must be specified.")
3212 for var, type_node in kwds.key_value_pairs:
3213 type = type_node.analyse_as_type(env)
3215 error(type_node.pos, "Unknown type")
3217 env.declare_var(var.value, type, var.pos, is_cdef = True)
3218 self.__class__ = PassStatNode
3220 def analyse_expressions(self, env):
3221 self.expr.analyse_expressions(env)
3223 def generate_execution_code(self, code):
3224 self.expr.generate_evaluation_code(code)
3225 if not self.expr.is_temp and self.expr.result():
3226 code.putln("%s;" % self.expr.result())
3227 self.expr.generate_disposal_code(code)
3228 self.expr.free_temps(code)
3230 def generate_function_definitions(self, env, code):
3231 self.expr.generate_function_definitions(env, code)
3233 def annotate(self, code):
3234 self.expr.annotate(code)
3237 class AssignmentNode(StatNode):
3238 # Abstract base class for assignment nodes.
3240 # The analyse_expressions and generate_execution_code
3241 # phases of assignments are split into two sub-phases
3242 # each, to enable all the right hand sides of a
3243 # parallel assignment to be evaluated before assigning
3244 # to any of the left hand sides.
3246 def analyse_expressions(self, env):
3247 self.analyse_types(env)
3249 # def analyse_expressions(self, env):
3250 # self.analyse_expressions_1(env)
3251 # self.analyse_expressions_2(env)
3253 def generate_execution_code(self, code):
3254 self.generate_rhs_evaluation_code(code)
3255 self.generate_assignment_code(code)
3258 class SingleAssignmentNode(AssignmentNode):
3259 # The simplest case:
3263 # lhs ExprNode Left hand side
3264 # rhs ExprNode Right hand side
3265 # first bool Is this guaranteed the first assignment to lhs?
3267 child_attrs = ["lhs", "rhs"]
3269 declaration_only = False
3271 def analyse_declarations(self, env):
3274 # handle declarations of the form x = cython.foo()
3275 if isinstance(self.rhs, ExprNodes.CallNode):
3276 func_name = self.rhs.function.as_cython_attribute()
3278 args, kwds = self.rhs.explicit_args_kwds()
3280 if func_name in ['declare', 'typedef']:
3281 if len(args) > 2 or kwds is not None:
3282 error(rhs.pos, "Can only declare one type at a time.")
3284 type = args[0].analyse_as_type(env)
3286 error(args[0].pos, "Unknown type")
3289 if func_name == 'declare':
3290 if isinstance(lhs, ExprNodes.NameNode):
3291 vars = [(lhs.name, lhs.pos)]
3292 elif isinstance(lhs, ExprNodes.TupleNode):
3293 vars = [(var.name, var.pos) for var in lhs.args]
3295 error(lhs.pos, "Invalid declaration")
3297 for var, pos in vars:
3298 env.declare_var(var, type, pos, is_cdef = True)
3303 self.declaration_only = True
3305 self.declaration_only = True
3306 if not isinstance(lhs, ExprNodes.NameNode):
3307 error(lhs.pos, "Invalid declaration.")
3308 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3310 elif func_name in ['struct', 'union']:
3311 self.declaration_only = True
3312 if len(args) > 0 or kwds is None:
3313 error(rhs.pos, "Struct or union members must be given by name.")
3316 for member, type_node in kwds.key_value_pairs:
3317 type = type_node.analyse_as_type(env)
3319 error(type_node.pos, "Unknown type")
3321 members.append((member.value, type, member.pos))
3322 if len(members) < len(kwds.key_value_pairs):
3324 if not isinstance(self.lhs, ExprNodes.NameNode):
3325 error(self.lhs.pos, "Invalid declaration.")
3326 name = self.lhs.name
3327 scope = StructOrUnionScope(name)
3328 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3329 for member, type, pos in members:
3330 scope.declare_var(member, type, pos)
3332 if self.declaration_only:
3335 self.lhs.analyse_target_declaration(env)
3337 def analyse_types(self, env, use_temp = 0):
3338 self.rhs.analyse_types(env)
3339 self.lhs.analyse_target_types(env)
3340 self.lhs.gil_assignment_check(env)
3341 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3343 self.rhs = self.rhs.coerce_to_temp(env)
3345 def generate_rhs_evaluation_code(self, code):
3346 self.rhs.generate_evaluation_code(code)
3348 def generate_assignment_code(self, code):
3349 self.lhs.generate_assignment_code(self.rhs, code)
3351 def generate_function_definitions(self, env, code):
3352 self.rhs.generate_function_definitions(env, code)
3354 def annotate(self, code):
3355 self.lhs.annotate(code)
3356 self.rhs.annotate(code)
3359 class CascadedAssignmentNode(AssignmentNode):
3360 # An assignment with multiple left hand sides:
3364 # lhs_list [ExprNode] Left hand sides
3365 # rhs ExprNode Right hand sides
3369 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3371 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3372 coerced_rhs_list = None
3374 def analyse_declarations(self, env):
3375 for lhs in self.lhs_list:
3376 lhs.analyse_target_declaration(env)
3378 def analyse_types(self, env, use_temp = 0):
3379 self.rhs.analyse_types(env)
3380 if not self.rhs.is_simple():
3382 self.rhs = self.rhs.coerce_to_temp(env)
3384 self.rhs = self.rhs.coerce_to_simple(env)
3385 from ExprNodes import CloneNode
3386 self.coerced_rhs_list = []
3387 for lhs in self.lhs_list:
3388 lhs.analyse_target_types(env)
3389 lhs.gil_assignment_check(env)
3390 rhs = CloneNode(self.rhs)
3391 rhs = rhs.coerce_to(lhs.type, env)
3392 self.coerced_rhs_list.append(rhs)
3394 def generate_rhs_evaluation_code(self, code):
3395 self.rhs.generate_evaluation_code(code)
3397 def generate_assignment_code(self, code):
3398 for i in range(len(self.lhs_list)):
3399 lhs = self.lhs_list[i]
3400 rhs = self.coerced_rhs_list[i]
3401 rhs.generate_evaluation_code(code)
3402 lhs.generate_assignment_code(rhs, code)
3403 # Assignment has disposed of the cloned RHS
3404 self.rhs.generate_disposal_code(code)
3405 self.rhs.free_temps(code)
3407 def generate_function_definitions(self, env, code):
3408 self.rhs.generate_function_definitions(env, code)
3410 def annotate(self, code):
3411 for i in range(len(self.lhs_list)):
3412 lhs = self.lhs_list[i].annotate(code)
3413 rhs = self.coerced_rhs_list[i].annotate(code)
3414 self.rhs.annotate(code)
3417 class ParallelAssignmentNode(AssignmentNode):
3418 # A combined packing/unpacking assignment:
3422 # This has been rearranged by the parser into
3424 # a = d ; b = e ; c = f
3426 # but we must evaluate all the right hand sides
3427 # before assigning to any of the left hand sides.
3429 # stats [AssignmentNode] The constituent assignments
3431 child_attrs = ["stats"]
3433 def analyse_declarations(self, env):
3434 for stat in self.stats:
3435 stat.analyse_declarations(env)
3437 def analyse_expressions(self, env):
3438 for stat in self.stats:
3439 stat.analyse_types(env, use_temp = 1)
3441 # def analyse_expressions(self, env):
3442 # for stat in self.stats:
3443 # stat.analyse_expressions_1(env, use_temp = 1)
3444 # for stat in self.stats:
3445 # stat.analyse_expressions_2(env)
3447 def generate_execution_code(self, code):
3448 for stat in self.stats:
3449 stat.generate_rhs_evaluation_code(code)
3450 for stat in self.stats:
3451 stat.generate_assignment_code(code)
3453 def generate_function_definitions(self, env, code):
3454 for stat in self.stats:
3455 stat.generate_function_definitions(env, code)
3457 def annotate(self, code):
3458 for stat in self.stats:
3462 class InPlaceAssignmentNode(AssignmentNode):
3463 # An in place arithmetic operand:
3469 # lhs ExprNode Left hand side
3470 # rhs ExprNode Right hand side
3471 # op char one of "+-*/%^&|"
3472 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3474 # This code is a bit tricky because in order to obey Python
3475 # semantics the sub-expressions (e.g. indices) of the lhs must
3476 # not be evaluated twice. So we must re-use the values calculated
3477 # in evaluation phase for the assignment phase as well.
3478 # Fortunately, the type of the lhs node is fairly constrained
3479 # (it must be a NameNode, AttributeNode, or IndexNode).
3481 child_attrs = ["lhs", "rhs"]
3484 def analyse_declarations(self, env):
3485 self.lhs.analyse_target_declaration(env)
3487 def analyse_types(self, env):
3488 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3489 self.rhs.analyse_types(env)
3490 self.lhs.analyse_target_types(env)
3492 if self.lhs.type.is_pyobject:
3493 self.rhs = self.rhs.coerce_to_pyobject(env)
3494 elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3495 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3496 if self.lhs.type.is_pyobject:
3497 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3498 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3500 def generate_execution_code(self, code):
3502 self.rhs.generate_evaluation_code(code)
3503 self.dup.generate_subexpr_evaluation_code(code)
3504 if self.dup.is_temp:
3505 self.dup.allocate_temp_result(code)
3506 # self.dup.generate_result_code is run only if it is not buffer access
3507 if self.operator == "**":
3511 if self.lhs.type.is_pyobject:
3512 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3513 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3514 self.dup.generate_result_code(code)
3515 self.result_value_temp.allocate(code)
3517 "%s = %s(%s, %s%s); %s" % (
3518 self.result_value.result(),
3519 self.py_operation_function(),
3520 self.dup.py_result(),
3521 self.rhs.py_result(),
3523 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3524 code.put_gotref(self.result_value.py_result())
3525 self.result_value.generate_evaluation_code(code) # May be a type check...
3526 self.rhs.generate_disposal_code(code)
3527 self.rhs.free_temps(code)
3528 self.dup.generate_disposal_code(code)
3529 self.dup.free_temps(code)
3530 self.lhs.generate_assignment_code(self.result_value, code)
3531 self.result_value_temp.release(code)
3533 c_op = self.operator
3537 error(self.pos, "No C inplace power operator")
3538 elif self.lhs.type.is_complex:
3539 error(self.pos, "Inplace operators not implemented for complex types.")
3541 # have to do assignment directly to avoid side-effects
3542 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3543 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3545 self.dup.generate_result_code(code)
3546 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3547 self.rhs.generate_disposal_code(code)
3548 self.rhs.free_temps(code)
3549 if self.dup.is_temp:
3550 self.dup.generate_subexpr_disposal_code(code)
3551 self.dup.free_subexpr_temps(code)
3553 def create_dup_node(self, env):
3556 self.dup.analyse_types(env)
3557 if isinstance(self.lhs, ExprNodes.NameNode):
3558 target_lhs = ExprNodes.NameNode(self.dup.pos,
3559 name = self.dup.name,
3560 is_temp = self.dup.is_temp,
3561 entry = self.dup.entry)
3562 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3563 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3564 obj = ExprNodes.CloneNode(self.lhs.obj),
3565 attribute = self.dup.attribute,
3566 is_temp = self.dup.is_temp)
3567 elif isinstance(self.lhs, ExprNodes.IndexNode):
3569 index = ExprNodes.CloneNode(self.lhs.index)
3572 if self.lhs.indices:
3573 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3576 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3577 base = ExprNodes.CloneNode(self.dup.base),
3580 is_temp = self.dup.is_temp)
3582 assert False, "Unsupported node: %s" % type(self.lhs)
3583 self.lhs = target_lhs
3586 def py_operation_function(self):
3587 return self.py_functions[self.operator]
3590 "|": "PyNumber_InPlaceOr",
3591 "^": "PyNumber_InPlaceXor",
3592 "&": "PyNumber_InPlaceAnd",
3593 "+": "PyNumber_InPlaceAdd",
3594 "-": "PyNumber_InPlaceSubtract",
3595 "*": "PyNumber_InPlaceMultiply",
3596 "/": "__Pyx_PyNumber_InPlaceDivide",
3597 "%": "PyNumber_InPlaceRemainder",
3598 "<<": "PyNumber_InPlaceLshift",
3599 ">>": "PyNumber_InPlaceRshift",
3600 "**": "PyNumber_InPlacePower",
3601 "//": "PyNumber_InPlaceFloorDivide",
3604 def annotate(self, code):
3605 self.lhs.annotate(code)
3606 self.rhs.annotate(code)
3607 self.dup.annotate(code)
3609 def create_binop_node(self):
3611 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3614 class PrintStatNode(StatNode):
3617 # arg_tuple TupleNode
3618 # stream ExprNode or None (stdout)
3619 # append_newline boolean
3621 child_attrs = ["arg_tuple", "stream"]
3623 def analyse_expressions(self, env):
3625 self.stream.analyse_expressions(env)
3626 self.stream = self.stream.coerce_to_pyobject(env)
3627 self.arg_tuple.analyse_expressions(env)
3628 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3629 env.use_utility_code(printing_utility_code)
3630 if len(self.arg_tuple.args) == 1 and self.append_newline:
3631 env.use_utility_code(printing_one_utility_code)
3633 nogil_check = Node.gil_error
3634 gil_message = "Python print statement"
3636 def generate_execution_code(self, code):
3638 self.stream.generate_evaluation_code(code)
3639 stream_result = self.stream.py_result()
3642 if len(self.arg_tuple.args) == 1 and self.append_newline:
3643 arg = self.arg_tuple.args[0]
3644 arg.generate_evaluation_code(code)
3647 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3650 code.error_goto(self.pos)))
3651 arg.generate_disposal_code(code)
3652 arg.free_temps(code)
3654 self.arg_tuple.generate_evaluation_code(code)
3656 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3658 self.arg_tuple.py_result(),
3659 self.append_newline,
3660 code.error_goto(self.pos)))
3661 self.arg_tuple.generate_disposal_code(code)
3662 self.arg_tuple.free_temps(code)
3665 self.stream.generate_disposal_code(code)
3666 self.stream.free_temps(code)
3668 def generate_function_definitions(self, env, code):
3670 self.stream.generate_function_definitions(env, code)
3671 self.arg_tuple.generate_function_definitions(env, code)
3673 def annotate(self, code):
3675 self.stream.annotate(code)
3676 self.arg_tuple.annotate(code)
3679 class ExecStatNode(StatNode):
3684 child_attrs = ["args"]
3686 def analyse_expressions(self, env):
3687 for i, arg in enumerate(self.args):
3688 arg.analyse_expressions(env)
3689 arg = arg.coerce_to_pyobject(env)
3691 env.use_utility_code(Builtin.pyexec_utility_code)
3693 nogil_check = Node.gil_error
3694 gil_message = "Python exec statement"
3696 def generate_execution_code(self, code):
3698 for arg in self.args:
3699 arg.generate_evaluation_code(code)
3700 args.append( arg.py_result() )
3701 args = tuple(args + ['0', '0'][:3-len(args)])
3702 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3703 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3704 (temp_result,) + args))
3705 for arg in self.args:
3706 arg.generate_disposal_code(code)
3707 arg.free_temps(code)
3709 code.error_goto_if_null(temp_result, self.pos))
3710 code.put_gotref(temp_result)
3711 code.put_decref_clear(temp_result, py_object_type)
3712 code.funcstate.release_temp(temp_result)
3714 def annotate(self, code):
3715 for arg in self.args:
3719 class DelStatNode(StatNode):
3724 child_attrs = ["args"]
3726 def analyse_declarations(self, env):
3727 for arg in self.args:
3728 arg.analyse_target_declaration(env)
3730 def analyse_expressions(self, env):
3731 for arg in self.args:
3732 arg.analyse_target_expression(env, None)
3733 if arg.type.is_pyobject:
3735 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3737 elif arg.type.is_cpp_class:
3738 error(arg.pos, "Deletion of non-heap C++ object")
3740 error(arg.pos, "Deletion of non-Python, non-C++ object")
3741 #arg.release_target_temp(env)
3743 def nogil_check(self, env):
3744 for arg in self.args:
3745 if arg.type.is_pyobject:
3748 gil_message = "Deleting Python object"
3750 def generate_execution_code(self, code):
3751 for arg in self.args:
3752 if arg.type.is_pyobject:
3753 arg.generate_deletion_code(code)
3754 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3755 arg.generate_result_code(code)
3756 code.putln("delete %s;" % arg.result())
3757 # else error reported earlier
3759 def annotate(self, code):
3760 for arg in self.args:
3764 class PassStatNode(StatNode):
3769 def analyse_expressions(self, env):
3772 def generate_execution_code(self, code):
3776 class BreakStatNode(StatNode):
3780 def analyse_expressions(self, env):
3783 def generate_execution_code(self, code):
3784 if not code.break_label:
3785 error(self.pos, "break statement not inside loop")
3787 code.put_goto(code.break_label)
3790 class ContinueStatNode(StatNode):
3794 def analyse_expressions(self, env):
3797 def generate_execution_code(self, code):
3798 if code.funcstate.in_try_finally:
3799 error(self.pos, "continue statement inside try of try...finally")
3800 elif not code.continue_label:
3801 error(self.pos, "continue statement not inside loop")
3803 code.put_goto(code.continue_label)
3806 class ReturnStatNode(StatNode):
3809 # value ExprNode or None
3810 # return_type PyrexType
3812 child_attrs = ["value"]
3814 def analyse_expressions(self, env):
3815 return_type = env.return_type
3816 self.return_type = return_type
3818 error(self.pos, "Return not inside a function body")
3821 self.value.analyse_types(env)
3822 if return_type.is_void or return_type.is_returncode:
3823 error(self.value.pos,
3824 "Return with value in void function")
3826 self.value = self.value.coerce_to(env.return_type, env)
3828 if (not return_type.is_void
3829 and not return_type.is_pyobject
3830 and not return_type.is_returncode):
3831 error(self.pos, "Return value required")
3833 def nogil_check(self, env):
3834 if self.return_type.is_pyobject:
3837 gil_message = "Returning Python object"
3839 def generate_execution_code(self, code):
3840 code.mark_pos(self.pos)
3841 if not self.return_type:
3842 # error reported earlier
3844 if self.return_type.is_pyobject:
3845 code.put_xdecref(Naming.retval_cname,
3848 self.value.generate_evaluation_code(code)
3849 self.value.make_owned_reference(code)
3852 Naming.retval_cname,
3853 self.value.result_as(self.return_type)))
3854 self.value.generate_post_assignment_code(code)
3855 self.value.free_temps(code)
3857 if self.return_type.is_pyobject:
3858 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3859 elif self.return_type.is_returncode:
3862 Naming.retval_cname,
3863 self.return_type.default_value))
3864 for cname, type in code.funcstate.temps_holding_reference():
3865 code.put_decref_clear(cname, type)
3866 code.put_goto(code.return_label)
3868 def generate_function_definitions(self, env, code):
3869 if self.value is not None:
3870 self.value.generate_function_definitions(env, code)
3872 def annotate(self, code):
3874 self.value.annotate(code)
3877 class RaiseStatNode(StatNode):
3880 # exc_type ExprNode or None
3881 # exc_value ExprNode or None
3882 # exc_tb ExprNode or None
3884 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3886 def analyse_expressions(self, env):
3888 self.exc_type.analyse_types(env)
3889 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3891 self.exc_value.analyse_types(env)
3892 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3894 self.exc_tb.analyse_types(env)
3895 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3896 env.use_utility_code(raise_utility_code)
3898 nogil_check = Node.gil_error
3899 gil_message = "Raising exception"
3901 def generate_execution_code(self, code):
3903 self.exc_type.generate_evaluation_code(code)
3904 type_code = self.exc_type.py_result()
3908 self.exc_value.generate_evaluation_code(code)
3909 value_code = self.exc_value.py_result()
3913 self.exc_tb.generate_evaluation_code(code)
3914 tb_code = self.exc_tb.py_result()
3918 "__Pyx_Raise(%s, %s, %s);" % (
3922 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3924 obj.generate_disposal_code(code)
3925 obj.free_temps(code)
3927 code.error_goto(self.pos))
3929 def generate_function_definitions(self, env, code):
3930 if self.exc_type is not None:
3931 self.exc_type.generate_function_definitions(env, code)
3932 if self.exc_value is not None:
3933 self.exc_value.generate_function_definitions(env, code)
3934 if self.exc_tb is not None:
3935 self.exc_tb.generate_function_definitions(env, code)
3937 def annotate(self, code):
3939 self.exc_type.annotate(code)
3941 self.exc_value.annotate(code)
3943 self.exc_tb.annotate(code)
3946 class ReraiseStatNode(StatNode):
3950 def analyse_expressions(self, env):
3951 env.use_utility_code(restore_exception_utility_code)
3953 nogil_check = Node.gil_error
3954 gil_message = "Raising exception"
3956 def generate_execution_code(self, code):
3957 vars = code.funcstate.exc_vars
3959 for varname in vars:
3960 code.put_giveref(varname)
3961 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3962 for varname in vars:
3963 code.put("%s = 0; " % varname)
3965 code.putln(code.error_goto(self.pos))
3967 error(self.pos, "Reraise not inside except clause")
3970 class AssertStatNode(StatNode):
3974 # value ExprNode or None
3976 child_attrs = ["cond", "value"]
3978 def analyse_expressions(self, env):
3979 self.cond = self.cond.analyse_boolean_expression(env)
3981 self.value.analyse_types(env)
3982 self.value = self.value.coerce_to_pyobject(env)
3984 nogil_check = Node.gil_error
3985 gil_message = "Raising exception"
3987 def generate_execution_code(self, code):
3988 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3989 self.cond.generate_evaluation_code(code)
3991 "if (unlikely(!%s)) {" %
3994 self.value.generate_evaluation_code(code)
3996 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3997 self.value.py_result())
3998 self.value.generate_disposal_code(code)
3999 self.value.free_temps(code)
4002 "PyErr_SetNone(PyExc_AssertionError);")
4004 code.error_goto(self.pos))
4007 self.cond.generate_disposal_code(code)
4008 self.cond.free_temps(code)
4009 code.putln("#endif")
4011 def generate_function_definitions(self, env, code):
4012 self.cond.generate_function_definitions(env, code)
4013 if self.value is not None:
4014 self.value.generate_function_definitions(env, code)
4016 def annotate(self, code):
4017 self.cond.annotate(code)
4019 self.value.annotate(code)
4022 class IfStatNode(StatNode):
4025 # if_clauses [IfClauseNode]
4026 # else_clause StatNode or None
4028 child_attrs = ["if_clauses", "else_clause"]
4030 def analyse_control_flow(self, env):
4031 env.start_branching(self.pos)
4032 for if_clause in self.if_clauses:
4033 if_clause.analyse_control_flow(env)
4034 env.next_branch(if_clause.end_pos())
4035 if self.else_clause:
4036 self.else_clause.analyse_control_flow(env)
4037 env.finish_branching(self.end_pos())
4039 def analyse_declarations(self, env):
4040 for if_clause in self.if_clauses:
4041 if_clause.analyse_declarations(env)
4042 if self.else_clause:
4043 self.else_clause.analyse_declarations(env)
4045 def analyse_expressions(self, env):
4046 for if_clause in self.if_clauses:
4047 if_clause.analyse_expressions(env)
4048 if self.else_clause:
4049 self.else_clause.analyse_expressions(env)
4051 def generate_execution_code(self, code):
4052 code.mark_pos(self.pos)
4053 end_label = code.new_label()
4054 for if_clause in self.if_clauses:
4055 if_clause.generate_execution_code(code, end_label)
4056 if self.else_clause:
4057 code.putln("/*else*/ {")
4058 self.else_clause.generate_execution_code(code)
4060 code.put_label(end_label)
4062 def generate_function_definitions(self, env, code):
4063 for clause in self.if_clauses:
4064 clause.generate_function_definitions(env, code)
4065 if self.else_clause is not None:
4066 self.else_clause.generate_function_definitions(env, code)
4068 def annotate(self, code):
4069 for if_clause in self.if_clauses:
4070 if_clause.annotate(code)
4071 if self.else_clause:
4072 self.else_clause.annotate(code)
4075 class IfClauseNode(Node):
4076 # if or elif clause in an if statement
4078 # condition ExprNode
4081 child_attrs = ["condition", "body"]
4083 def analyse_control_flow(self, env):
4084 self.body.analyse_control_flow(env)
4086 def analyse_declarations(self, env):
4087 self.condition.analyse_declarations(env)
4088 self.body.analyse_declarations(env)
4090 def analyse_expressions(self, env):
4092 self.condition.analyse_temp_boolean_expression(env)
4093 self.body.analyse_expressions(env)
4095 def get_constant_condition_result(self):
4096 if self.condition.has_constant_result():
4097 return bool(self.condition.constant_result)
4101 def generate_execution_code(self, code, end_label):
4102 self.condition.generate_evaluation_code(code)
4105 self.condition.result())
4106 self.condition.generate_disposal_code(code)
4107 self.condition.free_temps(code)
4108 self.body.generate_execution_code(code)
4109 code.put_goto(end_label)
4112 def generate_function_definitions(self, env, code):
4113 self.condition.generate_function_definitions(env, code)
4114 self.body.generate_function_definitions(env, code)
4116 def annotate(self, code):
4117 self.condition.annotate(code)
4118 self.body.annotate(code)
4121 class SwitchCaseNode(StatNode):
4122 # Generated in the optimization of an if-elif-else node
4124 # conditions [ExprNode]
4127 child_attrs = ['conditions', 'body']
4129 def generate_execution_code(self, code):
4130 for cond in self.conditions:
4131 code.mark_pos(cond.pos)
4132 cond.generate_evaluation_code(code)
4133 code.putln("case %s:" % cond.result())
4134 self.body.generate_execution_code(code)
4135 code.putln("break;")
4137 def generate_function_definitions(self, env, code):
4138 for cond in self.conditions:
4139 cond.generate_function_definitions(env, code)
4140 self.body.generate_function_definitions(env, code)
4142 def annotate(self, code):
4143 for cond in self.conditions:
4145 self.body.annotate(code)
4147 class SwitchStatNode(StatNode):
4148 # Generated in the optimization of an if-elif-else node
4151 # cases [SwitchCaseNode]
4152 # else_clause StatNode or None
4154 child_attrs = ['test', 'cases', 'else_clause']
4156 def generate_execution_code(self, code):
4157 code.putln("switch (%s) {" % self.test.result())
4158 for case in self.cases:
4159 case.generate_execution_code(code)
4160 if self.else_clause is not None:
4161 code.putln("default:")
4162 self.else_clause.generate_execution_code(code)
4163 code.putln("break;")
4166 def generate_function_definitions(self, env, code):
4167 self.test.generate_function_definitions(env, code)
4168 for case in self.cases:
4169 case.generate_function_definitions(env, code)
4170 if self.else_clause is not None:
4171 self.else_clause.generate_function_definitions(env, code)
4173 def annotate(self, code):
4174 self.test.annotate(code)
4175 for case in self.cases:
4177 if self.else_clause is not None:
4178 self.else_clause.annotate(code)
4180 class LoopNode(object):
4182 def analyse_control_flow(self, env):
4183 env.start_branching(self.pos)
4184 self.body.analyse_control_flow(env)
4185 env.next_branch(self.body.end_pos())
4186 if self.else_clause:
4187 self.else_clause.analyse_control_flow(env)
4188 env.finish_branching(self.end_pos())
4191 class WhileStatNode(LoopNode, StatNode):
4194 # condition ExprNode
4196 # else_clause StatNode
4198 child_attrs = ["condition", "body", "else_clause"]
4200 def analyse_declarations(self, env):
4201 self.body.analyse_declarations(env)
4202 if self.else_clause:
4203 self.else_clause.analyse_declarations(env)
4205 def analyse_expressions(self, env):
4207 self.condition.analyse_temp_boolean_expression(env)
4208 self.body.analyse_expressions(env)
4209 if self.else_clause:
4210 self.else_clause.analyse_expressions(env)
4212 def generate_execution_code(self, code):
4213 old_loop_labels = code.new_loop_labels()
4216 self.condition.generate_evaluation_code(code)
4217 self.condition.generate_disposal_code(code)
4220 self.condition.result())
4221 self.condition.free_temps(code)
4222 self.body.generate_execution_code(code)
4223 code.put_label(code.continue_label)
4225 break_label = code.break_label
4226 code.set_loop_labels(old_loop_labels)
4227 if self.else_clause:
4228 code.putln("/*else*/ {")
4229 self.else_clause.generate_execution_code(code)
4231 code.put_label(break_label)
4233 def generate_function_definitions(self, env, code):
4234 self.condition.generate_function_definitions(env, code)
4235 self.body.generate_function_definitions(env, code)
4236 if self.else_clause is not None:
4237 self.else_clause.generate_function_definitions(env, code)
4239 def annotate(self, code):
4240 self.condition.annotate(code)
4241 self.body.annotate(code)
4242 if self.else_clause:
4243 self.else_clause.annotate(code)
4246 def ForStatNode(pos, **kw):
4247 if 'iterator' in kw:
4248 return ForInStatNode(pos, **kw)
4250 return ForFromStatNode(pos, **kw)
4252 class ForInStatNode(LoopNode, StatNode):
4256 # iterator IteratorNode
4258 # else_clause StatNode
4259 # item NextNode used internally
4261 child_attrs = ["target", "iterator", "body", "else_clause"]
4264 def analyse_declarations(self, env):
4265 self.target.analyse_target_declaration(env)
4266 self.body.analyse_declarations(env)
4267 if self.else_clause:
4268 self.else_clause.analyse_declarations(env)
4270 def analyse_expressions(self, env):
4272 self.target.analyse_target_types(env)
4273 self.iterator.analyse_expressions(env)
4274 self.item = ExprNodes.NextNode(self.iterator, env)
4275 self.item = self.item.coerce_to(self.target.type, env)
4276 self.body.analyse_expressions(env)
4277 if self.else_clause:
4278 self.else_clause.analyse_expressions(env)
4280 def generate_execution_code(self, code):
4281 old_loop_labels = code.new_loop_labels()
4282 self.iterator.allocate_counter_temp(code)
4283 self.iterator.generate_evaluation_code(code)
4286 self.item.generate_evaluation_code(code)
4287 self.target.generate_assignment_code(self.item, code)
4288 self.body.generate_execution_code(code)
4289 code.put_label(code.continue_label)
4292 break_label = code.break_label
4293 code.set_loop_labels(old_loop_labels)
4295 if self.else_clause:
4296 # in nested loops, the 'else' block can contain a
4297 # 'continue' statement for the outer loop, but we may need
4298 # to generate cleanup code before taking that path, so we
4300 orig_continue_label = code.continue_label
4301 code.continue_label = code.new_label('outer_continue')
4303 code.putln("/*else*/ {")
4304 self.else_clause.generate_execution_code(code)
4307 if code.label_used(code.continue_label):
4308 code.put_goto(break_label)
4309 code.put_label(code.continue_label)
4310 self.iterator.generate_disposal_code(code)
4311 code.put_goto(orig_continue_label)
4312 code.set_loop_labels(old_loop_labels)
4314 if code.label_used(break_label):
4315 code.put_label(break_label)
4316 self.iterator.release_counter_temp(code)
4317 self.iterator.generate_disposal_code(code)
4318 self.iterator.free_temps(code)
4320 def generate_function_definitions(self, env, code):
4321 self.target.generate_function_definitions(env, code)
4322 self.iterator.generate_function_definitions(env, code)
4323 self.body.generate_function_definitions(env, code)
4324 if self.else_clause is not None:
4325 self.else_clause.generate_function_definitions(env, code)
4327 def annotate(self, code):
4328 self.target.annotate(code)
4329 self.iterator.annotate(code)
4330 self.body.annotate(code)
4331 if self.else_clause:
4332 self.else_clause.annotate(code)
4333 self.item.annotate(code)
4336 class ForFromStatNode(LoopNode, StatNode):
4337 # for name from expr rel name rel expr
4344 # step ExprNode or None
4346 # else_clause StatNode or None
4352 # loopvar_node ExprNode (usually a NameNode or temp node)
4353 # py_loopvar_node PyTempNode or None
4354 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4356 is_py_target = False
4358 py_loopvar_node = None
4361 gil_message = "For-loop using object bounds or target"
4363 def nogil_check(self, env):
4364 for x in (self.target, self.bound1, self.bound2):
4365 if x.type.is_pyobject:
4368 def analyse_declarations(self, env):
4369 self.target.analyse_target_declaration(env)
4370 self.body.analyse_declarations(env)
4371 if self.else_clause:
4372 self.else_clause.analyse_declarations(env)
4374 def analyse_expressions(self, env):
4376 self.target.analyse_target_types(env)
4377 self.bound1.analyse_types(env)
4378 self.bound2.analyse_types(env)
4379 if self.step is not None:
4380 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4381 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4382 self.step.analyse_types(env)
4384 target_type = self.target.type
4385 if self.target.type.is_numeric:
4386 loop_type = self.target.type
4388 loop_type = PyrexTypes.c_int_type
4389 if not self.bound1.type.is_pyobject:
4390 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4391 if not self.bound2.type.is_pyobject:
4392 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4393 if self.step is not None and not self.step.type.is_pyobject:
4394 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4395 self.bound1 = self.bound1.coerce_to(loop_type, env)
4396 self.bound2 = self.bound2.coerce_to(loop_type, env)
4397 if not self.bound2.is_literal:
4398 self.bound2 = self.bound2.coerce_to_temp(env)
4399 if self.step is not None:
4400 self.step = self.step.coerce_to(loop_type, env)
4401 if not self.step.is_literal:
4402 self.step = self.step.coerce_to_temp(env)
4404 target_type = self.target.type
4405 if not (target_type.is_pyobject or target_type.is_numeric):
4406 error(self.target.pos,
4407 "for-from loop variable must be c numeric type or Python object")
4408 if target_type.is_numeric:
4409 self.is_py_target = False
4410 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4411 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4412 self.loopvar_node = self.target
4413 self.py_loopvar_node = None
4415 self.is_py_target = True
4416 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4417 self.loopvar_node = c_loopvar_node
4418 self.py_loopvar_node = \
4419 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4420 self.body.analyse_expressions(env)
4421 if self.else_clause:
4422 self.else_clause.analyse_expressions(env)
4424 def generate_execution_code(self, code):
4425 old_loop_labels = code.new_loop_labels()
4426 from_range = self.from_range
4427 self.bound1.generate_evaluation_code(code)
4428 self.bound2.generate_evaluation_code(code)
4429 offset, incop = self.relation_table[self.relation1]
4430 if self.step is not None:
4431 self.step.generate_evaluation_code(code)
4432 step = self.step.result()
4433 incop = "%s=%s" % (incop[0], step)
4435 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4436 self.loopvar_node.allocate(code)
4437 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4438 self.py_loopvar_node.allocate(code)
4440 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4442 loopvar_name = self.loopvar_node.result()
4444 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4446 self.bound1.result(), offset,
4447 loopvar_name, self.relation2, self.bound2.result(),
4448 loopvar_name, incop))
4449 if self.py_loopvar_node:
4450 self.py_loopvar_node.generate_evaluation_code(code)
4451 self.target.generate_assignment_code(self.py_loopvar_node, code)
4453 code.putln("%s = %s;" % (
4454 self.target.result(), loopvar_name))
4455 self.body.generate_execution_code(code)
4456 code.put_label(code.continue_label)
4457 if self.py_loopvar_node:
4458 # This mess is to make for..from loops with python targets behave
4459 # exactly like those with C targets with regards to re-assignment
4460 # of the loop variable.
4462 if self.target.entry.is_pyglobal:
4463 # We know target is a NameNode, this is the only ugly case.
4464 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4465 target_node.allocate(code)
4466 interned_cname = code.intern_identifier(self.target.entry.name)
4467 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4468 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4469 target_node.result(),
4470 Naming.module_cname,
4472 code.error_goto_if_null(target_node.result(), self.target.pos)))
4473 code.put_gotref(target_node.result())
4475 target_node = self.target
4476 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4477 from_py_node.temp_code = loopvar_name
4478 from_py_node.generate_result_code(code)
4479 if self.target.entry.is_pyglobal:
4480 code.put_decref(target_node.result(), target_node.type)
4481 target_node.release(code)
4483 if self.py_loopvar_node:
4484 # This is potentially wasteful, but we don't want the semantics to
4485 # depend on whether or not the loop is a python type.
4486 self.py_loopvar_node.generate_evaluation_code(code)
4487 self.target.generate_assignment_code(self.py_loopvar_node, code)
4489 code.funcstate.release_temp(loopvar_name)
4490 break_label = code.break_label
4491 code.set_loop_labels(old_loop_labels)
4492 if self.else_clause:
4493 code.putln("/*else*/ {")
4494 self.else_clause.generate_execution_code(code)
4496 code.put_label(break_label)
4497 self.bound1.generate_disposal_code(code)
4498 self.bound1.free_temps(code)
4499 self.bound2.generate_disposal_code(code)
4500 self.bound2.free_temps(code)
4501 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4502 self.loopvar_node.release(code)
4503 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4504 self.py_loopvar_node.release(code)
4505 if self.step is not None:
4506 self.step.generate_disposal_code(code)
4507 self.step.free_temps(code)
4510 # {relop : (initial offset, increment op)}
4517 def generate_function_definitions(self, env, code):
4518 self.target.generate_function_definitions(env, code)
4519 self.bound1.generate_function_definitions(env, code)
4520 self.bound2.generate_function_definitions(env, code)
4521 if self.step is not None:
4522 self.step.generate_function_definitions(env, code)
4523 self.body.generate_function_definitions(env, code)
4524 if self.else_clause is not None:
4525 self.else_clause.generate_function_definitions(env, code)
4527 def annotate(self, code):
4528 self.target.annotate(code)
4529 self.bound1.annotate(code)
4530 self.bound2.annotate(code)
4532 self.step.annotate(code)
4533 self.body.annotate(code)
4534 if self.else_clause:
4535 self.else_clause.annotate(code)
4538 class WithStatNode(StatNode):
4540 Represents a Python with statement.
4542 This is only used at parse tree level; and is not present in
4543 analysis or generation phases.
4545 # manager The with statement manager object
4546 # target Node (lhs expression)
4548 child_attrs = ["manager", "target", "body"]
4550 class TryExceptStatNode(StatNode):
4551 # try .. except statement
4554 # except_clauses [ExceptClauseNode]
4555 # else_clause StatNode or None
4557 child_attrs = ["body", "except_clauses", "else_clause"]
4559 def analyse_control_flow(self, env):
4560 env.start_branching(self.pos)
4561 self.body.analyse_control_flow(env)
4562 successful_try = env.control_flow # grab this for later
4563 env.next_branch(self.body.end_pos())
4564 env.finish_branching(self.body.end_pos())
4566 env.start_branching(self.except_clauses[0].pos)
4567 for except_clause in self.except_clauses:
4568 except_clause.analyse_control_flow(env)
4569 env.next_branch(except_clause.end_pos())
4571 # the else cause it executed only when the try clause finishes
4572 env.control_flow.incoming = successful_try
4573 if self.else_clause:
4574 self.else_clause.analyse_control_flow(env)
4575 env.finish_branching(self.end_pos())
4577 def analyse_declarations(self, env):
4578 self.body.analyse_declarations(env)
4579 for except_clause in self.except_clauses:
4580 except_clause.analyse_declarations(env)
4581 if self.else_clause:
4582 self.else_clause.analyse_declarations(env)
4583 env.use_utility_code(reset_exception_utility_code)
4585 def analyse_expressions(self, env):
4586 self.body.analyse_expressions(env)
4587 default_clause_seen = 0
4588 for except_clause in self.except_clauses:
4589 except_clause.analyse_expressions(env)
4590 if default_clause_seen:
4591 error(except_clause.pos, "default 'except:' must be last")
4592 if not except_clause.pattern:
4593 default_clause_seen = 1
4594 self.has_default_clause = default_clause_seen
4595 if self.else_clause:
4596 self.else_clause.analyse_expressions(env)
4598 nogil_check = Node.gil_error
4599 gil_message = "Try-except statement"
4601 def generate_execution_code(self, code):
4602 old_return_label = code.return_label
4603 old_break_label = code.break_label
4604 old_continue_label = code.continue_label
4605 old_error_label = code.new_error_label()
4606 our_error_label = code.error_label
4607 except_end_label = code.new_label('exception_handled')
4608 except_error_label = code.new_label('except_error')
4609 except_return_label = code.new_label('except_return')
4610 try_return_label = code.new_label('try_return')
4611 try_break_label = code.new_label('try_break')
4612 try_continue_label = code.new_label('try_continue')
4613 try_end_label = code.new_label('try_end')
4616 code.putln("PyObject %s;" %
4617 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4618 code.putln("__Pyx_ExceptionSave(%s);" %
4619 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4620 for var in Naming.exc_save_vars:
4621 code.put_xgotref(var)
4624 code.return_label = try_return_label
4625 code.break_label = try_break_label
4626 code.continue_label = try_continue_label
4627 self.body.generate_execution_code(code)
4630 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4631 code.error_label = except_error_label
4632 code.return_label = except_return_label
4633 if self.else_clause:
4636 self.else_clause.generate_execution_code(code)
4639 for var in Naming.exc_save_vars:
4640 code.put_xdecref_clear(var, py_object_type)
4641 code.put_goto(try_end_label)
4642 if code.label_used(try_return_label):
4643 code.put_label(try_return_label)
4644 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4645 code.putln("__Pyx_ExceptionReset(%s);" %
4646 ', '.join(Naming.exc_save_vars))
4647 code.put_goto(old_return_label)
4648 code.put_label(our_error_label)
4649 for temp_name, type in temps_to_clean_up:
4650 code.put_xdecref_clear(temp_name, type)
4651 for except_clause in self.except_clauses:
4652 except_clause.generate_handling_code(code, except_end_label)
4654 error_label_used = code.label_used(except_error_label)
4655 if error_label_used or not self.has_default_clause:
4656 if error_label_used:
4657 code.put_label(except_error_label)
4658 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4659 code.putln("__Pyx_ExceptionReset(%s);" %
4660 ', '.join(Naming.exc_save_vars))
4661 code.put_goto(old_error_label)
4663 for exit_label, old_label in zip(
4664 [try_break_label, try_continue_label, except_return_label],
4665 [old_break_label, old_continue_label, old_return_label]):
4667 if code.label_used(exit_label):
4668 code.put_label(exit_label)
4669 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4670 code.putln("__Pyx_ExceptionReset(%s);" %
4671 ', '.join(Naming.exc_save_vars))
4672 code.put_goto(old_label)
4674 if code.label_used(except_end_label):
4675 code.put_label(except_end_label)
4676 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4677 code.putln("__Pyx_ExceptionReset(%s);" %
4678 ', '.join(Naming.exc_save_vars))
4679 code.put_label(try_end_label)
4682 code.return_label = old_return_label
4683 code.break_label = old_break_label
4684 code.continue_label = old_continue_label
4685 code.error_label = old_error_label
4687 def generate_function_definitions(self, env, code):
4688 self.body.generate_function_definitions(env, code)
4689 for except_clause in self.except_clauses:
4690 except_clause.generate_function_definitions(env, code)
4691 if self.else_clause is not None:
4692 self.else_clause.generate_function_definitions(env, code)
4694 def annotate(self, code):
4695 self.body.annotate(code)
4696 for except_node in self.except_clauses:
4697 except_node.annotate(code)
4698 if self.else_clause:
4699 self.else_clause.annotate(code)
4702 class ExceptClauseNode(Node):
4703 # Part of try ... except statement.
4706 # target ExprNode or None
4708 # excinfo_target NameNode or None optional target for exception info
4709 # match_flag string result of exception match
4710 # exc_value ExcValueNode used internally
4711 # function_name string qualified name of enclosing function
4712 # exc_vars (string * 3) local exception variables
4714 # excinfo_target is never set by the parser, but can be set by a transform
4715 # in order to extract more extensive information about the exception as a
4716 # sys.exc_info()-style tuple into a target variable
4718 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4721 excinfo_target = None
4723 def analyse_declarations(self, env):
4725 self.target.analyse_target_declaration(env)
4726 if self.excinfo_target is not None:
4727 self.excinfo_target.analyse_target_declaration(env)
4728 self.body.analyse_declarations(env)
4730 def analyse_expressions(self, env):
4732 genv = env.global_scope()
4733 self.function_name = env.qualified_name
4735 self.pattern.analyse_expressions(env)
4736 self.pattern = self.pattern.coerce_to_pyobject(env)
4739 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4740 self.target.analyse_target_expression(env, self.exc_value)
4741 if self.excinfo_target is not None:
4743 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4744 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4745 self.excinfo_tuple.analyse_expressions(env)
4746 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4748 self.body.analyse_expressions(env)
4750 def generate_handling_code(self, code, end_label):
4751 code.mark_pos(self.pos)
4753 self.pattern.generate_evaluation_code(code)
4755 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4757 "%s = PyErr_ExceptionMatches(%s);" % (
4759 self.pattern.py_result()))
4760 self.pattern.generate_disposal_code(code)
4761 self.pattern.free_temps(code)
4765 code.funcstate.release_temp(match_flag)
4767 code.putln("/*except:*/ {")
4769 if not getattr(self.body, 'stats', True) and \
4770 self.excinfo_target is None and self.target is None:
4771 # most simple case: no exception variable, empty body (pass)
4772 # => reset the exception state, done
4773 code.putln("PyErr_Restore(0,0,0);")
4774 code.put_goto(end_label)
4778 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4781 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4782 # We always have to fetch the exception value even if
4783 # there is no target, because this also normalises the
4784 # exception and stores it in the thread state.
4785 code.globalstate.use_utility_code(get_exception_utility_code)
4786 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4787 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4788 code.error_goto(self.pos)))
4792 self.exc_value.set_var(exc_vars[1])
4793 self.exc_value.generate_evaluation_code(code)
4794 self.target.generate_assignment_code(self.exc_value, code)
4795 if self.excinfo_target is not None:
4796 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4797 node.set_var(tempvar)
4798 self.excinfo_tuple.generate_evaluation_code(code)
4799 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4801 old_break_label, old_continue_label = code.break_label, code.continue_label
4802 code.break_label = code.new_label('except_break')
4803 code.continue_label = code.new_label('except_continue')
4805 old_exc_vars = code.funcstate.exc_vars
4806 code.funcstate.exc_vars = exc_vars
4807 self.body.generate_execution_code(code)
4808 code.funcstate.exc_vars = old_exc_vars
4809 for var in exc_vars:
4810 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4811 code.put_goto(end_label)
4813 if code.label_used(code.break_label):
4814 code.put_label(code.break_label)
4815 for var in exc_vars:
4816 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4817 code.put_goto(old_break_label)
4818 code.break_label = old_break_label
4820 if code.label_used(code.continue_label):
4821 code.put_label(code.continue_label)
4822 for var in exc_vars:
4823 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4824 code.put_goto(old_continue_label)
4825 code.continue_label = old_continue_label
4827 for temp in exc_vars:
4828 code.funcstate.release_temp(temp)
4833 def generate_function_definitions(self, env, code):
4834 if self.target is not None:
4835 self.target.generate_function_definitions(env, code)
4836 self.body.generate_function_definitions(env, code)
4838 def annotate(self, code):
4840 self.pattern.annotate(code)
4842 self.target.annotate(code)
4843 self.body.annotate(code)
4846 class TryFinallyStatNode(StatNode):
4847 # try ... finally statement
4850 # finally_clause StatNode
4852 # The plan is that we funnel all continue, break
4853 # return and error gotos into the beginning of the
4854 # finally block, setting a variable to remember which
4855 # one we're doing. At the end of the finally block, we
4856 # switch on the variable to figure out where to go.
4857 # In addition, if we're doing an error, we save the
4858 # exception on entry to the finally block and restore
4861 child_attrs = ["body", "finally_clause"]
4863 preserve_exception = 1
4865 disallow_continue_in_try_finally = 0
4866 # There doesn't seem to be any point in disallowing
4867 # continue in the try block, since we have no problem
4870 def create_analysed(pos, env, body, finally_clause):
4871 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4873 create_analysed = staticmethod(create_analysed)
4875 def analyse_control_flow(self, env):
4876 env.start_branching(self.pos)
4877 self.body.analyse_control_flow(env)
4878 env.next_branch(self.body.end_pos())
4879 env.finish_branching(self.body.end_pos())
4880 self.finally_clause.analyse_control_flow(env)
4882 def analyse_declarations(self, env):
4883 self.body.analyse_declarations(env)
4884 self.finally_clause.analyse_declarations(env)
4886 def analyse_expressions(self, env):
4887 self.body.analyse_expressions(env)
4888 self.finally_clause.analyse_expressions(env)
4890 nogil_check = Node.gil_error
4891 gil_message = "Try-finally statement"
4893 def generate_execution_code(self, code):
4894 old_error_label = code.error_label
4895 old_labels = code.all_new_labels()
4896 new_labels = code.get_all_labels()
4897 new_error_label = code.error_label
4898 catch_label = code.new_label()
4901 if self.disallow_continue_in_try_finally:
4902 was_in_try_finally = code.funcstate.in_try_finally
4903 code.funcstate.in_try_finally = 1
4904 self.body.generate_execution_code(code)
4905 if self.disallow_continue_in_try_finally:
4906 code.funcstate.in_try_finally = was_in_try_finally
4909 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4910 code.mark_pos(self.finally_clause.pos)
4914 error_label_used = 0
4915 for i, new_label in enumerate(new_labels):
4916 if new_label in code.labels_used:
4917 cases_used.append(i)
4918 if new_label == new_error_label:
4919 error_label_used = 1
4920 error_label_case = i
4924 if error_label_used and self.preserve_exception:
4926 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4928 "int %s;" % Naming.exc_lineno_name)
4929 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4930 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4931 code.putln(exc_var_init_zero)
4933 exc_var_init_zero = None
4934 code.use_label(catch_label)
4936 "__pyx_why = 0; goto %s;" % catch_label)
4937 for i in cases_used:
4938 new_label = new_labels[i]
4939 #if new_label and new_label != "<try>":
4940 if new_label == new_error_label and self.preserve_exception:
4941 self.put_error_catcher(code,
4942 new_error_label, i+1, catch_label, temps_to_clean_up)
4944 code.put('%s: ' % new_label)
4945 if exc_var_init_zero:
4946 code.putln(exc_var_init_zero)
4947 code.putln("__pyx_why = %s; goto %s;" % (
4950 code.put_label(catch_label)
4951 code.set_all_labels(old_labels)
4952 if error_label_used:
4953 code.new_error_label()
4954 finally_error_label = code.error_label
4955 self.finally_clause.generate_execution_code(code)
4956 if error_label_used:
4957 if finally_error_label in code.labels_used and self.preserve_exception:
4958 over_label = code.new_label()
4959 code.put_goto(over_label);
4960 code.put_label(finally_error_label)
4961 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4962 for var in Naming.exc_vars:
4963 code.putln("Py_XDECREF(%s);" % var)
4965 code.put_goto(old_error_label)
4966 code.put_label(over_label)
4967 code.error_label = old_error_label
4970 "switch (__pyx_why) {")
4971 for i in cases_used:
4972 old_label = old_labels[i]
4973 if old_label == old_error_label and self.preserve_exception:
4974 self.put_error_uncatcher(code, i+1, old_error_label)
4976 code.use_label(old_label)
4978 "case %s: goto %s;" % (
4986 def generate_function_definitions(self, env, code):
4987 self.body.generate_function_definitions(env, code)
4988 self.finally_clause.generate_function_definitions(env, code)
4990 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4991 code.globalstate.use_utility_code(restore_exception_utility_code)
4998 for temp_name, type in temps_to_clean_up:
4999 code.put_xdecref_clear(temp_name, type)
5001 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5005 Naming.exc_lineno_name, Naming.lineno_cname))
5006 code.put_goto(catch_label)
5009 def put_error_uncatcher(self, code, i, error_label):
5010 code.globalstate.use_utility_code(restore_exception_utility_code)
5015 "__Pyx_ErrRestore(%s, %s, %s);" %
5019 Naming.lineno_cname, Naming.exc_lineno_name))
5020 for var in Naming.exc_vars:
5024 code.put_goto(error_label)
5028 def annotate(self, code):
5029 self.body.annotate(code)
5030 self.finally_clause.annotate(code)
5033 class GILStatNode(TryFinallyStatNode):
5034 # 'with gil' or 'with nogil' statement
5036 # state string 'gil' or 'nogil'
5040 preserve_exception = 0
5042 def __init__(self, pos, state, body):
5044 TryFinallyStatNode.__init__(self, pos,
5046 finally_clause = GILExitNode(pos, state = state))
5048 def analyse_expressions(self, env):
5049 env.use_utility_code(force_init_threads_utility_code)
5050 was_nogil = env.nogil
5052 TryFinallyStatNode.analyse_expressions(self, env)
5053 env.nogil = was_nogil
5057 def generate_execution_code(self, code):
5058 code.mark_pos(self.pos)
5059 if self.state == 'gil':
5060 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5062 code.putln("{ PyThreadState *_save;")
5063 code.putln("Py_UNBLOCK_THREADS")
5064 TryFinallyStatNode.generate_execution_code(self, code)
5068 class GILExitNode(StatNode):
5069 # Used as the 'finally' block in a GILStatNode
5071 # state string 'gil' or 'nogil'
5075 def analyse_expressions(self, env):
5078 def generate_execution_code(self, code):
5079 if self.state == 'gil':
5080 code.putln("PyGILState_Release();")
5082 code.putln("Py_BLOCK_THREADS")
5085 class CImportStatNode(StatNode):
5088 # module_name string Qualified name of module being imported
5089 # as_name string or None Name specified in "as" clause, if any
5093 def analyse_declarations(self, env):
5094 if not env.is_module_scope:
5095 error(self.pos, "cimport only allowed at module level")
5097 module_scope = env.find_module(self.module_name, self.pos)
5098 if "." in self.module_name:
5099 names = [EncodedString(name) for name in self.module_name.split(".")]
5101 top_module_scope = env.context.find_submodule(top_name)
5102 module_scope = top_module_scope
5103 for name in names[1:]:
5104 submodule_scope = module_scope.find_submodule(name)
5105 module_scope.declare_module(name, submodule_scope, self.pos)
5106 module_scope = submodule_scope
5108 env.declare_module(self.as_name, module_scope, self.pos)
5110 env.declare_module(top_name, top_module_scope, self.pos)
5112 name = self.as_name or self.module_name
5113 env.declare_module(name, module_scope, self.pos)
5115 def analyse_expressions(self, env):
5118 def generate_execution_code(self, code):
5122 class FromCImportStatNode(StatNode):
5123 # from ... cimport statement
5125 # module_name string Qualified name of module
5126 # imported_names [(pos, name, as_name, kind)] Names to be imported
5130 def analyse_declarations(self, env):
5131 if not env.is_module_scope:
5132 error(self.pos, "cimport only allowed at module level")
5134 module_scope = env.find_module(self.module_name, self.pos)
5135 env.add_imported_module(module_scope)
5136 for pos, name, as_name, kind in self.imported_names:
5138 for local_name, entry in module_scope.entries.items():
5139 env.add_imported_entry(local_name, entry, pos)
5141 entry = module_scope.lookup(name)
5143 if kind and not self.declaration_matches(entry, kind):
5144 entry.redeclared(pos)
5146 if kind == 'struct' or kind == 'union':
5147 entry = module_scope.declare_struct_or_union(name,
5148 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5149 elif kind == 'class':
5150 entry = module_scope.declare_c_class(name, pos = pos,
5151 module_name = self.module_name)
5153 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5154 if submodule_scope.parent_module is module_scope:
5155 env.declare_module(as_name or name, submodule_scope, self.pos)
5157 error(pos, "Name '%s' not declared in module '%s'"
5158 % (name, self.module_name))
5161 local_name = as_name or name
5162 env.add_imported_entry(local_name, entry, pos)
5164 def declaration_matches(self, entry, kind):
5165 if not entry.is_type:
5169 if not type.is_extension_type:
5172 if not type.is_struct_or_union:
5174 if kind != type.kind:
5178 def analyse_expressions(self, env):
5181 def generate_execution_code(self, code):
5185 class FromImportStatNode(StatNode):
5186 # from ... import statement
5189 # items [(string, NameNode)]
5190 # interned_items [(string, NameNode, ExprNode)]
5191 # item PyTempNode used internally
5192 # import_star boolean used internally
5194 child_attrs = ["module"]
5197 def analyse_declarations(self, env):
5198 for name, target in self.items:
5200 if not env.is_module_scope:
5201 error(self.pos, "import * only allowed at module level")
5203 env.has_import_star = 1
5204 self.import_star = 1
5206 target.analyse_target_declaration(env)
5208 def analyse_expressions(self, env):
5210 self.module.analyse_expressions(env)
5211 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5212 self.interned_items = []
5213 for name, target in self.items:
5215 for _, entry in env.entries.items():
5216 if not entry.is_type and entry.type.is_extension_type:
5217 env.use_utility_code(ExprNodes.type_test_utility_code)
5220 entry = env.lookup(target.name)
5221 # check whether or not entry is already cimported
5222 if (entry.is_type and entry.type.name == name
5223 and hasattr(entry.type, 'module_name')):
5224 if entry.type.module_name == self.module.module_name.value:
5225 # cimported with absolute name
5228 # cimported with relative name
5229 module = env.find_module(self.module.module_name.value,
5231 if entry.type.module_name == module.qualified_name:
5233 except AttributeError:
5235 target.analyse_target_expression(env, None)
5236 if target.type is py_object_type:
5239 coerced_item = self.item.coerce_to(target.type, env)
5240 self.interned_items.append((name, target, coerced_item))
5242 def generate_execution_code(self, code):
5243 self.module.generate_evaluation_code(code)
5244 if self.import_star:
5246 'if (%s(%s) < 0) %s;' % (
5248 self.module.py_result(),
5249 code.error_goto(self.pos)))
5250 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5251 self.item.set_cname(item_temp)
5252 for name, target, coerced_item in self.interned_items:
5253 cname = code.intern_identifier(name)
5255 '%s = PyObject_GetAttr(%s, %s); %s' % (
5257 self.module.py_result(),
5259 code.error_goto_if_null(item_temp, self.pos)))
5260 code.put_gotref(item_temp)
5261 if coerced_item is None:
5262 target.generate_assignment_code(self.item, code)
5264 coerced_item.allocate_temp_result(code)
5265 coerced_item.generate_result_code(code)
5266 target.generate_assignment_code(coerced_item, code)
5267 code.put_decref_clear(item_temp, py_object_type)
5268 code.funcstate.release_temp(item_temp)
5269 self.module.generate_disposal_code(code)
5270 self.module.free_temps(code)
5274 #------------------------------------------------------------------------------------
5276 # Runtime support code
5278 #------------------------------------------------------------------------------------
5280 utility_function_predeclarations = \
5282 /* inline attribute */
5283 #ifndef CYTHON_INLINE
5284 #if defined(__GNUC__)
5285 #define CYTHON_INLINE __inline__
5286 #elif defined(_MSC_VER)
5287 #define CYTHON_INLINE __inline
5288 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5289 #define CYTHON_INLINE inline
5291 #define CYTHON_INLINE
5295 /* unused attribute */
5296 #ifndef CYTHON_UNUSED
5297 # if defined(__GNUC__)
5298 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5299 # define CYTHON_UNUSED __attribute__ ((__unused__))
5301 # define CYTHON_UNUSED
5303 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5304 # define CYTHON_UNUSED __attribute__ ((__unused__))
5306 # define CYTHON_UNUSED
5310 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*/
5314 if Options.gcc_branch_hints:
5315 branch_prediction_macros = \
5318 /* Test for GCC > 2.95 */
5319 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5320 #define likely(x) __builtin_expect(!!(x), 1)
5321 #define unlikely(x) __builtin_expect(!!(x), 0)
5322 #else /* __GNUC__ > 2 ... */
5323 #define likely(x) (x)
5324 #define unlikely(x) (x)
5325 #endif /* __GNUC__ > 2 ... */
5326 #else /* __GNUC__ */
5327 #define likely(x) (x)
5328 #define unlikely(x) (x)
5329 #endif /* __GNUC__ */
5332 branch_prediction_macros = \
5334 #define likely(x) (x)
5335 #define unlikely(x) (x)
5338 #get_name_predeclaration = \
5339 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5341 #get_name_interned_predeclaration = \
5342 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5344 #------------------------------------------------------------------------------------
5346 printing_utility_code = UtilityCode(
5348 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5349 #if PY_MAJOR_VERSION >= 3
5350 static PyObject* %s = 0;
5351 static PyObject* %s = 0;
5353 """ % (Naming.print_function, Naming.print_function_kwargs),
5355 #if PY_MAJOR_VERSION >= 3
5359 """ % (Naming.print_function, Naming.print_function_kwargs),
5361 #if PY_MAJOR_VERSION < 3
5362 static PyObject *__Pyx_GetStdout(void) {
5363 PyObject *f = PySys_GetObject((char *)"stdout");
5365 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5370 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5375 if (!(f = __Pyx_GetStdout()))
5378 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5379 if (PyFile_SoftSpace(f, 1)) {
5380 if (PyFile_WriteString(" ", f) < 0)
5383 v = PyTuple_GET_ITEM(arg_tuple, i);
5384 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5386 if (PyString_Check(v)) {
5387 char *s = PyString_AsString(v);
5388 Py_ssize_t len = PyString_Size(v);
5390 isspace(Py_CHARMASK(s[len-1])) &&
5392 PyFile_SoftSpace(f, 0);
5396 if (PyFile_WriteString("\n", f) < 0)
5398 PyFile_SoftSpace(f, 0);
5403 #else /* Python 3 has a print function */
5405 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5406 PyObject* kwargs = 0;
5407 PyObject* result = 0;
5408 PyObject* end_string;
5409 if (unlikely(!%(PRINT_FUNCTION)s)) {
5410 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5411 if (!%(PRINT_FUNCTION)s)
5415 kwargs = PyDict_New();
5416 if (unlikely(!kwargs))
5418 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5421 end_string = PyUnicode_FromStringAndSize(" ", 1);
5422 if (unlikely(!end_string))
5424 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5425 Py_DECREF(end_string);
5428 Py_DECREF(end_string);
5430 } else if (!newline) {
5431 if (unlikely(!%(PRINT_KWARGS)s)) {
5432 %(PRINT_KWARGS)s = PyDict_New();
5433 if (unlikely(!%(PRINT_KWARGS)s))
5435 end_string = PyUnicode_FromStringAndSize(" ", 1);
5436 if (unlikely(!end_string))
5438 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5439 Py_DECREF(end_string);
5442 Py_DECREF(end_string);
5444 kwargs = %(PRINT_KWARGS)s;
5446 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5447 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5454 if (kwargs != %(PRINT_KWARGS)s)
5460 """ % {'BUILTINS' : Naming.builtins_cname,
5461 'PRINT_FUNCTION' : Naming.print_function,
5462 'PRINT_KWARGS' : Naming.print_function_kwargs}
5466 printing_one_utility_code = UtilityCode(
5468 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5471 #if PY_MAJOR_VERSION < 3
5473 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5475 if (!(f = __Pyx_GetStdout()))
5478 if (PyFile_SoftSpace(f, 0)) {
5479 if (PyFile_WriteString(" ", f) < 0)
5482 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5484 if (PyFile_WriteString("\n", f) < 0)
5487 /* the line below is just to avoid compiler
5488 * compiler warnings about unused functions */
5489 return __Pyx_Print(f, NULL, 0);
5492 #else /* Python 3 has a print function */
5494 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5496 PyObject* arg_tuple = PyTuple_New(1);
5497 if (unlikely(!arg_tuple))
5500 PyTuple_SET_ITEM(arg_tuple, 0, o);
5501 res = __Pyx_Print(stream, arg_tuple, 1);
5502 Py_DECREF(arg_tuple);
5508 requires=[printing_utility_code])
5512 #------------------------------------------------------------------------------------
5514 # Exception raising code
5516 # Exceptions are raised by __Pyx_Raise() and stored as plain
5517 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5518 # 'except' statement, curexc_* is moved over to exc_* by
5519 # __Pyx_GetException()
5521 restore_exception_utility_code = UtilityCode(
5523 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5524 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5527 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5528 PyObject *tmp_type, *tmp_value, *tmp_tb;
5529 PyThreadState *tstate = PyThreadState_GET();
5531 tmp_type = tstate->curexc_type;
5532 tmp_value = tstate->curexc_value;
5533 tmp_tb = tstate->curexc_traceback;
5534 tstate->curexc_type = type;
5535 tstate->curexc_value = value;
5536 tstate->curexc_traceback = tb;
5537 Py_XDECREF(tmp_type);
5538 Py_XDECREF(tmp_value);
5542 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5543 PyThreadState *tstate = PyThreadState_GET();
5544 *type = tstate->curexc_type;
5545 *value = tstate->curexc_value;
5546 *tb = tstate->curexc_traceback;
5548 tstate->curexc_type = 0;
5549 tstate->curexc_value = 0;
5550 tstate->curexc_traceback = 0;
5555 # The following function is based on do_raise() from ceval.c. There
5556 # are separate versions for Python2 and Python3 as exception handling
5557 # has changed quite a lot between the two versions.
5559 raise_utility_code = UtilityCode(
5561 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5564 #if PY_MAJOR_VERSION < 3
5565 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5569 /* First, check the traceback argument, replacing None with NULL. */
5570 if (tb == Py_None) {
5574 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5575 PyErr_SetString(PyExc_TypeError,
5576 "raise: arg 3 must be a traceback or None");
5579 /* Next, replace a missing value with None */
5580 if (value == NULL) {
5584 #if PY_VERSION_HEX < 0x02050000
5585 if (!PyClass_Check(type))
5587 if (!PyType_Check(type))
5590 /* Raising an instance. The value should be a dummy. */
5591 if (value != Py_None) {
5592 PyErr_SetString(PyExc_TypeError,
5593 "instance exception may not have a separate value");
5596 /* Normalize to raise <class>, <instance> */
5599 #if PY_VERSION_HEX < 0x02050000
5600 if (PyInstance_Check(type)) {
5601 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5606 PyErr_SetString(PyExc_TypeError,
5607 "raise: exception must be an old-style class or instance");
5611 type = (PyObject*) Py_TYPE(type);
5613 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5614 PyErr_SetString(PyExc_TypeError,
5615 "raise: exception class must be a subclass of BaseException");
5621 __Pyx_ErrRestore(type, value, tb);
5630 #else /* Python 3+ */
5632 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5633 if (tb == Py_None) {
5635 } else if (tb && !PyTraceBack_Check(tb)) {
5636 PyErr_SetString(PyExc_TypeError,
5637 "raise: arg 3 must be a traceback or None");
5640 if (value == Py_None)
5643 if (PyExceptionInstance_Check(type)) {
5645 PyErr_SetString(PyExc_TypeError,
5646 "instance exception may not have a separate value");
5650 type = (PyObject*) Py_TYPE(value);
5651 } else if (!PyExceptionClass_Check(type)) {
5652 PyErr_SetString(PyExc_TypeError,
5653 "raise: exception class must be a subclass of BaseException");
5657 PyErr_SetObject(type, value);
5660 PyThreadState *tstate = PyThreadState_GET();
5661 PyObject* tmp_tb = tstate->curexc_traceback;
5664 tstate->curexc_traceback = tb;
5674 requires=[restore_exception_utility_code])
5676 #------------------------------------------------------------------------------------
5678 get_exception_utility_code = UtilityCode(
5680 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5683 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5684 PyObject *local_type, *local_value, *local_tb;
5685 PyObject *tmp_type, *tmp_value, *tmp_tb;
5686 PyThreadState *tstate = PyThreadState_GET();
5687 local_type = tstate->curexc_type;
5688 local_value = tstate->curexc_value;
5689 local_tb = tstate->curexc_traceback;
5690 tstate->curexc_type = 0;
5691 tstate->curexc_value = 0;
5692 tstate->curexc_traceback = 0;
5693 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5694 if (unlikely(tstate->curexc_type))
5696 #if PY_MAJOR_VERSION >= 3
5697 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5701 *value = local_value;
5703 Py_INCREF(local_type);
5704 Py_INCREF(local_value);
5705 Py_INCREF(local_tb);
5706 tmp_type = tstate->exc_type;
5707 tmp_value = tstate->exc_value;
5708 tmp_tb = tstate->exc_traceback;
5709 tstate->exc_type = local_type;
5710 tstate->exc_value = local_value;
5711 tstate->exc_traceback = local_tb;
5712 /* Make sure tstate is in a consistent state when we XDECREF
5713 these objects (XDECREF may run arbitrary code). */
5714 Py_XDECREF(tmp_type);
5715 Py_XDECREF(tmp_value);
5722 Py_XDECREF(local_type);
5723 Py_XDECREF(local_value);
5724 Py_XDECREF(local_tb);
5730 #------------------------------------------------------------------------------------
5732 get_exception_tuple_utility_code = UtilityCode(proto="""
5733 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5735 # I doubt that calling __Pyx_GetException() here is correct as it moves
5736 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5737 # exception handlers later on from receiving it.
5739 static PyObject *__Pyx_GetExceptionTuple(void) {
5740 PyObject *type = NULL, *value = NULL, *tb = NULL;
5741 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5742 PyObject* exc_info = PyTuple_New(3);
5747 PyTuple_SET_ITEM(exc_info, 0, type);
5748 PyTuple_SET_ITEM(exc_info, 1, value);
5749 PyTuple_SET_ITEM(exc_info, 2, tb);
5756 requires=[get_exception_utility_code])
5758 #------------------------------------------------------------------------------------
5760 reset_exception_utility_code = UtilityCode(
5762 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5763 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5766 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5767 PyThreadState *tstate = PyThreadState_GET();
5768 *type = tstate->exc_type;
5769 *value = tstate->exc_value;
5770 *tb = tstate->exc_traceback;
5776 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5777 PyObject *tmp_type, *tmp_value, *tmp_tb;
5778 PyThreadState *tstate = PyThreadState_GET();
5779 tmp_type = tstate->exc_type;
5780 tmp_value = tstate->exc_value;
5781 tmp_tb = tstate->exc_traceback;
5782 tstate->exc_type = type;
5783 tstate->exc_value = value;
5784 tstate->exc_traceback = tb;
5785 Py_XDECREF(tmp_type);
5786 Py_XDECREF(tmp_value);
5791 #------------------------------------------------------------------------------------
5793 arg_type_test_utility_code = UtilityCode(
5795 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5796 const char *name, int exact); /*proto*/
5799 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5800 const char *name, int exact)
5803 PyErr_Format(PyExc_SystemError, "Missing type object");
5806 if (none_allowed && obj == Py_None) return 1;
5808 if (Py_TYPE(obj) == type) return 1;
5811 if (PyObject_TypeCheck(obj, type)) return 1;
5813 PyErr_Format(PyExc_TypeError,
5814 "Argument '%s' has incorrect type (expected %s, got %s)",
5815 name, type->tp_name, Py_TYPE(obj)->tp_name);
5820 #------------------------------------------------------------------------------------
5822 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5823 # many or too few positional arguments were found. This handles
5824 # Py_ssize_t formatting correctly.
5826 raise_argtuple_invalid_utility_code = UtilityCode(
5828 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5829 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5832 static void __Pyx_RaiseArgtupleInvalid(
5833 const char* func_name,
5837 Py_ssize_t num_found)
5839 Py_ssize_t num_expected;
5840 const char *number, *more_or_less;
5842 if (num_found < num_min) {
5843 num_expected = num_min;
5844 more_or_less = "at least";
5846 num_expected = num_max;
5847 more_or_less = "at most";
5850 more_or_less = "exactly";
5852 number = (num_expected == 1) ? "" : "s";
5853 PyErr_Format(PyExc_TypeError,
5854 #if PY_VERSION_HEX < 0x02050000
5855 "%s() takes %s %d positional argument%s (%d given)",
5857 "%s() takes %s %zd positional argument%s (%zd given)",
5859 func_name, more_or_less, num_expected, number, num_found);
5863 raise_keyword_required_utility_code = UtilityCode(
5865 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5868 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5869 const char* func_name,
5872 PyErr_Format(PyExc_TypeError,
5873 #if PY_MAJOR_VERSION >= 3
5874 "%s() needs keyword-only argument %U", func_name, kw_name);
5876 "%s() needs keyword-only argument %s", func_name,
5877 PyString_AS_STRING(kw_name));
5882 raise_double_keywords_utility_code = UtilityCode(
5884 static void __Pyx_RaiseDoubleKeywordsError(
5885 const char* func_name, PyObject* kw_name); /*proto*/
5888 static void __Pyx_RaiseDoubleKeywordsError(
5889 const char* func_name,
5892 PyErr_Format(PyExc_TypeError,
5893 #if PY_MAJOR_VERSION >= 3
5894 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5896 "%s() got multiple values for keyword argument '%s'", func_name,
5897 PyString_AS_STRING(kw_name));
5902 #------------------------------------------------------------------------------------
5904 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5905 # were passed to a function, or if any keywords were passed to a
5906 # function that does not accept them.
5908 keyword_string_check_utility_code = UtilityCode(
5910 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5911 const char* function_name, int kw_allowed); /*proto*/
5914 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5916 const char* function_name,
5921 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5922 #if PY_MAJOR_VERSION < 3
5923 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5925 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5927 goto invalid_keyword_type;
5929 if ((!kw_allowed) && unlikely(key))
5930 goto invalid_keyword;
5932 invalid_keyword_type:
5933 PyErr_Format(PyExc_TypeError,
5934 "%s() keywords must be strings", function_name);
5937 PyErr_Format(PyExc_TypeError,
5938 #if PY_MAJOR_VERSION < 3
5939 "%s() got an unexpected keyword argument '%s'",
5940 function_name, PyString_AsString(key));
5942 "%s() got an unexpected keyword argument '%U'",
5943 function_name, key);
5949 #------------------------------------------------------------------------------------
5951 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5952 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5953 # keywords will raise an invalid keyword error.
5955 # Three kinds of errors are checked: 1) non-string keywords, 2)
5956 # unexpected keywords and 3) overlap with positional arguments.
5958 # If num_posargs is greater 0, it denotes the number of positional
5959 # arguments that were passed and that must therefore not appear
5960 # amongst the keywords as well.
5962 # This method does not check for required keyword arguments.
5965 parse_keywords_utility_code = UtilityCode(
5967 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5968 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5969 const char* function_name); /*proto*/
5972 static int __Pyx_ParseOptionalKeywords(
5974 PyObject **argnames[],
5977 Py_ssize_t num_pos_args,
5978 const char* function_name)
5980 PyObject *key = 0, *value = 0;
5983 PyObject*** first_kw_arg = argnames + num_pos_args;
5985 while (PyDict_Next(kwds, &pos, &key, &value)) {
5986 name = first_kw_arg;
5987 while (*name && (**name != key)) name++;
5989 values[name-argnames] = value;
5991 #if PY_MAJOR_VERSION < 3
5992 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5994 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5996 goto invalid_keyword_type;
5998 for (name = first_kw_arg; *name; name++) {
5999 #if PY_MAJOR_VERSION >= 3
6000 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6001 PyUnicode_Compare(**name, key) == 0) break;
6003 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6004 _PyString_Eq(**name, key)) break;
6008 values[name-argnames] = value;
6010 /* unexpected keyword found */
6011 for (name=argnames; name != first_kw_arg; name++) {
6012 if (**name == key) goto arg_passed_twice;
6013 #if PY_MAJOR_VERSION >= 3
6014 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6015 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6017 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6018 _PyString_Eq(**name, key)) goto arg_passed_twice;
6022 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6024 goto invalid_keyword;
6032 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6034 invalid_keyword_type:
6035 PyErr_Format(PyExc_TypeError,
6036 "%s() keywords must be strings", function_name);
6039 PyErr_Format(PyExc_TypeError,
6040 #if PY_MAJOR_VERSION < 3
6041 "%s() got an unexpected keyword argument '%s'",
6042 function_name, PyString_AsString(key));
6044 "%s() got an unexpected keyword argument '%U'",
6045 function_name, key);
6052 #------------------------------------------------------------------------------------
6054 traceback_utility_code = UtilityCode(
6056 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6059 #include "compile.h"
6060 #include "frameobject.h"
6061 #include "traceback.h"
6063 static void __Pyx_AddTraceback(const char *funcname) {
6064 PyObject *py_srcfile = 0;
6065 PyObject *py_funcname = 0;
6066 PyObject *py_globals = 0;
6067 PyCodeObject *py_code = 0;
6068 PyFrameObject *py_frame = 0;
6070 #if PY_MAJOR_VERSION < 3
6071 py_srcfile = PyString_FromString(%(FILENAME)s);
6073 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6075 if (!py_srcfile) goto bad;
6077 #if PY_MAJOR_VERSION < 3
6078 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6080 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6084 #if PY_MAJOR_VERSION < 3
6085 py_funcname = PyString_FromString(funcname);
6087 py_funcname = PyUnicode_FromString(funcname);
6090 if (!py_funcname) goto bad;
6091 py_globals = PyModule_GetDict(%(GLOBALS)s);
6092 if (!py_globals) goto bad;
6093 py_code = PyCode_New(
6094 0, /*int argcount,*/
6095 #if PY_MAJOR_VERSION >= 3
6096 0, /*int kwonlyargcount,*/
6099 0, /*int stacksize,*/
6101 %(EMPTY_BYTES)s, /*PyObject *code,*/
6102 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6103 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6104 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6105 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6106 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6107 py_srcfile, /*PyObject *filename,*/
6108 py_funcname, /*PyObject *name,*/
6109 %(LINENO)s, /*int firstlineno,*/
6110 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6112 if (!py_code) goto bad;
6113 py_frame = PyFrame_New(
6114 PyThreadState_GET(), /*PyThreadState *tstate,*/
6115 py_code, /*PyCodeObject *code,*/
6116 py_globals, /*PyObject *globals,*/
6117 0 /*PyObject *locals*/
6119 if (!py_frame) goto bad;
6120 py_frame->f_lineno = %(LINENO)s;
6121 PyTraceBack_Here(py_frame);
6123 Py_XDECREF(py_srcfile);
6124 Py_XDECREF(py_funcname);
6125 Py_XDECREF(py_code);
6126 Py_XDECREF(py_frame);
6129 'FILENAME': Naming.filename_cname,
6130 'LINENO': Naming.lineno_cname,
6131 'CFILENAME': Naming.cfilenm_cname,
6132 'CLINENO': Naming.clineno_cname,
6133 'GLOBALS': Naming.module_cname,
6134 'EMPTY_TUPLE' : Naming.empty_tuple,
6135 'EMPTY_BYTES' : Naming.empty_bytes,
6138 #------------------------------------------------------------------------------------
6140 unraisable_exception_utility_code = UtilityCode(
6142 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6145 static void __Pyx_WriteUnraisable(const char *name) {
6146 PyObject *old_exc, *old_val, *old_tb;
6148 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6149 #if PY_MAJOR_VERSION < 3
6150 ctx = PyString_FromString(name);
6152 ctx = PyUnicode_FromString(name);
6154 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6156 PyErr_WriteUnraisable(Py_None);
6158 PyErr_WriteUnraisable(ctx);
6163 requires=[restore_exception_utility_code])
6165 #------------------------------------------------------------------------------------
6167 set_vtable_utility_code = UtilityCode(
6169 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6172 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6173 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6174 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6176 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6180 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6190 #------------------------------------------------------------------------------------
6192 get_vtable_utility_code = UtilityCode(
6194 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6197 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6198 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6201 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6202 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6204 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6206 if (!*(void **)vtabptr)
6216 #------------------------------------------------------------------------------------
6218 init_string_tab_utility_code = UtilityCode(
6220 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6223 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6225 #if PY_MAJOR_VERSION < 3
6226 if (t->is_unicode) {
6227 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6228 } else if (t->intern) {
6229 *t->p = PyString_InternFromString(t->s);
6231 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6233 #else /* Python 3+ has unicode identifiers */
6234 if (t->is_unicode | t->is_str) {
6236 *t->p = PyUnicode_InternFromString(t->s);
6237 } else if (t->encoding) {
6238 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6240 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6243 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6254 #------------------------------------------------------------------------------------
6256 force_init_threads_utility_code = UtilityCode(
6258 #ifndef __PYX_FORCE_INIT_THREADS
6259 #if PY_VERSION_HEX < 0x02040200
6260 #define __PYX_FORCE_INIT_THREADS 1
6262 #define __PYX_FORCE_INIT_THREADS 0
6267 #------------------------------------------------------------------------------------
6269 # Note that cPython ignores PyTrace_EXCEPTION,
6270 # but maybe some other profilers don't.
6272 profile_utility_code = UtilityCode(proto="""
6273 #ifndef CYTHON_PROFILE
6274 #define CYTHON_PROFILE 1
6277 #ifndef CYTHON_PROFILE_REUSE_FRAME
6278 #define CYTHON_PROFILE_REUSE_FRAME 0
6283 #include "compile.h"
6284 #include "frameobject.h"
6285 #include "traceback.h"
6287 #if CYTHON_PROFILE_REUSE_FRAME
6288 #define CYTHON_FRAME_MODIFIER static
6289 #define CYTHON_FRAME_DEL
6291 #define CYTHON_FRAME_MODIFIER
6292 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6295 #define __Pyx_TraceDeclarations \\
6296 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6297 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6298 int __Pyx_use_tracing = 0;
6300 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6301 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6302 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6305 #define __Pyx_TraceException() \\
6306 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6307 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6309 PyThreadState_GET()->c_profilefunc( \\
6310 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6311 Py_DECREF(exc_info); \\
6315 #define __Pyx_TraceReturn(result) \\
6316 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6317 PyThreadState_GET()->c_profilefunc( \\
6318 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6319 CYTHON_FRAME_DEL; \\
6322 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6323 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6327 #define __Pyx_TraceDeclarations
6328 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6329 #define __Pyx_TraceException()
6330 #define __Pyx_TraceReturn(result)
6332 #endif /* CYTHON_PROFILE */
6335 "FRAME": Naming.frame_cname,
6336 "FRAME_CODE": Naming.frame_code_cname,
6342 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6343 PyFrameObject** frame,
6344 const char *funcname,
6345 const char *srcfile,
6347 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6348 if (*code == NULL) {
6349 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6350 if (*code == NULL) return 0;
6352 *frame = PyFrame_New(
6353 PyThreadState_GET(), /*PyThreadState *tstate*/
6354 *code, /*PyCodeObject *code*/
6355 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6356 0 /*PyObject *locals*/
6358 if (*frame == NULL) return 0;
6361 (*frame)->f_tstate = PyThreadState_GET();
6363 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6366 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6367 PyObject *py_srcfile = 0;
6368 PyObject *py_funcname = 0;
6369 PyCodeObject *py_code = 0;
6371 #if PY_MAJOR_VERSION < 3
6372 py_funcname = PyString_FromString(funcname);
6373 py_srcfile = PyString_FromString(srcfile);
6375 py_funcname = PyUnicode_FromString(funcname);
6376 py_srcfile = PyUnicode_FromString(srcfile);
6378 if (!py_funcname | !py_srcfile) goto bad;
6380 py_code = PyCode_New(
6381 0, /*int argcount,*/
6382 #if PY_MAJOR_VERSION >= 3
6383 0, /*int kwonlyargcount,*/
6386 0, /*int stacksize,*/
6388 %(EMPTY_BYTES)s, /*PyObject *code,*/
6389 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6390 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6391 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6392 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6393 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6394 py_srcfile, /*PyObject *filename,*/
6395 py_funcname, /*PyObject *name,*/
6396 firstlineno, /*int firstlineno,*/
6397 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6401 Py_XDECREF(py_srcfile);
6402 Py_XDECREF(py_funcname);
6407 #endif /* CYTHON_PROFILE */
6409 'EMPTY_TUPLE' : Naming.empty_tuple,
6410 'EMPTY_BYTES' : Naming.empty_bytes,
6411 "MODULE": Naming.module_cname,