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 template_types.append(template_node.analyse_as_type(env))
838 self.type = base_type.specialize_here(self.pos, template_types)
840 elif base_type.is_pyobject:
844 options = Buffer.analyse_buffer_options(
847 self.positional_args,
849 base_type.buffer_defaults)
851 if sys.version_info[0] < 3:
852 # Py 2.x enforces byte strings as keyword arguments ...
853 options = dict([ (name.encode('ASCII'), value)
854 for name, value in options.iteritems() ])
856 self.type = PyrexTypes.BufferType(base_type, **options)
860 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
861 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
862 error(self.pos, "invalid array declaration")
863 self.type = PyrexTypes.error_type
865 # It would be nice to merge this class with CArrayDeclaratorNode,
866 # but arrays are part of the declaration, not the type...
867 if not self.positional_args:
870 dimension = self.positional_args[0]
871 self.array_declarator = CArrayDeclaratorNode(self.pos,
872 base = empty_declarator,
873 dimension = dimension)
874 self.type = self.array_declarator.analyse(base_type, env)[1]
878 class CComplexBaseTypeNode(CBaseTypeNode):
879 # base_type CBaseTypeNode
880 # declarator CDeclaratorNode
882 child_attrs = ["base_type", "declarator"]
884 def analyse(self, env, could_be_name = False):
885 base = self.base_type.analyse(env, could_be_name)
886 _, type = self.declarator.analyse(base, env)
890 class CVarDefNode(StatNode):
891 # C variable definition or forward/extern function declaration.
893 # visibility 'private' or 'public' or 'extern'
894 # base_type CBaseTypeNode
895 # declarators [CDeclaratorNode]
900 # decorators [cython.locals(...)] or None
901 # directive_locals { string : NameNode } locals defined by cython.locals(...)
903 child_attrs = ["base_type", "declarators"]
907 directive_locals = {}
909 def analyse_declarations(self, env, dest_scope = None):
912 self.dest_scope = dest_scope
913 base_type = self.base_type.analyse(env)
915 # If the field is an external typedef, we cannot be sure about the type,
916 # so do conversion ourself rather than rely on the CPython mechanism (through
917 # a property; made in AnalyseDeclarationsTransform).
918 if (dest_scope.is_c_class_scope
919 and self.visibility in ('public', 'readonly')):
923 need_property = False
924 visibility = self.visibility
926 for declarator in self.declarators:
927 name_declarator, type = declarator.analyse(base_type, env)
928 if not type.is_complete():
929 if not (self.visibility == 'extern' and type.is_array):
930 error(declarator.pos,
931 "Variable type '%s' is incomplete" % type)
932 if self.visibility == 'extern' and type.is_pyobject:
933 error(declarator.pos,
934 "Python object cannot be declared extern")
935 name = name_declarator.name
936 cname = name_declarator.cname
938 error(declarator.pos, "Missing name in declaration.")
940 if type.is_cfunction:
941 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
942 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
944 if entry is not None:
945 entry.directive_locals = self.directive_locals
947 if self.directive_locals:
948 s.error("Decorators can only be followed by functions")
949 if self.in_pxd and self.visibility != 'extern':
951 "Only 'extern' C variable declaration allowed in .pxd file")
952 entry = dest_scope.declare_var(name, type, declarator.pos,
953 cname = cname, visibility = visibility, is_cdef = 1)
955 self.properties.append(entry)
958 class CStructOrUnionDefNode(StatNode):
960 # cname string or None
961 # kind "struct" or "union"
962 # typedef_flag boolean
963 # visibility "public" or "private"
965 # attributes [CVarDefNode] or None
969 child_attrs = ["attributes"]
971 def analyse_declarations(self, env):
973 if self.visibility == 'extern' and self.packed:
974 error(self.pos, "Cannot declare extern struct as 'packed'")
975 if self.attributes is not None:
976 scope = StructOrUnionScope(self.name)
977 self.entry = env.declare_struct_or_union(
978 self.name, self.kind, scope, self.typedef_flag, self.pos,
979 self.cname, visibility = self.visibility, packed = self.packed)
980 if self.attributes is not None:
981 if self.in_pxd and not env.in_cinclude:
982 self.entry.defined_in_pxd = 1
983 for attr in self.attributes:
984 attr.analyse_declarations(env, scope)
985 if self.visibility != 'extern':
986 need_typedef_indirection = False
987 for attr in scope.var_entries:
990 type = type.base_type
991 if type == self.entry.type:
992 error(attr.pos, "Struct cannot contain itself as a member.")
993 if self.typedef_flag:
995 type = type.base_type
996 if type == self.entry.type:
997 need_typedef_indirection = True
998 if need_typedef_indirection:
999 # C can't handle typedef structs that refer to themselves.
1000 struct_entry = self.entry
1001 self.entry = env.declare_typedef(
1002 self.name, struct_entry.type, self.pos,
1003 cname = self.cname, visibility='ignore')
1004 struct_entry.type.typedef_flag = False
1005 # FIXME: this might be considered a hack ;-)
1006 struct_entry.cname = struct_entry.type.cname = \
1007 '_' + self.entry.type.typedef_cname
1009 def analyse_expressions(self, env):
1012 def generate_execution_code(self, code):
1016 class CppClassNode(CStructOrUnionDefNode):
1019 # cname string or None
1020 # visibility "extern"
1022 # attributes [CVarDefNode] or None
1024 # base_classes [string]
1025 # templates [string] or None
1027 def analyse_declarations(self, env):
1029 if self.attributes is not None:
1030 scope = CppClassScope(self.name, env)
1031 base_class_types = []
1032 for base_class_name in self.base_classes:
1033 base_class_entry = env.lookup(base_class_name)
1034 if base_class_entry is None:
1035 error(self.pos, "'%s' not found" % base_class_name)
1036 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1037 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1039 base_class_types.append(base_class_entry.type)
1040 if self.templates is None:
1041 template_types = None
1043 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1044 self.entry = env.declare_cpp_class(
1045 self.name, scope, self.pos,
1046 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1047 self.entry.is_cpp_class = 1
1048 if self.attributes is not None:
1049 if self.in_pxd and not env.in_cinclude:
1050 self.entry.defined_in_pxd = 1
1051 for attr in self.attributes:
1052 attr.analyse_declarations(scope)
1054 class CEnumDefNode(StatNode):
1055 # name string or None
1056 # cname string or None
1057 # items [CEnumDefItemNode]
1058 # typedef_flag boolean
1059 # visibility "public" or "private"
1063 child_attrs = ["items"]
1065 def analyse_declarations(self, env):
1066 self.entry = env.declare_enum(self.name, self.pos,
1067 cname = self.cname, typedef_flag = self.typedef_flag,
1068 visibility = self.visibility)
1069 if self.items is not None:
1070 if self.in_pxd and not env.in_cinclude:
1071 self.entry.defined_in_pxd = 1
1072 for item in self.items:
1073 item.analyse_declarations(env, self.entry)
1075 def analyse_expressions(self, env):
1078 def generate_execution_code(self, code):
1079 if self.visibility == 'public':
1080 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1081 for item in self.entry.enum_values:
1082 code.putln("%s = PyInt_FromLong(%s); %s" % (
1085 code.error_goto_if_null(temp, item.pos)))
1086 code.put_gotref(temp)
1087 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1088 Naming.module_cname,
1091 code.error_goto(item.pos)))
1092 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1093 code.funcstate.release_temp(temp)
1096 class CEnumDefItemNode(StatNode):
1098 # cname string or None
1099 # value ExprNode or None
1101 child_attrs = ["value"]
1103 def analyse_declarations(self, env, enum_entry):
1105 self.value.analyse_const_expression(env)
1106 if not self.value.type.is_int:
1107 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1108 self.value.analyse_const_expression(env)
1109 entry = env.declare_const(self.name, enum_entry.type,
1110 self.value, self.pos, cname = self.cname,
1111 visibility = enum_entry.visibility)
1112 enum_entry.enum_values.append(entry)
1115 class CTypeDefNode(StatNode):
1116 # base_type CBaseTypeNode
1117 # declarator CDeclaratorNode
1118 # visibility "public" or "private"
1121 child_attrs = ["base_type", "declarator"]
1123 def analyse_declarations(self, env):
1124 base = self.base_type.analyse(env)
1125 name_declarator, type = self.declarator.analyse(base, env)
1126 name = name_declarator.name
1127 cname = name_declarator.cname
1128 entry = env.declare_typedef(name, type, self.pos,
1129 cname = cname, visibility = self.visibility)
1130 if self.in_pxd and not env.in_cinclude:
1131 entry.defined_in_pxd = 1
1133 def analyse_expressions(self, env):
1135 def generate_execution_code(self, code):
1139 class FuncDefNode(StatNode, BlockNode):
1140 # Base class for function definition nodes.
1142 # return_type PyrexType
1143 # #filename string C name of filename string const
1144 # entry Symtab.Entry
1145 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1146 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1150 needs_closure = False
1153 def analyse_default_values(self, env):
1154 genv = env.global_scope()
1156 for arg in self.args:
1160 arg.default.analyse_types(env)
1161 arg.default = arg.default.coerce_to(arg.type, genv)
1164 "This argument cannot have a default value")
1169 error(arg.pos, "Non-default argument following default argument")
1171 def need_gil_acquisition(self, lenv):
1174 def create_local_scope(self, env):
1176 while genv.is_py_class_scope or genv.is_c_class_scope:
1177 genv = env.outer_scope
1178 if self.needs_closure:
1179 lenv = ClosureScope(name=self.entry.name,
1181 scope_name=self.entry.cname)
1183 lenv = LocalScope(name=self.entry.name,
1186 lenv.return_type = self.return_type
1187 type = self.entry.type
1188 if type.is_cfunction:
1189 lenv.nogil = type.nogil and not type.with_gil
1190 self.local_scope = lenv
1191 lenv.directives = env.directives
1194 def generate_function_definitions(self, env, code):
1197 lenv = self.local_scope
1198 if lenv.is_closure_scope:
1199 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1200 Naming.outer_scope_cname)
1202 outer_scope_cname = Naming.outer_scope_cname
1203 lenv.mangle_closure_cnames(outer_scope_cname)
1204 # Generate closure function definitions
1205 self.body.generate_function_definitions(lenv, code)
1206 # generate lambda function definitions
1207 for node in lenv.lambda_defs:
1208 node.generate_function_definitions(lenv, code)
1210 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1211 self.entry.scope.is_c_class_scope)
1212 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1213 self.entry.scope.is_c_class_scope)
1214 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1216 if 'cython_unused' not in self.modifiers:
1217 self.modifiers = self.modifiers + ['cython_unused']
1219 profile = code.globalstate.directives['profile']
1222 error(self.pos, "Cannot profile nogil function.")
1223 code.globalstate.use_utility_code(profile_utility_code)
1225 # Generate C code for header and body of function
1226 code.enter_cfunc_scope()
1227 code.return_from_error_cleanup_label = code.new_label()
1229 # ----- Top-level constants used by this function
1230 code.mark_pos(self.pos)
1231 self.generate_cached_builtins_decls(lenv, code)
1232 # ----- Function header
1234 with_pymethdef = self.needs_assignment_synthesis(env, code)
1236 self.py_func.generate_function_header(code,
1237 with_pymethdef = with_pymethdef,
1239 self.generate_function_header(code,
1240 with_pymethdef = with_pymethdef)
1241 # ----- Local variable declarations
1242 if lenv.is_closure_scope:
1243 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1245 elif env.is_closure_scope:
1246 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1248 self.generate_argument_declarations(lenv, code)
1249 for entry in lenv.var_entries:
1250 if not entry.in_closure:
1251 code.put_var_declaration(entry)
1253 if not self.return_type.is_void:
1254 if self.return_type.is_pyobject:
1258 (self.return_type.declaration_code(Naming.retval_cname),
1260 tempvardecl_code = code.insertion_point()
1261 self.generate_keyword_list(code)
1263 code.put_trace_declarations()
1264 # ----- Extern library function declarations
1265 lenv.generate_library_function_declarations(code)
1266 # ----- GIL acquisition
1267 acquire_gil = self.acquire_gil
1269 env.use_utility_code(force_init_threads_utility_code)
1270 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1271 # ----- set up refnanny
1273 code.put_setup_refcount_context(self.entry.name)
1274 # ----- Automatic lead-ins for certain special functions
1275 if is_getbuffer_slot:
1276 self.getbuffer_init(code)
1277 # ----- Create closure scope object
1278 if self.needs_closure:
1279 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1280 Naming.cur_scope_cname,
1281 lenv.scope_class.type.declaration_code(''),
1282 lenv.scope_class.type.typeptr_cname,
1283 lenv.scope_class.type.typeptr_cname,
1284 Naming.empty_tuple))
1285 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1286 if is_getbuffer_slot:
1287 self.getbuffer_error_cleanup(code)
1289 code.put_finish_refcount_context()
1290 # FIXME: what if the error return value is a Python value?
1291 code.putln("return %s;" % self.error_value())
1293 code.put_gotref(Naming.cur_scope_cname)
1294 # Note that it is unsafe to decref the scope at this point.
1295 if env.is_closure_scope:
1296 code.putln("%s = (%s)%s;" % (
1298 env.scope_class.type.declaration_code(''),
1300 if self.needs_closure:
1301 # inner closures own a reference to their outer parent
1302 code.put_incref(outer_scope_cname, env.scope_class.type)
1303 code.put_giveref(outer_scope_cname)
1304 # ----- Trace function call
1306 # this looks a bit late, but if we don't get here due to a
1307 # fatal error before hand, it's not really worth tracing
1308 code.put_trace_call(self.entry.name, self.pos)
1309 # ----- Fetch arguments
1310 self.generate_argument_parsing_code(env, code)
1311 # If an argument is assigned to in the body, we must
1312 # incref it to properly keep track of refcounts.
1313 for entry in lenv.arg_entries:
1314 if entry.type.is_pyobject:
1315 if entry.assignments and not entry.in_closure:
1316 code.put_var_incref(entry)
1317 # ----- Initialise local variables
1318 for entry in lenv.var_entries:
1319 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1320 code.put_init_var_to_py_none(entry)
1321 # ----- Initialise local buffer auxiliary variables
1322 for entry in lenv.var_entries + lenv.arg_entries:
1323 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1324 code.putln("%s.buf = NULL;" %
1325 entry.buffer_aux.buffer_info_var.cname)
1326 # ----- Check and convert arguments
1327 self.generate_argument_type_tests(code)
1328 # ----- Acquire buffer arguments
1329 for entry in lenv.arg_entries:
1330 if entry.type.is_buffer:
1331 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1333 # -------------------------
1334 # ----- Function body -----
1335 # -------------------------
1336 self.body.generate_execution_code(code)
1338 # ----- Default return value
1340 if self.return_type.is_pyobject:
1341 #if self.return_type.is_extension_type:
1342 # lhs = "(PyObject *)%s" % Naming.retval_cname
1344 lhs = Naming.retval_cname
1345 code.put_init_to_py_none(lhs, self.return_type)
1347 val = self.return_type.default_value
1349 code.putln("%s = %s;" % (Naming.retval_cname, val))
1350 # ----- Error cleanup
1351 if code.error_label in code.labels_used:
1352 code.put_goto(code.return_label)
1353 code.put_label(code.error_label)
1354 for cname, type in code.funcstate.all_managed_temps():
1355 code.put_xdecref(cname, type)
1357 # Clean up buffers -- this calls a Python function
1358 # so need to save and restore error state
1359 buffers_present = len(lenv.buffer_entries) > 0
1361 code.globalstate.use_utility_code(restore_exception_utility_code)
1362 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1363 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1364 for entry in lenv.buffer_entries:
1365 Buffer.put_release_buffer_code(code, entry)
1366 #code.putln("%s = 0;" % entry.cname)
1367 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1369 err_val = self.error_value()
1370 exc_check = self.caller_will_check_exceptions()
1371 if err_val is not None or exc_check:
1372 # TODO: Fix exception tracing (though currently unused by cProfile).
1373 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1374 # code.put_trace_exception()
1375 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1377 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1378 % self.entry.qualified_name, 0)
1380 '__Pyx_WriteUnraisable("%s");' %
1381 self.entry.qualified_name)
1382 env.use_utility_code(unraisable_exception_utility_code)
1383 env.use_utility_code(restore_exception_utility_code)
1384 default_retval = self.return_type.default_value
1385 if err_val is None and default_retval:
1386 err_val = default_retval
1387 if err_val is not None:
1388 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1390 if is_getbuffer_slot:
1391 self.getbuffer_error_cleanup(code)
1393 # If we are using the non-error cleanup section we should
1394 # jump past it if we have an error. The if-test below determine
1395 # whether this section is used.
1396 if buffers_present or is_getbuffer_slot:
1397 code.put_goto(code.return_from_error_cleanup_label)
1400 # ----- Non-error return cleanup
1401 code.put_label(code.return_label)
1402 for entry in lenv.buffer_entries:
1404 Buffer.put_release_buffer_code(code, entry)
1405 if is_getbuffer_slot:
1406 self.getbuffer_normal_cleanup(code)
1407 # ----- Return cleanup for both error and no-error return
1408 code.put_label(code.return_from_error_cleanup_label)
1409 if not Options.init_local_none:
1410 for entry in lenv.var_entries:
1411 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1412 entry.xdecref_cleanup = 1
1414 for entry in lenv.var_entries:
1415 if entry.type.is_pyobject:
1416 if entry.used and not entry.in_closure:
1417 code.put_var_decref(entry)
1418 elif entry.in_closure and self.needs_closure:
1419 code.put_giveref(entry.cname)
1420 # Decref any increfed args
1421 for entry in lenv.arg_entries:
1422 if entry.type.is_pyobject:
1423 if entry.in_closure:
1424 code.put_var_giveref(entry)
1425 elif entry.assignments:
1426 code.put_var_decref(entry)
1427 if self.needs_closure:
1428 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1431 # This code is duplicated in ModuleNode.generate_module_init_func
1433 default_retval = self.return_type.default_value
1434 err_val = self.error_value()
1435 if err_val is None and default_retval:
1436 err_val = default_retval
1437 if self.return_type.is_pyobject:
1438 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1440 if self.entry.is_special and self.entry.name == "__hash__":
1441 # Returning -1 for __hash__ is supposed to signal an error
1442 # We do as Python instances and coerce -1 into -2.
1443 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1444 Naming.retval_cname, Naming.retval_cname))
1447 if self.return_type.is_pyobject:
1448 code.put_trace_return(Naming.retval_cname)
1450 code.put_trace_return("Py_None")
1452 code.put_finish_refcount_context()
1455 code.putln("PyGILState_Release(_save);")
1457 if not self.return_type.is_void:
1458 code.putln("return %s;" % Naming.retval_cname)
1461 # ----- Go back and insert temp variable declarations
1462 tempvardecl_code.put_temp_declarations(code.funcstate)
1463 # ----- Python version
1464 code.exit_cfunc_scope()
1466 self.py_func.generate_function_definitions(env, code)
1467 self.generate_wrapper_functions(code)
1469 def declare_argument(self, env, arg):
1470 if arg.type.is_void:
1471 error(arg.pos, "Invalid use of 'void'")
1472 elif not arg.type.is_complete() and not arg.type.is_array:
1474 "Argument type '%s' is incomplete" % arg.type)
1475 return env.declare_arg(arg.name, arg.type, arg.pos)
1477 def generate_arg_type_test(self, arg, code):
1478 # Generate type test for one argument.
1479 if arg.type.typeobj_is_available():
1480 code.globalstate.use_utility_code(arg_type_test_utility_code)
1481 typeptr_cname = arg.type.typeptr_cname
1482 arg_code = "((PyObject *)%s)" % arg.entry.cname
1484 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1489 arg.type.is_builtin_type,
1490 code.error_goto(arg.pos)))
1492 error(arg.pos, "Cannot test type of extern C class "
1493 "without type object name specification")
1495 def generate_arg_none_check(self, arg, code):
1496 # Generate None check for one argument.
1497 code.globalstate.use_utility_code(arg_type_test_utility_code)
1498 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1499 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1501 code.error_goto(arg.pos)))
1504 def generate_wrapper_functions(self, code):
1507 def generate_execution_code(self, code):
1508 # Evaluate and store argument default values
1509 for arg in self.args:
1510 default = arg.default
1512 if not default.is_literal:
1513 default.generate_evaluation_code(code)
1514 default.make_owned_reference(code)
1515 result = default.result_as(arg.type)
1518 arg.calculate_default_value_code(code),
1520 if arg.type.is_pyobject:
1521 code.put_giveref(default.result())
1522 default.generate_post_assignment_code(code)
1523 default.free_temps(code)
1524 # For Python class methods, create and store function object
1526 self.assmt.generate_execution_code(code)
1529 # Special code for the __getbuffer__ function
1531 def getbuffer_init(self, code):
1532 info = self.local_scope.arg_entries[1].cname
1533 # Python 3.0 betas have a bug in memoryview which makes it call
1534 # getbuffer with a NULL parameter. For now we work around this;
1535 # the following line should be removed when this bug is fixed.
1536 code.putln("if (%s == NULL) return 0;" % info)
1537 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1538 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1540 def getbuffer_error_cleanup(self, code):
1541 info = self.local_scope.arg_entries[1].cname
1542 code.put_gotref("%s->obj" % info)
1543 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1546 def getbuffer_normal_cleanup(self, code):
1547 info = self.local_scope.arg_entries[1].cname
1548 code.putln("if (%s->obj == Py_None) {" % info)
1549 code.put_gotref("Py_None")
1550 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1553 class CFuncDefNode(FuncDefNode):
1554 # C function definition.
1556 # modifiers ['inline']
1557 # visibility 'private' or 'public' or 'extern'
1558 # base_type CBaseTypeNode
1559 # declarator CDeclaratorNode
1562 # decorators [DecoratorNode] list of decorators
1564 # with_gil boolean Acquire GIL around body
1566 # py_func wrapper for calling from Python
1567 # overridable whether or not this is a cpdef function
1568 # inline_in_pxd whether this is an inline function in a pxd file
1570 child_attrs = ["base_type", "declarator", "body", "py_func"]
1572 inline_in_pxd = False
1574 directive_locals = {}
1576 def unqualified_name(self):
1577 return self.entry.name
1579 def analyse_declarations(self, env):
1580 self.directive_locals.update(env.directives['locals'])
1581 base_type = self.base_type.analyse(env)
1582 # The 2 here is because we need both function and argument names.
1583 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1584 if not type.is_cfunction:
1586 "Suite attached to non-function declaration")
1587 # Remember the actual type according to the function header
1588 # written here, because the type in the symbol table entry
1589 # may be different if we're overriding a C method inherited
1590 # from the base type of an extension type.
1592 type.is_overridable = self.overridable
1593 declarator = self.declarator
1594 while not hasattr(declarator, 'args'):
1595 declarator = declarator.base
1596 self.args = declarator.args
1597 for formal_arg, type_arg in zip(self.args, type.args):
1598 formal_arg.type = type_arg.type
1599 formal_arg.name = type_arg.name
1600 formal_arg.cname = type_arg.cname
1601 name = name_declarator.name
1602 cname = name_declarator.cname
1603 self.entry = env.declare_cfunction(
1604 name, type, self.pos,
1605 cname = cname, visibility = self.visibility,
1606 defining = self.body is not None,
1607 api = self.api, modifiers = self.modifiers)
1608 self.entry.inline_func_in_pxd = self.inline_in_pxd
1609 self.return_type = type.return_type
1611 if self.overridable and not env.is_module_scope:
1612 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1613 # An error will be produced in the cdef function
1614 self.overridable = False
1616 if self.overridable:
1618 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1619 self.py_func = DefNode(pos = self.pos,
1620 name = self.entry.name,
1623 starstar_arg = None,
1625 body = py_func_body,
1627 self.py_func.is_module_scope = env.is_module_scope
1628 self.py_func.analyse_declarations(env)
1629 self.entry.as_variable = self.py_func.entry
1630 # Reset scope entry the above cfunction
1631 env.entries[name] = self.entry
1632 if not env.is_module_scope or Options.lookup_module_cpdef:
1633 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1634 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1635 self.create_local_scope(env)
1637 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1639 args = self.type.args
1640 if omit_optional_args:
1641 args = args[:len(args) - self.type.optional_arg_count]
1642 arg_names = [arg.name for arg in args]
1644 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1646 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1647 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1648 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1649 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)
1650 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1652 def declare_arguments(self, env):
1653 for arg in self.type.args:
1655 error(arg.pos, "Missing argument name")
1656 self.declare_argument(env, arg)
1658 def need_gil_acquisition(self, lenv):
1659 return self.type.with_gil
1661 def nogil_check(self, env):
1663 with_gil = type.with_gil
1664 if type.nogil and not with_gil:
1665 if type.return_type.is_pyobject:
1667 "Function with Python return type cannot be declared nogil")
1668 for entry in self.local_scope.var_entries:
1669 if entry.type.is_pyobject:
1670 error(self.pos, "Function declared nogil has Python locals or temporaries")
1672 def analyse_expressions(self, env):
1673 self.local_scope.directives = env.directives
1674 if self.py_func is not None:
1675 # this will also analyse the default values
1676 self.py_func.analyse_expressions(env)
1678 self.analyse_default_values(env)
1679 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1681 def needs_assignment_synthesis(self, env, code=None):
1684 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1687 visibility = self.entry.visibility
1688 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1689 arg_decls.append(arg.declaration_code())
1690 if with_dispatch and self.overridable:
1691 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1692 if type.optional_arg_count and with_opt_args:
1693 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1694 if type.has_varargs:
1695 arg_decls.append("...")
1697 arg_decls = ["void"]
1699 cname = self.entry.func_cname
1700 entity = type.function_header_code(cname, ', '.join(arg_decls))
1701 if visibility == 'public':
1702 dll_linkage = "DL_EXPORT"
1705 header = self.return_type.declaration_code(entity,
1706 dll_linkage = dll_linkage)
1707 if visibility == 'extern':
1708 storage_class = "%s " % Naming.extern_c_macro
1709 elif visibility == 'public':
1712 storage_class = "static "
1713 if 'inline' in self.modifiers:
1714 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1715 code.putln("%s%s %s {" % (
1717 ' '.join(self.modifiers).upper(), # macro forms
1720 def generate_argument_declarations(self, env, code):
1721 for arg in self.args:
1723 result = arg.calculate_default_value_code(code)
1724 code.putln('%s = %s;' % (
1725 arg.type.declaration_code(arg.cname), result))
1727 def generate_keyword_list(self, code):
1730 def generate_argument_parsing_code(self, env, code):
1732 if self.type.optional_arg_count:
1733 code.putln('if (%s) {' % Naming.optional_args_cname)
1734 for arg in self.args:
1736 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1737 declarator = arg.declarator
1738 while not hasattr(declarator, 'name'):
1739 declarator = declarator.base
1740 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1742 for _ in range(self.type.optional_arg_count):
1746 def generate_argument_conversion_code(self, code):
1749 def generate_argument_type_tests(self, code):
1750 # Generate type tests for args whose type in a parent
1751 # class is a supertype of the declared type.
1752 for arg in self.type.args:
1753 if arg.needs_type_test:
1754 self.generate_arg_type_test(arg, code)
1755 elif arg.type.is_pyobject and not arg.accept_none:
1756 self.generate_arg_none_check(arg, code)
1758 def error_value(self):
1759 if self.return_type.is_pyobject:
1763 return self.entry.type.exception_value
1765 def caller_will_check_exceptions(self):
1766 return self.entry.type.exception_check
1768 def generate_wrapper_functions(self, code):
1769 # If the C signature of a function has changed, we need to generate
1770 # wrappers to put in the slots here.
1773 func_type = entry.type
1774 while entry.prev_entry is not None:
1776 entry = entry.prev_entry
1777 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1779 self.generate_function_header(code,
1781 with_dispatch = entry.type.is_overridable,
1782 with_opt_args = entry.type.optional_arg_count,
1783 cname = entry.func_cname)
1784 if not self.return_type.is_void:
1786 args = self.type.args
1787 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1788 if entry.type.is_overridable:
1789 arglist.append(Naming.skip_dispatch_cname)
1790 elif func_type.is_overridable:
1792 if entry.type.optional_arg_count:
1793 arglist.append(Naming.optional_args_cname)
1794 elif func_type.optional_arg_count:
1795 arglist.append('NULL')
1796 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1800 class PyArgDeclNode(Node):
1801 # Argument which must be a Python object (used
1802 # for * and ** arguments).
1805 # entry Symtab.Entry
1806 # annotation ExprNode or None Py3 argument annotation
1809 def generate_function_definitions(self, env, code):
1810 self.entry.generate_function_definitions(env, code)
1812 class DecoratorNode(Node):
1815 # decorator NameNode or CallNode or AttributeNode
1816 child_attrs = ['decorator']
1819 class DefNode(FuncDefNode):
1820 # A Python function definition.
1822 # name string the Python name of the function
1823 # lambda_name string the internal name of a lambda 'function'
1824 # decorators [DecoratorNode] list of decorators
1825 # args [CArgDeclNode] formal arguments
1826 # star_arg PyArgDeclNode or None * argument
1827 # starstar_arg PyArgDeclNode or None ** argument
1828 # doc EncodedString or None
1830 # return_type_annotation
1831 # ExprNode or None the Py3 return type annotation
1833 # The following subnode is constructed internally
1834 # when the def statement is inside a Python class definition.
1836 # assmt AssignmentNode Function construction/assignment
1838 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1843 num_required_kw_args = 0
1844 reqd_kw_flags_cname = "0"
1847 return_type_annotation = None
1852 def __init__(self, pos, **kwds):
1853 FuncDefNode.__init__(self, pos, **kwds)
1855 for arg in self.args:
1862 self.num_kwonly_args = k
1863 self.num_required_kw_args = rk
1864 self.num_required_args = r
1866 def as_cfunction(self, cfunc=None, scope=None):
1868 error(self.star_arg.pos, "cdef function cannot have star argument")
1869 if self.starstar_arg:
1870 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1873 for formal_arg in self.args:
1874 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1875 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1877 type = py_object_type,
1878 pos = formal_arg.pos))
1879 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1881 has_varargs = False,
1882 exception_value = None,
1883 exception_check = False,
1886 is_overridable = True)
1887 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1889 cfunc_type = cfunc.type
1890 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1891 error(self.pos, "wrong number of arguments")
1892 error(cfunc.pos, "previous declaration here")
1893 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1894 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1895 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1896 formal_arg.type = type_arg.type
1897 formal_arg.name_declarator = name_declarator
1899 if cfunc_type.exception_value is None:
1900 exception_value = None
1902 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1903 declarator = CFuncDeclaratorNode(self.pos,
1904 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1906 has_varargs = False,
1907 exception_check = cfunc_type.exception_check,
1908 exception_value = exception_value,
1909 with_gil = cfunc_type.with_gil,
1910 nogil = cfunc_type.nogil)
1911 return CFuncDefNode(self.pos,
1913 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1914 declarator = declarator,
1917 overridable = cfunc_type.is_overridable,
1919 with_gil = cfunc_type.with_gil,
1920 nogil = cfunc_type.nogil,
1921 visibility = 'private',
1923 directive_locals = getattr(cfunc, 'directive_locals', {}))
1925 def analyse_declarations(self, env):
1926 self.is_classmethod = self.is_staticmethod = False
1928 for decorator in self.decorators:
1929 func = decorator.decorator
1931 self.is_classmethod |= func.name == 'classmethod'
1932 self.is_staticmethod |= func.name == 'staticmethod'
1934 if self.is_classmethod and env.lookup_here('classmethod'):
1935 # classmethod() was overridden - not much we can do here ...
1936 self.is_classmethod = False
1937 if self.is_staticmethod and env.lookup_here('staticmethod'):
1938 # staticmethod() was overridden - not much we can do here ...
1939 self.is_staticmethod = False
1941 self.analyse_argument_types(env)
1942 if self.name == '<lambda>':
1943 self.declare_lambda_function(env)
1945 self.declare_pyfunction(env)
1946 self.analyse_signature(env)
1947 self.return_type = self.entry.signature.return_type()
1948 self.create_local_scope(env)
1950 def analyse_argument_types(self, env):
1951 directive_locals = self.directive_locals = env.directives['locals']
1952 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1953 for arg in self.args:
1954 if hasattr(arg, 'name'):
1956 name_declarator = None
1958 base_type = arg.base_type.analyse(env)
1959 name_declarator, type = \
1960 arg.declarator.analyse(base_type, env)
1961 arg.name = name_declarator.name
1962 if arg.name in directive_locals:
1963 type_node = directive_locals[arg.name]
1964 other_type = type_node.analyse_as_type(env)
1965 if other_type is None:
1966 error(type_node.pos, "Not a type")
1967 elif (type is not PyrexTypes.py_object_type
1968 and not type.same_as(other_type)):
1969 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1970 error(type_node.pos, "Previous declaration here")
1973 if name_declarator and name_declarator.cname:
1975 "Python function argument cannot have C name specification")
1976 arg.type = type.as_argument_type()
1978 arg.needs_conversion = 0
1979 arg.needs_type_test = 0
1981 if arg.type.is_pyobject:
1983 arg.accept_none = True
1985 arg.accept_none = False
1986 elif arg.type.is_extension_type or arg.type.is_builtin_type:
1987 if arg.default and arg.default.constant_result is None:
1988 # special case: def func(MyType obj = None)
1989 arg.accept_none = True
1991 # default depends on compiler directive
1992 arg.accept_none = allow_none_for_extension_args
1994 # probably just a plain 'object'
1995 arg.accept_none = True
1997 arg.accept_none = True # won't be used, but must be there
1999 error(arg.pos, "Only Python type arguments can have 'not None'")
2001 error(arg.pos, "Only Python type arguments can have 'or None'")
2003 def analyse_signature(self, env):
2004 if self.entry.is_special:
2005 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2006 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2007 # Use the simpler calling signature for zero- and one-argument functions.
2008 if self.entry.signature is TypeSlots.pyfunction_signature:
2009 if len(self.args) == 0:
2010 self.entry.signature = TypeSlots.pyfunction_noargs
2011 elif len(self.args) == 1:
2012 if self.args[0].default is None and not self.args[0].kw_only:
2013 self.entry.signature = TypeSlots.pyfunction_onearg
2014 elif self.entry.signature is TypeSlots.pymethod_signature:
2015 if len(self.args) == 1:
2016 self.entry.signature = TypeSlots.unaryfunc
2017 elif len(self.args) == 2:
2018 if self.args[1].default is None and not self.args[1].kw_only:
2019 self.entry.signature = TypeSlots.ibinaryfunc
2021 sig = self.entry.signature
2022 nfixed = sig.num_fixed_args()
2023 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2024 and len(self.args) == 0 and self.star_arg:
2025 # this is the only case where a diverging number of
2026 # arguments is not an error - when we have no explicit
2027 # 'self' parameter as in method(*args)
2028 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2029 self.self_in_stararg = 1
2032 for i in range(min(nfixed, len(self.args))):
2035 if sig.is_self_arg(i) and not self.is_staticmethod:
2036 if self.is_classmethod:
2038 arg.hdr_type = arg.type = Builtin.type_type
2041 arg.hdr_type = arg.type = env.parent_type
2042 arg.needs_conversion = 0
2044 arg.hdr_type = sig.fixed_arg_type(i)
2045 if not arg.type.same_as(arg.hdr_type):
2046 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2047 arg.needs_type_test = 1
2049 arg.needs_conversion = 1
2050 if arg.needs_conversion:
2051 arg.hdr_cname = Naming.arg_prefix + arg.name
2053 arg.hdr_cname = Naming.var_prefix + arg.name
2055 if nfixed > len(self.args):
2056 self.bad_signature()
2058 elif nfixed < len(self.args):
2059 if not sig.has_generic_args:
2060 self.bad_signature()
2061 for arg in self.args:
2062 if arg.is_generic and \
2063 (arg.type.is_extension_type or arg.type.is_builtin_type):
2064 arg.needs_type_test = 1
2066 def bad_signature(self):
2067 sig = self.entry.signature
2068 expected_str = "%d" % sig.num_fixed_args()
2069 if sig.has_generic_args:
2070 expected_str = expected_str + " or more"
2072 if name.startswith("__") and name.endswith("__"):
2073 desc = "Special method"
2077 "%s %s has wrong number of arguments "
2078 "(%d declared, %s expected)" % (
2079 desc, self.name, len(self.args), expected_str))
2081 def signature_has_nongeneric_args(self):
2082 argcount = len(self.args)
2083 if argcount == 0 or (
2084 argcount == 1 and (self.args[0].is_self_arg or
2085 self.args[0].is_type_arg)):
2089 def signature_has_generic_args(self):
2090 return self.entry.signature.has_generic_args
2092 def declare_pyfunction(self, env):
2093 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2095 entry = env.lookup_here(name)
2096 if entry and entry.type.is_cfunction and not self.is_wrapper:
2097 warning(self.pos, "Overriding cdef method with def method.", 5)
2098 entry = env.declare_pyfunction(name, self.pos)
2100 prefix = env.scope_prefix
2101 entry.func_cname = \
2102 Naming.pyfunc_prefix + prefix + name
2103 entry.pymethdef_cname = \
2104 Naming.pymethdef_prefix + prefix + name
2105 if Options.docstrings:
2106 entry.doc = embed_position(self.pos, self.doc)
2108 Naming.funcdoc_prefix + prefix + name
2112 def declare_lambda_function(self, env):
2114 prefix = env.scope_prefix
2116 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2117 entry = env.declare_lambda_function(func_cname, self.pos)
2118 entry.pymethdef_cname = \
2119 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2120 entry.qualified_name = env.qualify_name(self.lambda_name)
2124 def declare_arguments(self, env):
2125 for arg in self.args:
2127 error(arg.pos, "Missing argument name")
2129 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2130 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2131 if arg.needs_conversion:
2132 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2133 if arg.type.is_pyobject:
2134 arg.entry.init = "0"
2135 arg.entry.init_to_none = 0
2137 arg.entry = self.declare_argument(env, arg)
2139 arg.entry.is_self_arg = arg.is_self_arg
2141 if arg.is_self_arg or arg.is_type_arg or \
2142 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2143 arg.entry.is_declared_generic = 1
2144 self.declare_python_arg(env, self.star_arg)
2145 self.declare_python_arg(env, self.starstar_arg)
2147 def declare_python_arg(self, env, arg):
2149 if env.directives['infer_types'] != False:
2150 type = PyrexTypes.unspecified_type
2152 type = py_object_type
2153 entry = env.declare_var(arg.name, type, arg.pos)
2156 entry.init_to_none = 0
2157 entry.xdecref_cleanup = 1
2159 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2161 def analyse_expressions(self, env):
2162 self.local_scope.directives = env.directives
2163 self.analyse_default_values(env)
2164 if self.needs_assignment_synthesis(env):
2165 # Shouldn't we be doing this at the module level too?
2166 self.synthesize_assignment_node(env)
2168 def needs_assignment_synthesis(self, env, code=None):
2169 # Should enable for module level as well, that will require more testing...
2170 if env.is_module_scope:
2172 return env.directives['binding']
2174 return code.globalstate.directives['binding']
2175 return env.is_py_class_scope or env.is_closure_scope
2177 def synthesize_assignment_node(self, env):
2179 if env.is_py_class_scope:
2180 rhs = ExprNodes.UnboundMethodNode(self.pos,
2181 function = ExprNodes.PyCFunctionNode(self.pos,
2182 pymethdef_cname = self.entry.pymethdef_cname))
2183 elif env.is_closure_scope:
2184 rhs = ExprNodes.InnerFunctionNode(
2185 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2187 rhs = ExprNodes.PyCFunctionNode(
2188 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2189 self.assmt = SingleAssignmentNode(self.pos,
2190 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2192 self.assmt.analyse_declarations(env)
2193 self.assmt.analyse_expressions(env)
2195 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2197 sig = self.entry.signature
2198 if sig.has_dummy_arg or self.self_in_stararg:
2199 arg_code_list.append(
2200 "PyObject *%s" % Naming.self_cname)
2201 for arg in self.args:
2202 if not arg.is_generic:
2203 if arg.is_self_arg or arg.is_type_arg:
2204 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2206 arg_code_list.append(
2207 arg.hdr_type.declaration_code(arg.hdr_cname))
2208 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2209 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2210 if sig.has_generic_args:
2211 arg_code_list.append(
2212 "PyObject *%s, PyObject *%s"
2213 % (Naming.args_cname, Naming.kwds_cname))
2214 arg_code = ", ".join(arg_code_list)
2215 dc = self.return_type.declaration_code(self.entry.func_cname)
2216 mf = " ".join(self.modifiers).upper()
2218 header = "static %s%s(%s)" % (mf, dc, arg_code)
2219 code.putln("%s; /*proto*/" % header)
2222 if (Options.docstrings and self.entry.doc and
2223 (not self.entry.is_special or
2224 self.entry.signature.method_flags()) and
2225 not self.entry.scope.is_property_scope
2227 docstr = self.entry.doc
2228 if docstr.is_unicode:
2229 docstr = docstr.utf8encode()
2231 'static char %s[] = "%s";' % (
2232 self.entry.doc_cname,
2233 split_string_literal(escape_byte_string(docstr))))
2236 "static PyMethodDef %s = " %
2237 self.entry.pymethdef_cname)
2238 code.put_pymethoddef(self.entry, ";")
2239 code.putln("%s {" % header)
2241 def generate_argument_declarations(self, env, code):
2242 for arg in self.args:
2243 if arg.is_generic: # or arg.needs_conversion:
2244 if arg.needs_conversion:
2245 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2246 elif not arg.entry.in_closure:
2247 code.put_var_declaration(arg.entry)
2249 def generate_keyword_list(self, code):
2250 if self.signature_has_generic_args() and \
2251 self.signature_has_nongeneric_args():
2253 "static PyObject **%s[] = {" %
2254 Naming.pykwdlist_cname)
2255 for arg in self.args:
2257 pystring_cname = code.intern_identifier(arg.name)
2258 code.put('&%s,' % pystring_cname)
2261 def generate_argument_parsing_code(self, env, code):
2262 # Generate PyArg_ParseTuple call for generic
2263 # arguments, if any.
2264 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2265 # get rid of unused argument warning
2266 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2268 old_error_label = code.new_error_label()
2269 our_error_label = code.error_label
2270 end_label = code.new_label("argument_unpacking_done")
2272 has_kwonly_args = self.num_kwonly_args > 0
2273 has_star_or_kw_args = self.star_arg is not None \
2274 or self.starstar_arg is not None or has_kwonly_args
2276 for arg in self.args:
2277 if not arg.type.is_pyobject:
2278 done = arg.type.create_from_py_utility_code(env)
2279 if not done: pass # will fail later
2281 if not self.signature_has_generic_args():
2282 if has_star_or_kw_args:
2283 error(self.pos, "This method cannot have * or keyword arguments")
2284 self.generate_argument_conversion_code(code)
2286 elif not self.signature_has_nongeneric_args():
2287 # func(*args) or func(**kw) or func(*args, **kw)
2288 self.generate_stararg_copy_code(code)
2291 positional_args = []
2293 for arg in self.args:
2294 arg_entry = arg.entry
2297 if not arg.is_self_arg and not arg.is_type_arg:
2299 kw_only_args.append(arg)
2301 positional_args.append(arg)
2303 kw_only_args.append(arg)
2304 elif not arg.is_self_arg and not arg.is_type_arg:
2305 positional_args.append(arg)
2307 self.generate_tuple_and_keyword_parsing_code(
2308 positional_args, kw_only_args, end_label, code)
2310 code.error_label = old_error_label
2311 if code.label_used(our_error_label):
2312 if not code.label_used(end_label):
2313 code.put_goto(end_label)
2314 code.put_label(our_error_label)
2315 if has_star_or_kw_args:
2316 self.generate_arg_decref(self.star_arg, code)
2317 if self.starstar_arg:
2318 if self.starstar_arg.entry.xdecref_cleanup:
2319 code.put_var_xdecref(self.starstar_arg.entry)
2321 code.put_var_decref(self.starstar_arg.entry)
2322 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2323 # The arguments are put into the closure one after the
2324 # other, so when type errors are found, all references in
2325 # the closure instance must be properly ref-counted to
2326 # facilitate generic closure instance deallocation. In
2327 # the case of an argument type error, it's best to just
2328 # DECREF+clear the already handled references, as this
2329 # frees their references as early as possible.
2330 for arg in self.args:
2331 if arg.type.is_pyobject and arg.entry.in_closure:
2332 code.put_var_xdecref_clear(arg.entry)
2333 if self.needs_closure:
2334 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2335 code.put_finish_refcount_context()
2336 code.putln("return %s;" % self.error_value())
2337 if code.label_used(end_label):
2338 code.put_label(end_label)
2340 def generate_arg_assignment(self, arg, item, code):
2341 if arg.type.is_pyobject:
2343 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2345 code.putln("%s = %s;" % (entry.cname, item))
2346 if entry.in_closure:
2347 code.put_var_incref(entry)
2349 func = arg.type.from_py_function
2351 code.putln("%s = %s(%s); %s" % (
2355 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2357 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2359 def generate_arg_xdecref(self, arg, code):
2361 code.put_var_xdecref(arg.entry)
2363 def generate_arg_decref(self, arg, code):
2365 code.put_var_decref(arg.entry)
2367 def generate_stararg_copy_code(self, code):
2368 if not self.star_arg:
2369 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2370 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2372 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2373 self.name, Naming.args_cname, self.error_value()))
2376 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2378 if self.starstar_arg:
2380 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2382 kwarg_check = "%s" % Naming.kwds_cname
2384 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2385 Naming.kwds_cname, Naming.kwds_cname)
2387 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2388 kwarg_check, Naming.kwds_cname, self.name,
2389 bool(self.starstar_arg), self.error_value()))
2391 if self.starstar_arg:
2392 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2393 self.starstar_arg.entry.cname,
2396 code.putln("if (unlikely(!%s)) return %s;" % (
2397 self.starstar_arg.entry.cname, self.error_value()))
2398 self.starstar_arg.entry.xdecref_cleanup = 0
2399 code.put_gotref(self.starstar_arg.entry.cname)
2401 if self.self_in_stararg:
2402 # need to create a new tuple with 'self' inserted as first item
2403 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2404 self.star_arg.entry.cname,
2406 self.star_arg.entry.cname))
2407 if self.starstar_arg:
2409 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2410 code.putln("return %s;" % self.error_value())
2413 code.putln("return %s;" % self.error_value())
2414 code.put_gotref(self.star_arg.entry.cname)
2415 code.put_incref(Naming.self_cname, py_object_type)
2416 code.put_giveref(Naming.self_cname)
2417 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2418 self.star_arg.entry.cname, Naming.self_cname))
2419 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2420 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2421 temp, temp, Naming.args_cname, temp))
2422 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2423 Naming.args_cname, temp))
2424 code.put_incref("item", py_object_type)
2425 code.put_giveref("item")
2426 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2427 self.star_arg.entry.cname, temp))
2429 code.funcstate.release_temp(temp)
2430 self.star_arg.entry.xdecref_cleanup = 0
2432 code.put_incref(Naming.args_cname, py_object_type)
2433 code.putln("%s = %s;" % (
2434 self.star_arg.entry.cname,
2436 self.star_arg.entry.xdecref_cleanup = 0
2438 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2439 kw_only_args, success_label, code):
2440 argtuple_error_label = code.new_label("argtuple_error")
2442 min_positional_args = self.num_required_args - self.num_required_kw_args
2443 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2444 min_positional_args -= 1
2445 max_positional_args = len(positional_args)
2446 has_fixed_positional_count = not self.star_arg and \
2447 min_positional_args == max_positional_args
2449 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2450 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2451 if self.num_required_kw_args:
2452 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2454 if self.starstar_arg or self.star_arg:
2455 self.generate_stararg_init_code(max_positional_args, code)
2457 # --- optimised code when we receive keyword arguments
2458 if self.num_required_kw_args:
2459 likely_hint = "likely"
2461 likely_hint = "unlikely"
2462 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2463 self.generate_keyword_unpacking_code(
2464 min_positional_args, max_positional_args,
2465 has_fixed_positional_count,
2466 positional_args, kw_only_args, argtuple_error_label, code)
2468 # --- optimised code when we do not receive any keyword arguments
2469 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2470 # Python raises arg tuple related errors first, so we must
2471 # check the length here
2472 if min_positional_args == max_positional_args and not self.star_arg:
2476 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2477 Naming.args_cname, compare, min_positional_args))
2478 code.put_goto(argtuple_error_label)
2480 if self.num_required_kw_args:
2481 # pure error case: keywords required but not passed
2482 if max_positional_args > min_positional_args and not self.star_arg:
2483 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2484 Naming.args_cname, max_positional_args))
2485 code.put_goto(argtuple_error_label)
2486 code.putln('} else {')
2487 for i, arg in enumerate(kw_only_args):
2489 pystring_cname = code.intern_identifier(arg.name)
2490 # required keyword-only argument missing
2491 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2494 code.putln(code.error_goto(self.pos))
2497 elif min_positional_args == max_positional_args:
2498 # parse the exact number of positional arguments from the
2500 code.putln('} else {')
2501 for i, arg in enumerate(positional_args):
2502 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2503 self.generate_arg_assignment(arg, item, code)
2504 self.generate_arg_default_assignments(code)
2507 # parse the positional arguments from the variable length
2509 code.putln('} else {')
2510 self.generate_arg_default_assignments(code)
2511 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2513 code.putln('default:')
2514 reversed_args = list(enumerate(positional_args))[::-1]
2515 for i, arg in reversed_args:
2516 if i >= min_positional_args-1:
2517 if min_positional_args > 1:
2518 code.putln('case %2d:' % (i+1)) # pure code beautification
2520 code.put('case %2d: ' % (i+1))
2521 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2522 self.generate_arg_assignment(arg, item, code)
2523 if min_positional_args == 0:
2524 code.put('case 0: ')
2525 code.putln('break;')
2527 if min_positional_args:
2528 for i in range(min_positional_args-1, -1, -1):
2529 code.putln('case %2d:' % i)
2530 code.put_goto(argtuple_error_label)
2532 code.put('default: ')
2533 code.put_goto(argtuple_error_label)
2538 if code.label_used(argtuple_error_label):
2539 code.put_goto(success_label)
2540 code.put_label(argtuple_error_label)
2541 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2542 self.name, has_fixed_positional_count,
2543 min_positional_args, max_positional_args,
2545 code.putln(code.error_goto(self.pos))
2547 def generate_arg_default_assignments(self, code):
2548 for arg in self.args:
2549 if arg.is_generic and arg.default:
2553 arg.calculate_default_value_code(code)))
2555 def generate_stararg_init_code(self, max_positional_args, code):
2556 if self.starstar_arg:
2557 self.starstar_arg.entry.xdecref_cleanup = 0
2558 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2559 self.starstar_arg.entry.cname,
2560 self.starstar_arg.entry.cname,
2561 self.error_value()))
2562 code.put_gotref(self.starstar_arg.entry.cname)
2564 self.star_arg.entry.xdecref_cleanup = 0
2565 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2567 max_positional_args))
2568 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2569 self.star_arg.entry.cname, Naming.args_cname,
2570 max_positional_args, Naming.args_cname))
2571 code.put_gotref(self.star_arg.entry.cname)
2572 if self.starstar_arg:
2574 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2575 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2576 code.putln('return %s;' % self.error_value())
2579 code.putln("if (unlikely(!%s)) return %s;" % (
2580 self.star_arg.entry.cname, self.error_value()))
2581 code.putln('} else {')
2582 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2583 code.put_incref(Naming.empty_tuple, py_object_type)
2586 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2587 has_fixed_positional_count, positional_args,
2588 kw_only_args, argtuple_error_label, code):
2589 all_args = tuple(positional_args) + tuple(kw_only_args)
2590 max_args = len(all_args)
2593 for i, arg in enumerate(all_args):
2594 if arg.default and arg.type.is_pyobject:
2595 default_value = arg.calculate_default_value_code(code)
2596 if arg.type is not PyrexTypes.py_object_type:
2597 default_value = "(PyObject*)"+default_value
2598 default_args.append((i, default_value))
2600 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2602 # it looks funny to separate the init-to-0 from setting the
2603 # default value, but C89 needs this
2604 code.putln("PyObject* values[%d] = {%s};" % (
2605 max_args, ','.join('0'*max_args)))
2606 for i, default_value in default_args:
2607 code.putln('values[%d] = %s;' % (i, default_value))
2609 # parse the tuple and check that it's not too long
2610 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2612 code.putln('default:')
2613 for i in range(max_positional_args-1, -1, -1):
2614 code.put('case %2d: ' % (i+1))
2615 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2616 i, Naming.args_cname, i))
2617 code.putln('case 0: break;')
2618 if not self.star_arg:
2619 code.put('default: ') # more arguments than allowed
2620 code.put_goto(argtuple_error_label)
2623 # now fill up the positional/required arguments with values
2625 if self.num_required_args or max_positional_args > 0:
2626 last_required_arg = -1
2627 for i, arg in enumerate(all_args):
2629 last_required_arg = i
2630 if last_required_arg < max_positional_args:
2631 last_required_arg = max_positional_args-1
2632 num_required_args = self.num_required_args
2633 if max_positional_args > 0:
2634 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2635 for i, arg in enumerate(all_args[:last_required_arg+1]):
2636 if max_positional_args > 0 and i <= max_positional_args:
2637 if self.star_arg and i == max_positional_args:
2638 code.putln('default:')
2640 code.putln('case %2d:' % i)
2641 pystring_cname = code.intern_identifier(arg.name)
2644 # handled separately below
2646 code.putln('if (kw_args > %d) {' % num_required_args)
2647 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2648 Naming.kwds_cname, pystring_cname))
2649 code.putln('if (unlikely(value)) { values[%d] = value; kw_args--; }' % i)
2652 num_required_args -= 1
2653 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2654 i, Naming.kwds_cname, pystring_cname))
2655 code.putln('if (likely(values[%d])) kw_args--;' % i);
2656 if i < min_positional_args:
2658 # special case: we know arg 0 is missing
2660 code.put_goto(argtuple_error_label)
2662 # print the correct number of values (args or
2663 # kwargs) that were passed into positional
2664 # arguments up to this point
2665 code.putln('else {')
2666 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2667 self.name, has_fixed_positional_count,
2668 min_positional_args, max_positional_args, i))
2669 code.putln(code.error_goto(self.pos))
2672 code.putln('else {')
2673 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2674 self.name, pystring_cname))
2675 code.putln(code.error_goto(self.pos))
2677 if max_positional_args > 0:
2680 if kw_only_args and not self.starstar_arg:
2681 # unpack optional keyword-only arguments
2682 # checking for interned strings in a dict is faster than iterating
2683 # but it's too likely that we must iterate if we expect **kwargs
2685 for i, arg in enumerate(all_args[max_positional_args:]):
2686 if not arg.kw_only or not arg.default:
2688 optional_args.append((i+max_positional_args, arg))
2690 # this mimics an unrolled loop so that we can "break" out of it
2691 code.putln('while (kw_args > 0) {')
2692 code.putln('PyObject* value;')
2693 for i, arg in optional_args:
2694 pystring_cname = code.intern_identifier(arg.name)
2696 'value = PyDict_GetItem(%s, %s);' % (
2697 Naming.kwds_cname, pystring_cname))
2699 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2700 code.putln('break;')
2703 code.putln('if (unlikely(kw_args > 0)) {')
2704 # non-positional/-required kw args left in dict: default args,
2705 # kw-only args, **kwargs or error
2707 # This is sort of a catch-all: except for checking required
2708 # arguments, this will always do the right thing for unpacking
2709 # keyword arguments, so that we can concentrate on optimising
2710 # common cases above.
2711 if max_positional_args == 0:
2714 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2715 Naming.args_cname, max_positional_args,
2716 Naming.args_cname, max_positional_args))
2717 pos_arg_count = "used_pos_args"
2719 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2720 code.globalstate.use_utility_code(parse_keywords_utility_code)
2722 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2724 Naming.pykwdlist_cname,
2725 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2728 code.putln(code.error_goto(self.pos))
2731 # convert arg values to their final type and assign them
2732 for i, arg in enumerate(all_args):
2733 if arg.default and not arg.type.is_pyobject:
2734 code.putln("if (values[%d]) {" % i)
2735 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2736 if arg.default and not arg.type.is_pyobject:
2737 code.putln('} else {')
2741 arg.calculate_default_value_code(code)))
2744 def generate_argument_conversion_code(self, code):
2745 # Generate code to convert arguments from signature type to
2746 # declared type, if needed. Also copies signature arguments
2747 # into closure fields.
2748 for arg in self.args:
2749 if arg.needs_conversion:
2750 self.generate_arg_conversion(arg, code)
2751 elif arg.entry.in_closure:
2752 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2753 if arg.type.is_pyobject:
2754 code.put_var_incref(arg.entry)
2756 def generate_arg_conversion(self, arg, code):
2757 # Generate conversion code for one argument.
2758 old_type = arg.hdr_type
2760 if old_type.is_pyobject:
2762 code.putln("if (%s) {" % arg.hdr_cname)
2764 code.putln("assert(%s); {" % arg.hdr_cname)
2765 self.generate_arg_conversion_from_pyobject(arg, code)
2767 elif new_type.is_pyobject:
2768 self.generate_arg_conversion_to_pyobject(arg, code)
2770 if new_type.assignable_from(old_type):
2772 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2775 "Cannot convert 1 argument from '%s' to '%s'" %
2776 (old_type, new_type))
2778 def generate_arg_conversion_from_pyobject(self, arg, code):
2780 func = new_type.from_py_function
2781 # copied from CoerceFromPyTypeNode
2783 lhs = arg.entry.cname
2784 rhs = "%s(%s)" % (func, arg.hdr_cname)
2785 if new_type.is_enum:
2786 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2787 code.putln("%s = %s; %s" % (
2790 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2793 "Cannot convert Python object argument to type '%s'"
2796 def generate_arg_conversion_to_pyobject(self, arg, code):
2797 old_type = arg.hdr_type
2798 func = old_type.to_py_function
2800 code.putln("%s = %s(%s); %s" % (
2804 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2805 code.put_var_gotref(arg.entry)
2808 "Cannot convert argument of type '%s' to Python object"
2811 def generate_argument_type_tests(self, code):
2812 # Generate type tests for args whose signature
2813 # type is PyObject * and whose declared type is
2814 # a subtype thereof.
2815 for arg in self.args:
2816 if arg.needs_type_test:
2817 self.generate_arg_type_test(arg, code)
2818 elif not arg.accept_none and arg.type.is_pyobject:
2819 self.generate_arg_none_check(arg, code)
2821 def error_value(self):
2822 return self.entry.signature.error_value
2824 def caller_will_check_exceptions(self):
2827 class OverrideCheckNode(StatNode):
2828 # A Node for dispatching to the def method if it
2837 child_attrs = ['body']
2841 def analyse_expressions(self, env):
2842 self.args = env.arg_entries
2843 if self.py_func.is_module_scope:
2848 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2849 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2850 call_node = ExprNodes.SimpleCallNode(self.pos,
2851 function=self.func_node,
2852 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2853 self.body = ReturnStatNode(self.pos, value=call_node)
2854 self.body.analyse_expressions(env)
2856 def generate_execution_code(self, code):
2857 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2858 # Check to see if we are an extension type
2859 if self.py_func.is_module_scope:
2860 self_arg = "((PyObject *)%s)" % Naming.module_cname
2862 self_arg = "((PyObject *)%s)" % self.args[0].cname
2863 code.putln("/* Check if called by wrapper */")
2864 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2865 code.putln("/* Check if overriden in Python */")
2866 if self.py_func.is_module_scope:
2867 code.putln("else {")
2869 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2870 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2871 self.func_node.set_cname(func_node_temp)
2872 # need to get attribute manually--scope would return cdef method
2873 err = code.error_goto_if_null(func_node_temp, self.pos)
2874 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2875 func_node_temp, self_arg, interned_attr_cname, err))
2876 code.put_gotref(func_node_temp)
2877 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2878 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2879 func_node_temp, self.py_func.entry.func_cname)
2880 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2881 self.body.generate_execution_code(code)
2883 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2884 code.funcstate.release_temp(func_node_temp)
2887 class ClassDefNode(StatNode, BlockNode):
2890 class PyClassDefNode(ClassDefNode):
2891 # A Python class definition.
2893 # name EncodedString Name of the class
2894 # doc string or None
2895 # body StatNode Attribute definition code
2896 # entry Symtab.Entry
2897 # scope PyClassScope
2898 # decorators [DecoratorNode] list of decorators or None
2900 # The following subnodes are constructed internally:
2902 # dict DictNode Class dictionary
2903 # classobj ClassNode Class object
2904 # target NameNode Variable to assign class object to
2906 child_attrs = ["body", "dict", "classobj", "target"]
2909 def __init__(self, pos, name, bases, doc, body, decorators = None):
2910 StatNode.__init__(self, pos)
2914 self.decorators = decorators
2916 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2917 if self.doc and Options.docstrings:
2918 doc = embed_position(self.pos, self.doc)
2919 # FIXME: correct string node?
2920 doc_node = ExprNodes.StringNode(pos, value = doc)
2923 self.classobj = ExprNodes.ClassNode(pos, name = name,
2924 bases = bases, dict = self.dict, doc = doc_node)
2925 self.target = ExprNodes.NameNode(pos, name = name)
2927 def as_cclass(self):
2929 Return this node as if it were declared as an extension class
2931 bases = self.classobj.bases.args
2933 base_class_name = None
2934 base_class_module = None
2935 elif len(bases) == 1:
2938 from ExprNodes import AttributeNode, NameNode
2939 while isinstance(base, AttributeNode):
2940 path.insert(0, base.attribute)
2942 if isinstance(base, NameNode):
2943 path.insert(0, base.name)
2944 base_class_name = path[-1]
2946 base_class_module = u'.'.join(path[:-1])
2948 base_class_module = None
2950 error(self.classobj.bases.args.pos, "Invalid base class")
2952 error(self.classobj.bases.args.pos, "C class may only have one base class")
2955 return CClassDefNode(self.pos,
2956 visibility = 'private',
2958 class_name = self.name,
2959 base_class_module = base_class_module,
2960 base_class_name = base_class_name,
2961 decorators = self.decorators,
2966 def create_scope(self, env):
2968 while env.is_py_class_scope or env.is_c_class_scope:
2969 env = env.outer_scope
2970 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2973 def analyse_declarations(self, env):
2974 self.target.analyse_target_declaration(env)
2975 cenv = self.create_scope(env)
2976 cenv.directives = env.directives
2977 cenv.class_obj_cname = self.target.entry.cname
2978 self.body.analyse_declarations(cenv)
2980 def analyse_expressions(self, env):
2981 self.dict.analyse_expressions(env)
2982 self.classobj.analyse_expressions(env)
2983 genv = env.global_scope()
2985 self.body.analyse_expressions(cenv)
2986 self.target.analyse_target_expression(env, self.classobj)
2988 def generate_function_definitions(self, env, code):
2989 self.body.generate_function_definitions(self.scope, code)
2991 def generate_execution_code(self, code):
2992 code.pyclass_stack.append(self)
2994 self.dict.generate_evaluation_code(code)
2995 self.classobj.generate_evaluation_code(code)
2996 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
2997 self.body.generate_execution_code(code)
2998 self.target.generate_assignment_code(self.classobj, code)
2999 self.dict.generate_disposal_code(code)
3000 self.dict.free_temps(code)
3001 code.pyclass_stack.pop()
3004 class CClassDefNode(ClassDefNode):
3005 # An extension type definition.
3007 # visibility 'private' or 'public' or 'extern'
3008 # typedef_flag boolean
3010 # module_name string or None For import of extern type objects
3011 # class_name string Unqualified name of class
3012 # as_name string or None Name to declare as in this scope
3013 # base_class_module string or None Module containing the base class
3014 # base_class_name string or None Name of the base class
3015 # objstruct_name string or None Specified C name of object struct
3016 # typeobj_name string or None Specified C name of type object
3017 # in_pxd boolean Is in a .pxd file
3018 # decorators [DecoratorNode] list of decorators or None
3019 # doc string or None
3020 # body StatNode or None
3021 # entry Symtab.Entry
3022 # base_type PyExtensionType or None
3023 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3024 # buffer_defaults_pos
3026 child_attrs = ["body"]
3027 buffer_defaults_node = None
3028 buffer_defaults_pos = None
3029 typedef_flag = False
3031 objstruct_name = None
3035 def analyse_declarations(self, env):
3036 #print "CClassDefNode.analyse_declarations:", self.class_name
3037 #print "...visibility =", self.visibility
3038 #print "...module_name =", self.module_name
3041 if self.buffer_defaults_node:
3042 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3043 env, [], self.buffer_defaults_node,
3044 need_complete=False)
3046 buffer_defaults = None
3048 if env.in_cinclude and not self.objstruct_name:
3049 error(self.pos, "Object struct name specification required for "
3050 "C class defined in 'extern from' block")
3051 self.base_type = None
3052 # Now that module imports are cached, we need to
3053 # import the modules for extern classes.
3054 if self.module_name:
3056 for module in env.cimported_modules:
3057 if module.name == self.module_name:
3058 self.module = module
3059 if self.module is None:
3060 self.module = ModuleScope(self.module_name, None, env.context)
3061 self.module.has_extern_class = 1
3062 env.add_imported_module(self.module)
3064 if self.base_class_name:
3065 if self.base_class_module:
3066 base_class_scope = env.find_module(self.base_class_module, self.pos)
3068 base_class_scope = env
3069 if self.base_class_name == 'object':
3070 # extension classes are special and don't need to inherit from object
3071 if base_class_scope is None or base_class_scope.lookup('object') is None:
3072 self.base_class_name = None
3073 self.base_class_module = None
3074 base_class_scope = None
3075 if base_class_scope:
3076 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3077 if base_class_entry:
3078 if not base_class_entry.is_type:
3079 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3080 elif not base_class_entry.type.is_extension_type:
3081 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3082 elif not base_class_entry.type.is_complete():
3083 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
3085 self.base_type = base_class_entry.type
3086 has_body = self.body is not None
3087 if self.module_name and self.visibility != 'extern':
3088 module_path = self.module_name.split(".")
3089 home_scope = env.find_imported_module(module_path, self.pos)
3095 if self.visibility == 'extern':
3096 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3097 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3099 self.entry = home_scope.declare_c_class(
3100 name = self.class_name,
3102 defining = has_body and self.in_pxd,
3103 implementing = has_body and not self.in_pxd,
3104 module_name = self.module_name,
3105 base_type = self.base_type,
3106 objstruct_cname = self.objstruct_name,
3107 typeobj_cname = self.typeobj_name,
3108 visibility = self.visibility,
3109 typedef_flag = self.typedef_flag,
3111 buffer_defaults = buffer_defaults)
3112 if home_scope is not env and self.visibility == 'extern':
3113 env.add_imported_entry(self.class_name, self.entry, pos)
3114 self.scope = scope = self.entry.type.scope
3115 if scope is not None:
3116 scope.directives = env.directives
3118 if self.doc and Options.docstrings:
3119 scope.doc = embed_position(self.pos, self.doc)
3122 self.body.analyse_declarations(scope)
3126 scope.implemented = 1
3127 env.allocate_vtable_names(self.entry)
3129 def analyse_expressions(self, env):
3131 scope = self.entry.type.scope
3132 self.body.analyse_expressions(scope)
3134 def generate_function_definitions(self, env, code):
3136 self.body.generate_function_definitions(
3137 self.entry.type.scope, code)
3139 def generate_execution_code(self, code):
3140 # This is needed to generate evaluation code for
3141 # default values of method arguments.
3143 self.body.generate_execution_code(code)
3145 def annotate(self, code):
3147 self.body.annotate(code)
3150 class PropertyNode(StatNode):
3151 # Definition of a property in an extension type.
3154 # doc EncodedString or None Doc string
3157 child_attrs = ["body"]
3159 def analyse_declarations(self, env):
3160 entry = env.declare_property(self.name, self.doc, self.pos)
3162 entry.scope.directives = env.directives
3163 self.body.analyse_declarations(entry.scope)
3165 def analyse_expressions(self, env):
3166 self.body.analyse_expressions(env)
3168 def generate_function_definitions(self, env, code):
3169 self.body.generate_function_definitions(env, code)
3171 def generate_execution_code(self, code):
3174 def annotate(self, code):
3175 self.body.annotate(code)
3178 class GlobalNode(StatNode):
3179 # Global variable declaration.
3185 def analyse_declarations(self, env):
3186 for name in self.names:
3187 env.declare_global(name, self.pos)
3189 def analyse_expressions(self, env):
3192 def generate_execution_code(self, code):
3196 class ExprStatNode(StatNode):
3197 # Expression used as a statement.
3201 child_attrs = ["expr"]
3203 def analyse_declarations(self, env):
3205 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3206 func = self.expr.function.as_cython_attribute()
3207 if func == u'declare':
3208 args, kwds = self.expr.explicit_args_kwds()
3210 error(self.expr.pos, "Variable names must be specified.")
3211 for var, type_node in kwds.key_value_pairs:
3212 type = type_node.analyse_as_type(env)
3214 error(type_node.pos, "Unknown type")
3216 env.declare_var(var.value, type, var.pos, is_cdef = True)
3217 self.__class__ = PassStatNode
3219 def analyse_expressions(self, env):
3220 self.expr.analyse_expressions(env)
3222 def generate_execution_code(self, code):
3223 self.expr.generate_evaluation_code(code)
3224 if not self.expr.is_temp and self.expr.result():
3225 code.putln("%s;" % self.expr.result())
3226 self.expr.generate_disposal_code(code)
3227 self.expr.free_temps(code)
3229 def generate_function_definitions(self, env, code):
3230 self.expr.generate_function_definitions(env, code)
3232 def annotate(self, code):
3233 self.expr.annotate(code)
3236 class AssignmentNode(StatNode):
3237 # Abstract base class for assignment nodes.
3239 # The analyse_expressions and generate_execution_code
3240 # phases of assignments are split into two sub-phases
3241 # each, to enable all the right hand sides of a
3242 # parallel assignment to be evaluated before assigning
3243 # to any of the left hand sides.
3245 def analyse_expressions(self, env):
3246 self.analyse_types(env)
3248 # def analyse_expressions(self, env):
3249 # self.analyse_expressions_1(env)
3250 # self.analyse_expressions_2(env)
3252 def generate_execution_code(self, code):
3253 self.generate_rhs_evaluation_code(code)
3254 self.generate_assignment_code(code)
3257 class SingleAssignmentNode(AssignmentNode):
3258 # The simplest case:
3262 # lhs ExprNode Left hand side
3263 # rhs ExprNode Right hand side
3264 # first bool Is this guaranteed the first assignment to lhs?
3266 child_attrs = ["lhs", "rhs"]
3268 declaration_only = False
3270 def analyse_declarations(self, env):
3273 # handle declarations of the form x = cython.foo()
3274 if isinstance(self.rhs, ExprNodes.CallNode):
3275 func_name = self.rhs.function.as_cython_attribute()
3277 args, kwds = self.rhs.explicit_args_kwds()
3279 if func_name in ['declare', 'typedef']:
3280 if len(args) > 2 or kwds is not None:
3281 error(rhs.pos, "Can only declare one type at a time.")
3283 type = args[0].analyse_as_type(env)
3285 error(args[0].pos, "Unknown type")
3288 if func_name == 'declare':
3289 if isinstance(lhs, ExprNodes.NameNode):
3290 vars = [(lhs.name, lhs.pos)]
3291 elif isinstance(lhs, ExprNodes.TupleNode):
3292 vars = [(var.name, var.pos) for var in lhs.args]
3294 error(lhs.pos, "Invalid declaration")
3296 for var, pos in vars:
3297 env.declare_var(var, type, pos, is_cdef = True)
3302 self.declaration_only = True
3304 self.declaration_only = True
3305 if not isinstance(lhs, ExprNodes.NameNode):
3306 error(lhs.pos, "Invalid declaration.")
3307 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3309 elif func_name in ['struct', 'union']:
3310 self.declaration_only = True
3311 if len(args) > 0 or kwds is None:
3312 error(rhs.pos, "Struct or union members must be given by name.")
3315 for member, type_node in kwds.key_value_pairs:
3316 type = type_node.analyse_as_type(env)
3318 error(type_node.pos, "Unknown type")
3320 members.append((member.value, type, member.pos))
3321 if len(members) < len(kwds.key_value_pairs):
3323 if not isinstance(self.lhs, ExprNodes.NameNode):
3324 error(self.lhs.pos, "Invalid declaration.")
3325 name = self.lhs.name
3326 scope = StructOrUnionScope(name)
3327 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3328 for member, type, pos in members:
3329 scope.declare_var(member, type, pos)
3331 if self.declaration_only:
3334 self.lhs.analyse_target_declaration(env)
3336 def analyse_types(self, env, use_temp = 0):
3337 self.rhs.analyse_types(env)
3338 self.lhs.analyse_target_types(env)
3339 self.lhs.gil_assignment_check(env)
3340 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3342 self.rhs = self.rhs.coerce_to_temp(env)
3344 def generate_rhs_evaluation_code(self, code):
3345 self.rhs.generate_evaluation_code(code)
3347 def generate_assignment_code(self, code):
3348 self.lhs.generate_assignment_code(self.rhs, code)
3350 def generate_function_definitions(self, env, code):
3351 self.rhs.generate_function_definitions(env, code)
3353 def annotate(self, code):
3354 self.lhs.annotate(code)
3355 self.rhs.annotate(code)
3358 class CascadedAssignmentNode(AssignmentNode):
3359 # An assignment with multiple left hand sides:
3363 # lhs_list [ExprNode] Left hand sides
3364 # rhs ExprNode Right hand sides
3368 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3370 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3371 coerced_rhs_list = None
3373 def analyse_declarations(self, env):
3374 for lhs in self.lhs_list:
3375 lhs.analyse_target_declaration(env)
3377 def analyse_types(self, env, use_temp = 0):
3378 self.rhs.analyse_types(env)
3379 if not self.rhs.is_simple():
3381 self.rhs = self.rhs.coerce_to_temp(env)
3383 self.rhs = self.rhs.coerce_to_simple(env)
3384 from ExprNodes import CloneNode
3385 self.coerced_rhs_list = []
3386 for lhs in self.lhs_list:
3387 lhs.analyse_target_types(env)
3388 lhs.gil_assignment_check(env)
3389 rhs = CloneNode(self.rhs)
3390 rhs = rhs.coerce_to(lhs.type, env)
3391 self.coerced_rhs_list.append(rhs)
3393 def generate_rhs_evaluation_code(self, code):
3394 self.rhs.generate_evaluation_code(code)
3396 def generate_assignment_code(self, code):
3397 for i in range(len(self.lhs_list)):
3398 lhs = self.lhs_list[i]
3399 rhs = self.coerced_rhs_list[i]
3400 rhs.generate_evaluation_code(code)
3401 lhs.generate_assignment_code(rhs, code)
3402 # Assignment has disposed of the cloned RHS
3403 self.rhs.generate_disposal_code(code)
3404 self.rhs.free_temps(code)
3406 def generate_function_definitions(self, env, code):
3407 self.rhs.generate_function_definitions(env, code)
3409 def annotate(self, code):
3410 for i in range(len(self.lhs_list)):
3411 lhs = self.lhs_list[i].annotate(code)
3412 rhs = self.coerced_rhs_list[i].annotate(code)
3413 self.rhs.annotate(code)
3416 class ParallelAssignmentNode(AssignmentNode):
3417 # A combined packing/unpacking assignment:
3421 # This has been rearranged by the parser into
3423 # a = d ; b = e ; c = f
3425 # but we must evaluate all the right hand sides
3426 # before assigning to any of the left hand sides.
3428 # stats [AssignmentNode] The constituent assignments
3430 child_attrs = ["stats"]
3432 def analyse_declarations(self, env):
3433 for stat in self.stats:
3434 stat.analyse_declarations(env)
3436 def analyse_expressions(self, env):
3437 for stat in self.stats:
3438 stat.analyse_types(env, use_temp = 1)
3440 # def analyse_expressions(self, env):
3441 # for stat in self.stats:
3442 # stat.analyse_expressions_1(env, use_temp = 1)
3443 # for stat in self.stats:
3444 # stat.analyse_expressions_2(env)
3446 def generate_execution_code(self, code):
3447 for stat in self.stats:
3448 stat.generate_rhs_evaluation_code(code)
3449 for stat in self.stats:
3450 stat.generate_assignment_code(code)
3452 def generate_function_definitions(self, env, code):
3453 for stat in self.stats:
3454 stat.generate_function_definitions(env, code)
3456 def annotate(self, code):
3457 for stat in self.stats:
3461 class InPlaceAssignmentNode(AssignmentNode):
3462 # An in place arithmetic operand:
3468 # lhs ExprNode Left hand side
3469 # rhs ExprNode Right hand side
3470 # op char one of "+-*/%^&|"
3471 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3473 # This code is a bit tricky because in order to obey Python
3474 # semantics the sub-expressions (e.g. indices) of the lhs must
3475 # not be evaluated twice. So we must re-use the values calculated
3476 # in evaluation phase for the assignment phase as well.
3477 # Fortunately, the type of the lhs node is fairly constrained
3478 # (it must be a NameNode, AttributeNode, or IndexNode).
3480 child_attrs = ["lhs", "rhs"]
3483 def analyse_declarations(self, env):
3484 self.lhs.analyse_target_declaration(env)
3486 def analyse_types(self, env):
3487 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3488 self.rhs.analyse_types(env)
3489 self.lhs.analyse_target_types(env)
3491 if self.lhs.type.is_pyobject:
3492 self.rhs = self.rhs.coerce_to_pyobject(env)
3493 elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3494 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3495 if self.lhs.type.is_pyobject:
3496 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3497 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3499 def generate_execution_code(self, code):
3501 self.rhs.generate_evaluation_code(code)
3502 self.dup.generate_subexpr_evaluation_code(code)
3503 if self.dup.is_temp:
3504 self.dup.allocate_temp_result(code)
3505 # self.dup.generate_result_code is run only if it is not buffer access
3506 if self.operator == "**":
3510 if self.lhs.type.is_pyobject:
3511 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3512 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3513 self.dup.generate_result_code(code)
3514 self.result_value_temp.allocate(code)
3516 "%s = %s(%s, %s%s); %s" % (
3517 self.result_value.result(),
3518 self.py_operation_function(),
3519 self.dup.py_result(),
3520 self.rhs.py_result(),
3522 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3523 code.put_gotref(self.result_value.py_result())
3524 self.result_value.generate_evaluation_code(code) # May be a type check...
3525 self.rhs.generate_disposal_code(code)
3526 self.rhs.free_temps(code)
3527 self.dup.generate_disposal_code(code)
3528 self.dup.free_temps(code)
3529 self.lhs.generate_assignment_code(self.result_value, code)
3530 self.result_value_temp.release(code)
3532 c_op = self.operator
3536 error(self.pos, "No C inplace power operator")
3537 elif self.lhs.type.is_complex:
3538 error(self.pos, "Inplace operators not implemented for complex types.")
3540 # have to do assignment directly to avoid side-effects
3541 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3542 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3544 self.dup.generate_result_code(code)
3545 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3546 self.rhs.generate_disposal_code(code)
3547 self.rhs.free_temps(code)
3548 if self.dup.is_temp:
3549 self.dup.generate_subexpr_disposal_code(code)
3550 self.dup.free_subexpr_temps(code)
3552 def create_dup_node(self, env):
3555 self.dup.analyse_types(env)
3556 if isinstance(self.lhs, ExprNodes.NameNode):
3557 target_lhs = ExprNodes.NameNode(self.dup.pos,
3558 name = self.dup.name,
3559 is_temp = self.dup.is_temp,
3560 entry = self.dup.entry)
3561 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3562 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3563 obj = ExprNodes.CloneNode(self.lhs.obj),
3564 attribute = self.dup.attribute,
3565 is_temp = self.dup.is_temp)
3566 elif isinstance(self.lhs, ExprNodes.IndexNode):
3568 index = ExprNodes.CloneNode(self.lhs.index)
3571 if self.lhs.indices:
3572 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3575 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3576 base = ExprNodes.CloneNode(self.dup.base),
3579 is_temp = self.dup.is_temp)
3581 assert False, "Unsupported node: %s" % type(self.lhs)
3582 self.lhs = target_lhs
3585 def py_operation_function(self):
3586 return self.py_functions[self.operator]
3589 "|": "PyNumber_InPlaceOr",
3590 "^": "PyNumber_InPlaceXor",
3591 "&": "PyNumber_InPlaceAnd",
3592 "+": "PyNumber_InPlaceAdd",
3593 "-": "PyNumber_InPlaceSubtract",
3594 "*": "PyNumber_InPlaceMultiply",
3595 "/": "__Pyx_PyNumber_InPlaceDivide",
3596 "%": "PyNumber_InPlaceRemainder",
3597 "<<": "PyNumber_InPlaceLshift",
3598 ">>": "PyNumber_InPlaceRshift",
3599 "**": "PyNumber_InPlacePower",
3600 "//": "PyNumber_InPlaceFloorDivide",
3603 def annotate(self, code):
3604 self.lhs.annotate(code)
3605 self.rhs.annotate(code)
3606 self.dup.annotate(code)
3608 def create_binop_node(self):
3610 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3613 class PrintStatNode(StatNode):
3616 # arg_tuple TupleNode
3617 # stream ExprNode or None (stdout)
3618 # append_newline boolean
3620 child_attrs = ["arg_tuple", "stream"]
3622 def analyse_expressions(self, env):
3624 self.stream.analyse_expressions(env)
3625 self.stream = self.stream.coerce_to_pyobject(env)
3626 self.arg_tuple.analyse_expressions(env)
3627 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3628 env.use_utility_code(printing_utility_code)
3629 if len(self.arg_tuple.args) == 1 and self.append_newline:
3630 env.use_utility_code(printing_one_utility_code)
3632 nogil_check = Node.gil_error
3633 gil_message = "Python print statement"
3635 def generate_execution_code(self, code):
3637 self.stream.generate_evaluation_code(code)
3638 stream_result = self.stream.py_result()
3641 if len(self.arg_tuple.args) == 1 and self.append_newline:
3642 arg = self.arg_tuple.args[0]
3643 arg.generate_evaluation_code(code)
3646 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3649 code.error_goto(self.pos)))
3650 arg.generate_disposal_code(code)
3651 arg.free_temps(code)
3653 self.arg_tuple.generate_evaluation_code(code)
3655 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3657 self.arg_tuple.py_result(),
3658 self.append_newline,
3659 code.error_goto(self.pos)))
3660 self.arg_tuple.generate_disposal_code(code)
3661 self.arg_tuple.free_temps(code)
3664 self.stream.generate_disposal_code(code)
3665 self.stream.free_temps(code)
3667 def generate_function_definitions(self, env, code):
3669 self.stream.generate_function_definitions(env, code)
3670 self.arg_tuple.generate_function_definitions(env, code)
3672 def annotate(self, code):
3674 self.stream.annotate(code)
3675 self.arg_tuple.annotate(code)
3678 class ExecStatNode(StatNode):
3683 child_attrs = ["args"]
3685 def analyse_expressions(self, env):
3686 for i, arg in enumerate(self.args):
3687 arg.analyse_expressions(env)
3688 arg = arg.coerce_to_pyobject(env)
3690 env.use_utility_code(Builtin.pyexec_utility_code)
3692 nogil_check = Node.gil_error
3693 gil_message = "Python exec statement"
3695 def generate_execution_code(self, code):
3697 for arg in self.args:
3698 arg.generate_evaluation_code(code)
3699 args.append( arg.py_result() )
3700 args = tuple(args + ['0', '0'][:3-len(args)])
3701 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3702 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3703 (temp_result,) + args))
3704 for arg in self.args:
3705 arg.generate_disposal_code(code)
3706 arg.free_temps(code)
3708 code.error_goto_if_null(temp_result, self.pos))
3709 code.put_gotref(temp_result)
3710 code.put_decref_clear(temp_result, py_object_type)
3711 code.funcstate.release_temp(temp_result)
3713 def annotate(self, code):
3714 for arg in self.args:
3718 class DelStatNode(StatNode):
3723 child_attrs = ["args"]
3725 def analyse_declarations(self, env):
3726 for arg in self.args:
3727 arg.analyse_target_declaration(env)
3729 def analyse_expressions(self, env):
3730 for arg in self.args:
3731 arg.analyse_target_expression(env, None)
3732 if arg.type.is_pyobject:
3734 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3736 elif arg.type.is_cpp_class:
3737 error(arg.pos, "Deletion of non-heap C++ object")
3739 error(arg.pos, "Deletion of non-Python, non-C++ object")
3740 #arg.release_target_temp(env)
3742 def nogil_check(self, env):
3743 for arg in self.args:
3744 if arg.type.is_pyobject:
3747 gil_message = "Deleting Python object"
3749 def generate_execution_code(self, code):
3750 for arg in self.args:
3751 if arg.type.is_pyobject:
3752 arg.generate_deletion_code(code)
3753 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3754 arg.generate_result_code(code)
3755 code.putln("delete %s;" % arg.result())
3756 # else error reported earlier
3758 def annotate(self, code):
3759 for arg in self.args:
3763 class PassStatNode(StatNode):
3768 def analyse_expressions(self, env):
3771 def generate_execution_code(self, code):
3775 class BreakStatNode(StatNode):
3779 def analyse_expressions(self, env):
3782 def generate_execution_code(self, code):
3783 if not code.break_label:
3784 error(self.pos, "break statement not inside loop")
3786 code.put_goto(code.break_label)
3789 class ContinueStatNode(StatNode):
3793 def analyse_expressions(self, env):
3796 def generate_execution_code(self, code):
3797 if code.funcstate.in_try_finally:
3798 error(self.pos, "continue statement inside try of try...finally")
3799 elif not code.continue_label:
3800 error(self.pos, "continue statement not inside loop")
3802 code.put_goto(code.continue_label)
3805 class ReturnStatNode(StatNode):
3808 # value ExprNode or None
3809 # return_type PyrexType
3811 child_attrs = ["value"]
3813 def analyse_expressions(self, env):
3814 return_type = env.return_type
3815 self.return_type = return_type
3817 error(self.pos, "Return not inside a function body")
3820 self.value.analyse_types(env)
3821 if return_type.is_void or return_type.is_returncode:
3822 error(self.value.pos,
3823 "Return with value in void function")
3825 self.value = self.value.coerce_to(env.return_type, env)
3827 if (not return_type.is_void
3828 and not return_type.is_pyobject
3829 and not return_type.is_returncode):
3830 error(self.pos, "Return value required")
3832 def nogil_check(self, env):
3833 if self.return_type.is_pyobject:
3836 gil_message = "Returning Python object"
3838 def generate_execution_code(self, code):
3839 code.mark_pos(self.pos)
3840 if not self.return_type:
3841 # error reported earlier
3843 if self.return_type.is_pyobject:
3844 code.put_xdecref(Naming.retval_cname,
3847 self.value.generate_evaluation_code(code)
3848 self.value.make_owned_reference(code)
3851 Naming.retval_cname,
3852 self.value.result_as(self.return_type)))
3853 self.value.generate_post_assignment_code(code)
3854 self.value.free_temps(code)
3856 if self.return_type.is_pyobject:
3857 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3858 elif self.return_type.is_returncode:
3861 Naming.retval_cname,
3862 self.return_type.default_value))
3863 for cname, type in code.funcstate.temps_holding_reference():
3864 code.put_decref_clear(cname, type)
3865 code.put_goto(code.return_label)
3867 def generate_function_definitions(self, env, code):
3868 if self.value is not None:
3869 self.value.generate_function_definitions(env, code)
3871 def annotate(self, code):
3873 self.value.annotate(code)
3876 class RaiseStatNode(StatNode):
3879 # exc_type ExprNode or None
3880 # exc_value ExprNode or None
3881 # exc_tb ExprNode or None
3883 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3885 def analyse_expressions(self, env):
3887 self.exc_type.analyse_types(env)
3888 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3890 self.exc_value.analyse_types(env)
3891 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3893 self.exc_tb.analyse_types(env)
3894 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3895 env.use_utility_code(raise_utility_code)
3897 nogil_check = Node.gil_error
3898 gil_message = "Raising exception"
3900 def generate_execution_code(self, code):
3902 self.exc_type.generate_evaluation_code(code)
3903 type_code = self.exc_type.py_result()
3907 self.exc_value.generate_evaluation_code(code)
3908 value_code = self.exc_value.py_result()
3912 self.exc_tb.generate_evaluation_code(code)
3913 tb_code = self.exc_tb.py_result()
3917 "__Pyx_Raise(%s, %s, %s);" % (
3921 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3923 obj.generate_disposal_code(code)
3924 obj.free_temps(code)
3926 code.error_goto(self.pos))
3928 def generate_function_definitions(self, env, code):
3929 if self.exc_type is not None:
3930 self.exc_type.generate_function_definitions(env, code)
3931 if self.exc_value is not None:
3932 self.exc_value.generate_function_definitions(env, code)
3933 if self.exc_tb is not None:
3934 self.exc_tb.generate_function_definitions(env, code)
3936 def annotate(self, code):
3938 self.exc_type.annotate(code)
3940 self.exc_value.annotate(code)
3942 self.exc_tb.annotate(code)
3945 class ReraiseStatNode(StatNode):
3949 def analyse_expressions(self, env):
3950 env.use_utility_code(restore_exception_utility_code)
3952 nogil_check = Node.gil_error
3953 gil_message = "Raising exception"
3955 def generate_execution_code(self, code):
3956 vars = code.funcstate.exc_vars
3958 for varname in vars:
3959 code.put_giveref(varname)
3960 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3961 for varname in vars:
3962 code.put("%s = 0; " % varname)
3964 code.putln(code.error_goto(self.pos))
3966 error(self.pos, "Reraise not inside except clause")
3969 class AssertStatNode(StatNode):
3973 # value ExprNode or None
3975 child_attrs = ["cond", "value"]
3977 def analyse_expressions(self, env):
3978 self.cond = self.cond.analyse_boolean_expression(env)
3980 self.value.analyse_types(env)
3981 self.value = self.value.coerce_to_pyobject(env)
3983 nogil_check = Node.gil_error
3984 gil_message = "Raising exception"
3986 def generate_execution_code(self, code):
3987 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
3988 self.cond.generate_evaluation_code(code)
3990 "if (unlikely(!%s)) {" %
3993 self.value.generate_evaluation_code(code)
3995 "PyErr_SetObject(PyExc_AssertionError, %s);" %
3996 self.value.py_result())
3997 self.value.generate_disposal_code(code)
3998 self.value.free_temps(code)
4001 "PyErr_SetNone(PyExc_AssertionError);")
4003 code.error_goto(self.pos))
4006 self.cond.generate_disposal_code(code)
4007 self.cond.free_temps(code)
4008 code.putln("#endif")
4010 def generate_function_definitions(self, env, code):
4011 self.cond.generate_function_definitions(env, code)
4012 if self.value is not None:
4013 self.value.generate_function_definitions(env, code)
4015 def annotate(self, code):
4016 self.cond.annotate(code)
4018 self.value.annotate(code)
4021 class IfStatNode(StatNode):
4024 # if_clauses [IfClauseNode]
4025 # else_clause StatNode or None
4027 child_attrs = ["if_clauses", "else_clause"]
4029 def analyse_control_flow(self, env):
4030 env.start_branching(self.pos)
4031 for if_clause in self.if_clauses:
4032 if_clause.analyse_control_flow(env)
4033 env.next_branch(if_clause.end_pos())
4034 if self.else_clause:
4035 self.else_clause.analyse_control_flow(env)
4036 env.finish_branching(self.end_pos())
4038 def analyse_declarations(self, env):
4039 for if_clause in self.if_clauses:
4040 if_clause.analyse_declarations(env)
4041 if self.else_clause:
4042 self.else_clause.analyse_declarations(env)
4044 def analyse_expressions(self, env):
4045 for if_clause in self.if_clauses:
4046 if_clause.analyse_expressions(env)
4047 if self.else_clause:
4048 self.else_clause.analyse_expressions(env)
4050 def generate_execution_code(self, code):
4051 code.mark_pos(self.pos)
4052 end_label = code.new_label()
4053 for if_clause in self.if_clauses:
4054 if_clause.generate_execution_code(code, end_label)
4055 if self.else_clause:
4056 code.putln("/*else*/ {")
4057 self.else_clause.generate_execution_code(code)
4059 code.put_label(end_label)
4061 def generate_function_definitions(self, env, code):
4062 for clause in self.if_clauses:
4063 clause.generate_function_definitions(env, code)
4064 if self.else_clause is not None:
4065 self.else_clause.generate_function_definitions(env, code)
4067 def annotate(self, code):
4068 for if_clause in self.if_clauses:
4069 if_clause.annotate(code)
4070 if self.else_clause:
4071 self.else_clause.annotate(code)
4074 class IfClauseNode(Node):
4075 # if or elif clause in an if statement
4077 # condition ExprNode
4080 child_attrs = ["condition", "body"]
4082 def analyse_control_flow(self, env):
4083 self.body.analyse_control_flow(env)
4085 def analyse_declarations(self, env):
4086 self.condition.analyse_declarations(env)
4087 self.body.analyse_declarations(env)
4089 def analyse_expressions(self, env):
4091 self.condition.analyse_temp_boolean_expression(env)
4092 self.body.analyse_expressions(env)
4094 def get_constant_condition_result(self):
4095 if self.condition.has_constant_result():
4096 return bool(self.condition.constant_result)
4100 def generate_execution_code(self, code, end_label):
4101 self.condition.generate_evaluation_code(code)
4104 self.condition.result())
4105 self.condition.generate_disposal_code(code)
4106 self.condition.free_temps(code)
4107 self.body.generate_execution_code(code)
4108 code.put_goto(end_label)
4111 def generate_function_definitions(self, env, code):
4112 self.condition.generate_function_definitions(env, code)
4113 self.body.generate_function_definitions(env, code)
4115 def annotate(self, code):
4116 self.condition.annotate(code)
4117 self.body.annotate(code)
4120 class SwitchCaseNode(StatNode):
4121 # Generated in the optimization of an if-elif-else node
4123 # conditions [ExprNode]
4126 child_attrs = ['conditions', 'body']
4128 def generate_execution_code(self, code):
4129 for cond in self.conditions:
4130 code.mark_pos(cond.pos)
4131 cond.generate_evaluation_code(code)
4132 code.putln("case %s:" % cond.result())
4133 self.body.generate_execution_code(code)
4134 code.putln("break;")
4136 def generate_function_definitions(self, env, code):
4137 for cond in self.conditions:
4138 cond.generate_function_definitions(env, code)
4139 self.body.generate_function_definitions(env, code)
4141 def annotate(self, code):
4142 for cond in self.conditions:
4144 self.body.annotate(code)
4146 class SwitchStatNode(StatNode):
4147 # Generated in the optimization of an if-elif-else node
4150 # cases [SwitchCaseNode]
4151 # else_clause StatNode or None
4153 child_attrs = ['test', 'cases', 'else_clause']
4155 def generate_execution_code(self, code):
4156 code.putln("switch (%s) {" % self.test.result())
4157 for case in self.cases:
4158 case.generate_execution_code(code)
4159 if self.else_clause is not None:
4160 code.putln("default:")
4161 self.else_clause.generate_execution_code(code)
4162 code.putln("break;")
4165 def generate_function_definitions(self, env, code):
4166 self.test.generate_function_definitions(env, code)
4167 for case in self.cases:
4168 case.generate_function_definitions(env, code)
4169 if self.else_clause is not None:
4170 self.else_clause.generate_function_definitions(env, code)
4172 def annotate(self, code):
4173 self.test.annotate(code)
4174 for case in self.cases:
4176 if self.else_clause is not None:
4177 self.else_clause.annotate(code)
4179 class LoopNode(object):
4181 def analyse_control_flow(self, env):
4182 env.start_branching(self.pos)
4183 self.body.analyse_control_flow(env)
4184 env.next_branch(self.body.end_pos())
4185 if self.else_clause:
4186 self.else_clause.analyse_control_flow(env)
4187 env.finish_branching(self.end_pos())
4190 class WhileStatNode(LoopNode, StatNode):
4193 # condition ExprNode
4195 # else_clause StatNode
4197 child_attrs = ["condition", "body", "else_clause"]
4199 def analyse_declarations(self, env):
4200 self.body.analyse_declarations(env)
4201 if self.else_clause:
4202 self.else_clause.analyse_declarations(env)
4204 def analyse_expressions(self, env):
4206 self.condition.analyse_temp_boolean_expression(env)
4207 self.body.analyse_expressions(env)
4208 if self.else_clause:
4209 self.else_clause.analyse_expressions(env)
4211 def generate_execution_code(self, code):
4212 old_loop_labels = code.new_loop_labels()
4215 self.condition.generate_evaluation_code(code)
4216 self.condition.generate_disposal_code(code)
4219 self.condition.result())
4220 self.condition.free_temps(code)
4221 self.body.generate_execution_code(code)
4222 code.put_label(code.continue_label)
4224 break_label = code.break_label
4225 code.set_loop_labels(old_loop_labels)
4226 if self.else_clause:
4227 code.putln("/*else*/ {")
4228 self.else_clause.generate_execution_code(code)
4230 code.put_label(break_label)
4232 def generate_function_definitions(self, env, code):
4233 self.condition.generate_function_definitions(env, code)
4234 self.body.generate_function_definitions(env, code)
4235 if self.else_clause is not None:
4236 self.else_clause.generate_function_definitions(env, code)
4238 def annotate(self, code):
4239 self.condition.annotate(code)
4240 self.body.annotate(code)
4241 if self.else_clause:
4242 self.else_clause.annotate(code)
4245 def ForStatNode(pos, **kw):
4246 if 'iterator' in kw:
4247 return ForInStatNode(pos, **kw)
4249 return ForFromStatNode(pos, **kw)
4251 class ForInStatNode(LoopNode, StatNode):
4255 # iterator IteratorNode
4257 # else_clause StatNode
4258 # item NextNode used internally
4260 child_attrs = ["target", "iterator", "body", "else_clause"]
4263 def analyse_declarations(self, env):
4264 self.target.analyse_target_declaration(env)
4265 self.body.analyse_declarations(env)
4266 if self.else_clause:
4267 self.else_clause.analyse_declarations(env)
4269 def analyse_expressions(self, env):
4271 self.target.analyse_target_types(env)
4272 self.iterator.analyse_expressions(env)
4273 self.item = ExprNodes.NextNode(self.iterator, env)
4274 self.item = self.item.coerce_to(self.target.type, env)
4275 self.body.analyse_expressions(env)
4276 if self.else_clause:
4277 self.else_clause.analyse_expressions(env)
4279 def generate_execution_code(self, code):
4280 old_loop_labels = code.new_loop_labels()
4281 self.iterator.allocate_counter_temp(code)
4282 self.iterator.generate_evaluation_code(code)
4285 self.item.generate_evaluation_code(code)
4286 self.target.generate_assignment_code(self.item, code)
4287 self.body.generate_execution_code(code)
4288 code.put_label(code.continue_label)
4291 break_label = code.break_label
4292 code.set_loop_labels(old_loop_labels)
4294 if self.else_clause:
4295 # in nested loops, the 'else' block can contain a
4296 # 'continue' statement for the outer loop, but we may need
4297 # to generate cleanup code before taking that path, so we
4299 orig_continue_label = code.continue_label
4300 code.continue_label = code.new_label('outer_continue')
4302 code.putln("/*else*/ {")
4303 self.else_clause.generate_execution_code(code)
4306 if code.label_used(code.continue_label):
4307 code.put_goto(break_label)
4308 code.put_label(code.continue_label)
4309 self.iterator.generate_disposal_code(code)
4310 code.put_goto(orig_continue_label)
4311 code.set_loop_labels(old_loop_labels)
4313 if code.label_used(break_label):
4314 code.put_label(break_label)
4315 self.iterator.release_counter_temp(code)
4316 self.iterator.generate_disposal_code(code)
4317 self.iterator.free_temps(code)
4319 def generate_function_definitions(self, env, code):
4320 self.target.generate_function_definitions(env, code)
4321 self.iterator.generate_function_definitions(env, code)
4322 self.body.generate_function_definitions(env, code)
4323 if self.else_clause is not None:
4324 self.else_clause.generate_function_definitions(env, code)
4326 def annotate(self, code):
4327 self.target.annotate(code)
4328 self.iterator.annotate(code)
4329 self.body.annotate(code)
4330 if self.else_clause:
4331 self.else_clause.annotate(code)
4332 self.item.annotate(code)
4335 class ForFromStatNode(LoopNode, StatNode):
4336 # for name from expr rel name rel expr
4343 # step ExprNode or None
4345 # else_clause StatNode or None
4351 # loopvar_node ExprNode (usually a NameNode or temp node)
4352 # py_loopvar_node PyTempNode or None
4353 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4355 is_py_target = False
4357 py_loopvar_node = None
4360 gil_message = "For-loop using object bounds or target"
4362 def nogil_check(self, env):
4363 for x in (self.target, self.bound1, self.bound2):
4364 if x.type.is_pyobject:
4367 def analyse_declarations(self, env):
4368 self.target.analyse_target_declaration(env)
4369 self.body.analyse_declarations(env)
4370 if self.else_clause:
4371 self.else_clause.analyse_declarations(env)
4373 def analyse_expressions(self, env):
4375 self.target.analyse_target_types(env)
4376 self.bound1.analyse_types(env)
4377 self.bound2.analyse_types(env)
4378 if self.step is not None:
4379 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4380 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4381 self.step.analyse_types(env)
4383 target_type = self.target.type
4384 if self.target.type.is_numeric:
4385 loop_type = self.target.type
4387 loop_type = PyrexTypes.c_int_type
4388 if not self.bound1.type.is_pyobject:
4389 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4390 if not self.bound2.type.is_pyobject:
4391 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4392 if self.step is not None and not self.step.type.is_pyobject:
4393 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4394 self.bound1 = self.bound1.coerce_to(loop_type, env)
4395 self.bound2 = self.bound2.coerce_to(loop_type, env)
4396 if not self.bound2.is_literal:
4397 self.bound2 = self.bound2.coerce_to_temp(env)
4398 if self.step is not None:
4399 self.step = self.step.coerce_to(loop_type, env)
4400 if not self.step.is_literal:
4401 self.step = self.step.coerce_to_temp(env)
4403 target_type = self.target.type
4404 if not (target_type.is_pyobject or target_type.is_numeric):
4405 error(self.target.pos,
4406 "for-from loop variable must be c numeric type or Python object")
4407 if target_type.is_numeric:
4408 self.is_py_target = False
4409 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4410 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4411 self.loopvar_node = self.target
4412 self.py_loopvar_node = None
4414 self.is_py_target = True
4415 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4416 self.loopvar_node = c_loopvar_node
4417 self.py_loopvar_node = \
4418 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4419 self.body.analyse_expressions(env)
4420 if self.else_clause:
4421 self.else_clause.analyse_expressions(env)
4423 def generate_execution_code(self, code):
4424 old_loop_labels = code.new_loop_labels()
4425 from_range = self.from_range
4426 self.bound1.generate_evaluation_code(code)
4427 self.bound2.generate_evaluation_code(code)
4428 offset, incop = self.relation_table[self.relation1]
4429 if self.step is not None:
4430 self.step.generate_evaluation_code(code)
4431 step = self.step.result()
4432 incop = "%s=%s" % (incop[0], step)
4434 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4435 self.loopvar_node.allocate(code)
4436 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4437 self.py_loopvar_node.allocate(code)
4439 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4441 loopvar_name = self.loopvar_node.result()
4443 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4445 self.bound1.result(), offset,
4446 loopvar_name, self.relation2, self.bound2.result(),
4447 loopvar_name, incop))
4448 if self.py_loopvar_node:
4449 self.py_loopvar_node.generate_evaluation_code(code)
4450 self.target.generate_assignment_code(self.py_loopvar_node, code)
4452 code.putln("%s = %s;" % (
4453 self.target.result(), loopvar_name))
4454 self.body.generate_execution_code(code)
4455 code.put_label(code.continue_label)
4456 if self.py_loopvar_node:
4457 # This mess is to make for..from loops with python targets behave
4458 # exactly like those with C targets with regards to re-assignment
4459 # of the loop variable.
4461 if self.target.entry.is_pyglobal:
4462 # We know target is a NameNode, this is the only ugly case.
4463 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4464 target_node.allocate(code)
4465 interned_cname = code.intern_identifier(self.target.entry.name)
4466 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4467 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4468 target_node.result(),
4469 Naming.module_cname,
4471 code.error_goto_if_null(target_node.result(), self.target.pos)))
4472 code.put_gotref(target_node.result())
4474 target_node = self.target
4475 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4476 from_py_node.temp_code = loopvar_name
4477 from_py_node.generate_result_code(code)
4478 if self.target.entry.is_pyglobal:
4479 code.put_decref(target_node.result(), target_node.type)
4480 target_node.release(code)
4482 if self.py_loopvar_node:
4483 # This is potentially wasteful, but we don't want the semantics to
4484 # depend on whether or not the loop is a python type.
4485 self.py_loopvar_node.generate_evaluation_code(code)
4486 self.target.generate_assignment_code(self.py_loopvar_node, code)
4488 code.funcstate.release_temp(loopvar_name)
4489 break_label = code.break_label
4490 code.set_loop_labels(old_loop_labels)
4491 if self.else_clause:
4492 code.putln("/*else*/ {")
4493 self.else_clause.generate_execution_code(code)
4495 code.put_label(break_label)
4496 self.bound1.generate_disposal_code(code)
4497 self.bound1.free_temps(code)
4498 self.bound2.generate_disposal_code(code)
4499 self.bound2.free_temps(code)
4500 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4501 self.loopvar_node.release(code)
4502 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4503 self.py_loopvar_node.release(code)
4504 if self.step is not None:
4505 self.step.generate_disposal_code(code)
4506 self.step.free_temps(code)
4509 # {relop : (initial offset, increment op)}
4516 def generate_function_definitions(self, env, code):
4517 self.target.generate_function_definitions(env, code)
4518 self.bound1.generate_function_definitions(env, code)
4519 self.bound2.generate_function_definitions(env, code)
4520 if self.step is not None:
4521 self.step.generate_function_definitions(env, code)
4522 self.body.generate_function_definitions(env, code)
4523 if self.else_clause is not None:
4524 self.else_clause.generate_function_definitions(env, code)
4526 def annotate(self, code):
4527 self.target.annotate(code)
4528 self.bound1.annotate(code)
4529 self.bound2.annotate(code)
4531 self.step.annotate(code)
4532 self.body.annotate(code)
4533 if self.else_clause:
4534 self.else_clause.annotate(code)
4537 class WithStatNode(StatNode):
4539 Represents a Python with statement.
4541 This is only used at parse tree level; and is not present in
4542 analysis or generation phases.
4544 # manager The with statement manager object
4545 # target Node (lhs expression)
4547 child_attrs = ["manager", "target", "body"]
4549 class TryExceptStatNode(StatNode):
4550 # try .. except statement
4553 # except_clauses [ExceptClauseNode]
4554 # else_clause StatNode or None
4556 child_attrs = ["body", "except_clauses", "else_clause"]
4558 def analyse_control_flow(self, env):
4559 env.start_branching(self.pos)
4560 self.body.analyse_control_flow(env)
4561 successful_try = env.control_flow # grab this for later
4562 env.next_branch(self.body.end_pos())
4563 env.finish_branching(self.body.end_pos())
4565 env.start_branching(self.except_clauses[0].pos)
4566 for except_clause in self.except_clauses:
4567 except_clause.analyse_control_flow(env)
4568 env.next_branch(except_clause.end_pos())
4570 # the else cause it executed only when the try clause finishes
4571 env.control_flow.incoming = successful_try
4572 if self.else_clause:
4573 self.else_clause.analyse_control_flow(env)
4574 env.finish_branching(self.end_pos())
4576 def analyse_declarations(self, env):
4577 self.body.analyse_declarations(env)
4578 for except_clause in self.except_clauses:
4579 except_clause.analyse_declarations(env)
4580 if self.else_clause:
4581 self.else_clause.analyse_declarations(env)
4582 env.use_utility_code(reset_exception_utility_code)
4584 def analyse_expressions(self, env):
4585 self.body.analyse_expressions(env)
4586 default_clause_seen = 0
4587 for except_clause in self.except_clauses:
4588 except_clause.analyse_expressions(env)
4589 if default_clause_seen:
4590 error(except_clause.pos, "default 'except:' must be last")
4591 if not except_clause.pattern:
4592 default_clause_seen = 1
4593 self.has_default_clause = default_clause_seen
4594 if self.else_clause:
4595 self.else_clause.analyse_expressions(env)
4597 nogil_check = Node.gil_error
4598 gil_message = "Try-except statement"
4600 def generate_execution_code(self, code):
4601 old_return_label = code.return_label
4602 old_break_label = code.break_label
4603 old_continue_label = code.continue_label
4604 old_error_label = code.new_error_label()
4605 our_error_label = code.error_label
4606 except_end_label = code.new_label('exception_handled')
4607 except_error_label = code.new_label('except_error')
4608 except_return_label = code.new_label('except_return')
4609 try_return_label = code.new_label('try_return')
4610 try_break_label = code.new_label('try_break')
4611 try_continue_label = code.new_label('try_continue')
4612 try_end_label = code.new_label('try_end')
4615 code.putln("PyObject %s;" %
4616 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4617 code.putln("__Pyx_ExceptionSave(%s);" %
4618 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4619 for var in Naming.exc_save_vars:
4620 code.put_xgotref(var)
4623 code.return_label = try_return_label
4624 code.break_label = try_break_label
4625 code.continue_label = try_continue_label
4626 self.body.generate_execution_code(code)
4629 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4630 code.error_label = except_error_label
4631 code.return_label = except_return_label
4632 if self.else_clause:
4635 self.else_clause.generate_execution_code(code)
4638 for var in Naming.exc_save_vars:
4639 code.put_xdecref_clear(var, py_object_type)
4640 code.put_goto(try_end_label)
4641 if code.label_used(try_return_label):
4642 code.put_label(try_return_label)
4643 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4644 code.putln("__Pyx_ExceptionReset(%s);" %
4645 ', '.join(Naming.exc_save_vars))
4646 code.put_goto(old_return_label)
4647 code.put_label(our_error_label)
4648 for temp_name, type in temps_to_clean_up:
4649 code.put_xdecref_clear(temp_name, type)
4650 for except_clause in self.except_clauses:
4651 except_clause.generate_handling_code(code, except_end_label)
4653 error_label_used = code.label_used(except_error_label)
4654 if error_label_used or not self.has_default_clause:
4655 if error_label_used:
4656 code.put_label(except_error_label)
4657 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4658 code.putln("__Pyx_ExceptionReset(%s);" %
4659 ', '.join(Naming.exc_save_vars))
4660 code.put_goto(old_error_label)
4662 for exit_label, old_label in zip(
4663 [try_break_label, try_continue_label, except_return_label],
4664 [old_break_label, old_continue_label, old_return_label]):
4666 if code.label_used(exit_label):
4667 code.put_label(exit_label)
4668 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4669 code.putln("__Pyx_ExceptionReset(%s);" %
4670 ', '.join(Naming.exc_save_vars))
4671 code.put_goto(old_label)
4673 if code.label_used(except_end_label):
4674 code.put_label(except_end_label)
4675 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4676 code.putln("__Pyx_ExceptionReset(%s);" %
4677 ', '.join(Naming.exc_save_vars))
4678 code.put_label(try_end_label)
4681 code.return_label = old_return_label
4682 code.break_label = old_break_label
4683 code.continue_label = old_continue_label
4684 code.error_label = old_error_label
4686 def generate_function_definitions(self, env, code):
4687 self.body.generate_function_definitions(env, code)
4688 for except_clause in self.except_clauses:
4689 except_clause.generate_function_definitions(env, code)
4690 if self.else_clause is not None:
4691 self.else_clause.generate_function_definitions(env, code)
4693 def annotate(self, code):
4694 self.body.annotate(code)
4695 for except_node in self.except_clauses:
4696 except_node.annotate(code)
4697 if self.else_clause:
4698 self.else_clause.annotate(code)
4701 class ExceptClauseNode(Node):
4702 # Part of try ... except statement.
4705 # target ExprNode or None
4707 # excinfo_target NameNode or None optional target for exception info
4708 # match_flag string result of exception match
4709 # exc_value ExcValueNode used internally
4710 # function_name string qualified name of enclosing function
4711 # exc_vars (string * 3) local exception variables
4713 # excinfo_target is never set by the parser, but can be set by a transform
4714 # in order to extract more extensive information about the exception as a
4715 # sys.exc_info()-style tuple into a target variable
4717 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4720 excinfo_target = None
4722 def analyse_declarations(self, env):
4724 self.target.analyse_target_declaration(env)
4725 if self.excinfo_target is not None:
4726 self.excinfo_target.analyse_target_declaration(env)
4727 self.body.analyse_declarations(env)
4729 def analyse_expressions(self, env):
4731 genv = env.global_scope()
4732 self.function_name = env.qualified_name
4734 self.pattern.analyse_expressions(env)
4735 self.pattern = self.pattern.coerce_to_pyobject(env)
4738 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4739 self.target.analyse_target_expression(env, self.exc_value)
4740 if self.excinfo_target is not None:
4742 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4743 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4744 self.excinfo_tuple.analyse_expressions(env)
4745 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4747 self.body.analyse_expressions(env)
4749 def generate_handling_code(self, code, end_label):
4750 code.mark_pos(self.pos)
4752 self.pattern.generate_evaluation_code(code)
4754 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4756 "%s = PyErr_ExceptionMatches(%s);" % (
4758 self.pattern.py_result()))
4759 self.pattern.generate_disposal_code(code)
4760 self.pattern.free_temps(code)
4764 code.funcstate.release_temp(match_flag)
4766 code.putln("/*except:*/ {")
4768 if not getattr(self.body, 'stats', True) and \
4769 self.excinfo_target is None and self.target is None:
4770 # most simple case: no exception variable, empty body (pass)
4771 # => reset the exception state, done
4772 code.putln("PyErr_Restore(0,0,0);")
4773 code.put_goto(end_label)
4777 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4780 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4781 # We always have to fetch the exception value even if
4782 # there is no target, because this also normalises the
4783 # exception and stores it in the thread state.
4784 code.globalstate.use_utility_code(get_exception_utility_code)
4785 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4786 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4787 code.error_goto(self.pos)))
4791 self.exc_value.set_var(exc_vars[1])
4792 self.exc_value.generate_evaluation_code(code)
4793 self.target.generate_assignment_code(self.exc_value, code)
4794 if self.excinfo_target is not None:
4795 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4796 node.set_var(tempvar)
4797 self.excinfo_tuple.generate_evaluation_code(code)
4798 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4800 old_break_label, old_continue_label = code.break_label, code.continue_label
4801 code.break_label = code.new_label('except_break')
4802 code.continue_label = code.new_label('except_continue')
4804 old_exc_vars = code.funcstate.exc_vars
4805 code.funcstate.exc_vars = exc_vars
4806 self.body.generate_execution_code(code)
4807 code.funcstate.exc_vars = old_exc_vars
4808 for var in exc_vars:
4809 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4810 code.put_goto(end_label)
4812 if code.label_used(code.break_label):
4813 code.put_label(code.break_label)
4814 for var in exc_vars:
4815 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4816 code.put_goto(old_break_label)
4817 code.break_label = old_break_label
4819 if code.label_used(code.continue_label):
4820 code.put_label(code.continue_label)
4821 for var in exc_vars:
4822 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4823 code.put_goto(old_continue_label)
4824 code.continue_label = old_continue_label
4826 for temp in exc_vars:
4827 code.funcstate.release_temp(temp)
4832 def generate_function_definitions(self, env, code):
4833 if self.target is not None:
4834 self.target.generate_function_definitions(env, code)
4835 self.body.generate_function_definitions(env, code)
4837 def annotate(self, code):
4839 self.pattern.annotate(code)
4841 self.target.annotate(code)
4842 self.body.annotate(code)
4845 class TryFinallyStatNode(StatNode):
4846 # try ... finally statement
4849 # finally_clause StatNode
4851 # The plan is that we funnel all continue, break
4852 # return and error gotos into the beginning of the
4853 # finally block, setting a variable to remember which
4854 # one we're doing. At the end of the finally block, we
4855 # switch on the variable to figure out where to go.
4856 # In addition, if we're doing an error, we save the
4857 # exception on entry to the finally block and restore
4860 child_attrs = ["body", "finally_clause"]
4862 preserve_exception = 1
4864 disallow_continue_in_try_finally = 0
4865 # There doesn't seem to be any point in disallowing
4866 # continue in the try block, since we have no problem
4869 def create_analysed(pos, env, body, finally_clause):
4870 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4872 create_analysed = staticmethod(create_analysed)
4874 def analyse_control_flow(self, env):
4875 env.start_branching(self.pos)
4876 self.body.analyse_control_flow(env)
4877 env.next_branch(self.body.end_pos())
4878 env.finish_branching(self.body.end_pos())
4879 self.finally_clause.analyse_control_flow(env)
4881 def analyse_declarations(self, env):
4882 self.body.analyse_declarations(env)
4883 self.finally_clause.analyse_declarations(env)
4885 def analyse_expressions(self, env):
4886 self.body.analyse_expressions(env)
4887 self.finally_clause.analyse_expressions(env)
4889 nogil_check = Node.gil_error
4890 gil_message = "Try-finally statement"
4892 def generate_execution_code(self, code):
4893 old_error_label = code.error_label
4894 old_labels = code.all_new_labels()
4895 new_labels = code.get_all_labels()
4896 new_error_label = code.error_label
4897 catch_label = code.new_label()
4900 if self.disallow_continue_in_try_finally:
4901 was_in_try_finally = code.funcstate.in_try_finally
4902 code.funcstate.in_try_finally = 1
4903 self.body.generate_execution_code(code)
4904 if self.disallow_continue_in_try_finally:
4905 code.funcstate.in_try_finally = was_in_try_finally
4908 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4909 code.mark_pos(self.finally_clause.pos)
4913 error_label_used = 0
4914 for i, new_label in enumerate(new_labels):
4915 if new_label in code.labels_used:
4916 cases_used.append(i)
4917 if new_label == new_error_label:
4918 error_label_used = 1
4919 error_label_case = i
4923 if error_label_used and self.preserve_exception:
4925 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4927 "int %s;" % Naming.exc_lineno_name)
4928 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4929 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4930 code.putln(exc_var_init_zero)
4932 exc_var_init_zero = None
4933 code.use_label(catch_label)
4935 "__pyx_why = 0; goto %s;" % catch_label)
4936 for i in cases_used:
4937 new_label = new_labels[i]
4938 #if new_label and new_label != "<try>":
4939 if new_label == new_error_label and self.preserve_exception:
4940 self.put_error_catcher(code,
4941 new_error_label, i+1, catch_label, temps_to_clean_up)
4943 code.put('%s: ' % new_label)
4944 if exc_var_init_zero:
4945 code.putln(exc_var_init_zero)
4946 code.putln("__pyx_why = %s; goto %s;" % (
4949 code.put_label(catch_label)
4950 code.set_all_labels(old_labels)
4951 if error_label_used:
4952 code.new_error_label()
4953 finally_error_label = code.error_label
4954 self.finally_clause.generate_execution_code(code)
4955 if error_label_used:
4956 if finally_error_label in code.labels_used and self.preserve_exception:
4957 over_label = code.new_label()
4958 code.put_goto(over_label);
4959 code.put_label(finally_error_label)
4960 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4961 for var in Naming.exc_vars:
4962 code.putln("Py_XDECREF(%s);" % var)
4964 code.put_goto(old_error_label)
4965 code.put_label(over_label)
4966 code.error_label = old_error_label
4969 "switch (__pyx_why) {")
4970 for i in cases_used:
4971 old_label = old_labels[i]
4972 if old_label == old_error_label and self.preserve_exception:
4973 self.put_error_uncatcher(code, i+1, old_error_label)
4975 code.use_label(old_label)
4977 "case %s: goto %s;" % (
4985 def generate_function_definitions(self, env, code):
4986 self.body.generate_function_definitions(env, code)
4987 self.finally_clause.generate_function_definitions(env, code)
4989 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
4990 code.globalstate.use_utility_code(restore_exception_utility_code)
4997 for temp_name, type in temps_to_clean_up:
4998 code.put_xdecref_clear(temp_name, type)
5000 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5004 Naming.exc_lineno_name, Naming.lineno_cname))
5005 code.put_goto(catch_label)
5008 def put_error_uncatcher(self, code, i, error_label):
5009 code.globalstate.use_utility_code(restore_exception_utility_code)
5014 "__Pyx_ErrRestore(%s, %s, %s);" %
5018 Naming.lineno_cname, Naming.exc_lineno_name))
5019 for var in Naming.exc_vars:
5023 code.put_goto(error_label)
5027 def annotate(self, code):
5028 self.body.annotate(code)
5029 self.finally_clause.annotate(code)
5032 class GILStatNode(TryFinallyStatNode):
5033 # 'with gil' or 'with nogil' statement
5035 # state string 'gil' or 'nogil'
5039 preserve_exception = 0
5041 def __init__(self, pos, state, body):
5043 TryFinallyStatNode.__init__(self, pos,
5045 finally_clause = GILExitNode(pos, state = state))
5047 def analyse_expressions(self, env):
5048 env.use_utility_code(force_init_threads_utility_code)
5049 was_nogil = env.nogil
5051 TryFinallyStatNode.analyse_expressions(self, env)
5052 env.nogil = was_nogil
5056 def generate_execution_code(self, code):
5057 code.mark_pos(self.pos)
5058 if self.state == 'gil':
5059 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5061 code.putln("{ PyThreadState *_save;")
5062 code.putln("Py_UNBLOCK_THREADS")
5063 TryFinallyStatNode.generate_execution_code(self, code)
5067 class GILExitNode(StatNode):
5068 # Used as the 'finally' block in a GILStatNode
5070 # state string 'gil' or 'nogil'
5074 def analyse_expressions(self, env):
5077 def generate_execution_code(self, code):
5078 if self.state == 'gil':
5079 code.putln("PyGILState_Release();")
5081 code.putln("Py_BLOCK_THREADS")
5084 class CImportStatNode(StatNode):
5087 # module_name string Qualified name of module being imported
5088 # as_name string or None Name specified in "as" clause, if any
5092 def analyse_declarations(self, env):
5093 if not env.is_module_scope:
5094 error(self.pos, "cimport only allowed at module level")
5096 module_scope = env.find_module(self.module_name, self.pos)
5097 if "." in self.module_name:
5098 names = [EncodedString(name) for name in self.module_name.split(".")]
5100 top_module_scope = env.context.find_submodule(top_name)
5101 module_scope = top_module_scope
5102 for name in names[1:]:
5103 submodule_scope = module_scope.find_submodule(name)
5104 module_scope.declare_module(name, submodule_scope, self.pos)
5105 module_scope = submodule_scope
5107 env.declare_module(self.as_name, module_scope, self.pos)
5109 env.declare_module(top_name, top_module_scope, self.pos)
5111 name = self.as_name or self.module_name
5112 env.declare_module(name, module_scope, self.pos)
5114 def analyse_expressions(self, env):
5117 def generate_execution_code(self, code):
5121 class FromCImportStatNode(StatNode):
5122 # from ... cimport statement
5124 # module_name string Qualified name of module
5125 # imported_names [(pos, name, as_name, kind)] Names to be imported
5129 def analyse_declarations(self, env):
5130 if not env.is_module_scope:
5131 error(self.pos, "cimport only allowed at module level")
5133 module_scope = env.find_module(self.module_name, self.pos)
5134 env.add_imported_module(module_scope)
5135 for pos, name, as_name, kind in self.imported_names:
5137 for local_name, entry in module_scope.entries.items():
5138 env.add_imported_entry(local_name, entry, pos)
5140 entry = module_scope.lookup(name)
5142 if kind and not self.declaration_matches(entry, kind):
5143 entry.redeclared(pos)
5145 if kind == 'struct' or kind == 'union':
5146 entry = module_scope.declare_struct_or_union(name,
5147 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5148 elif kind == 'class':
5149 entry = module_scope.declare_c_class(name, pos = pos,
5150 module_name = self.module_name)
5152 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5153 if submodule_scope.parent_module is module_scope:
5154 env.declare_module(as_name or name, submodule_scope, self.pos)
5156 error(pos, "Name '%s' not declared in module '%s'"
5157 % (name, self.module_name))
5160 local_name = as_name or name
5161 env.add_imported_entry(local_name, entry, pos)
5163 def declaration_matches(self, entry, kind):
5164 if not entry.is_type:
5168 if not type.is_extension_type:
5171 if not type.is_struct_or_union:
5173 if kind != type.kind:
5177 def analyse_expressions(self, env):
5180 def generate_execution_code(self, code):
5184 class FromImportStatNode(StatNode):
5185 # from ... import statement
5188 # items [(string, NameNode)]
5189 # interned_items [(string, NameNode, ExprNode)]
5190 # item PyTempNode used internally
5191 # import_star boolean used internally
5193 child_attrs = ["module"]
5196 def analyse_declarations(self, env):
5197 for name, target in self.items:
5199 if not env.is_module_scope:
5200 error(self.pos, "import * only allowed at module level")
5202 env.has_import_star = 1
5203 self.import_star = 1
5205 target.analyse_target_declaration(env)
5207 def analyse_expressions(self, env):
5209 self.module.analyse_expressions(env)
5210 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5211 self.interned_items = []
5212 for name, target in self.items:
5214 for _, entry in env.entries.items():
5215 if not entry.is_type and entry.type.is_extension_type:
5216 env.use_utility_code(ExprNodes.type_test_utility_code)
5219 entry = env.lookup(target.name)
5220 # check whether or not entry is already cimported
5221 if (entry.is_type and entry.type.name == name
5222 and hasattr(entry.type, 'module_name')):
5223 if entry.type.module_name == self.module.module_name.value:
5224 # cimported with absolute name
5227 # cimported with relative name
5228 module = env.find_module(self.module.module_name.value,
5230 if entry.type.module_name == module.qualified_name:
5232 except AttributeError:
5234 target.analyse_target_expression(env, None)
5235 if target.type is py_object_type:
5238 coerced_item = self.item.coerce_to(target.type, env)
5239 self.interned_items.append((name, target, coerced_item))
5241 def generate_execution_code(self, code):
5242 self.module.generate_evaluation_code(code)
5243 if self.import_star:
5245 'if (%s(%s) < 0) %s;' % (
5247 self.module.py_result(),
5248 code.error_goto(self.pos)))
5249 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5250 self.item.set_cname(item_temp)
5251 for name, target, coerced_item in self.interned_items:
5252 cname = code.intern_identifier(name)
5254 '%s = PyObject_GetAttr(%s, %s); %s' % (
5256 self.module.py_result(),
5258 code.error_goto_if_null(item_temp, self.pos)))
5259 code.put_gotref(item_temp)
5260 if coerced_item is None:
5261 target.generate_assignment_code(self.item, code)
5263 coerced_item.allocate_temp_result(code)
5264 coerced_item.generate_result_code(code)
5265 target.generate_assignment_code(coerced_item, code)
5266 code.put_decref_clear(item_temp, py_object_type)
5267 code.funcstate.release_temp(item_temp)
5268 self.module.generate_disposal_code(code)
5269 self.module.free_temps(code)
5273 #------------------------------------------------------------------------------------
5275 # Runtime support code
5277 #------------------------------------------------------------------------------------
5279 utility_function_predeclarations = \
5281 /* inline attribute */
5282 #ifndef CYTHON_INLINE
5283 #if defined(__GNUC__)
5284 #define CYTHON_INLINE __inline__
5285 #elif defined(_MSC_VER)
5286 #define CYTHON_INLINE __inline
5287 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5288 #define CYTHON_INLINE inline
5290 #define CYTHON_INLINE
5294 /* unused attribute */
5295 #ifndef CYTHON_UNUSED
5296 # if defined(__GNUC__)
5297 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5298 # define CYTHON_UNUSED __attribute__ ((__unused__))
5300 # define CYTHON_UNUSED
5302 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5303 # define CYTHON_UNUSED __attribute__ ((__unused__))
5305 # define CYTHON_UNUSED
5309 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*/
5313 if Options.gcc_branch_hints:
5314 branch_prediction_macros = \
5317 /* Test for GCC > 2.95 */
5318 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5319 #define likely(x) __builtin_expect(!!(x), 1)
5320 #define unlikely(x) __builtin_expect(!!(x), 0)
5321 #else /* __GNUC__ > 2 ... */
5322 #define likely(x) (x)
5323 #define unlikely(x) (x)
5324 #endif /* __GNUC__ > 2 ... */
5325 #else /* __GNUC__ */
5326 #define likely(x) (x)
5327 #define unlikely(x) (x)
5328 #endif /* __GNUC__ */
5331 branch_prediction_macros = \
5333 #define likely(x) (x)
5334 #define unlikely(x) (x)
5337 #get_name_predeclaration = \
5338 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5340 #get_name_interned_predeclaration = \
5341 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5343 #------------------------------------------------------------------------------------
5345 printing_utility_code = UtilityCode(
5347 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5348 #if PY_MAJOR_VERSION >= 3
5349 static PyObject* %s = 0;
5350 static PyObject* %s = 0;
5352 """ % (Naming.print_function, Naming.print_function_kwargs),
5354 #if PY_MAJOR_VERSION >= 3
5358 """ % (Naming.print_function, Naming.print_function_kwargs),
5360 #if PY_MAJOR_VERSION < 3
5361 static PyObject *__Pyx_GetStdout(void) {
5362 PyObject *f = PySys_GetObject((char *)"stdout");
5364 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5369 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5374 if (!(f = __Pyx_GetStdout()))
5377 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5378 if (PyFile_SoftSpace(f, 1)) {
5379 if (PyFile_WriteString(" ", f) < 0)
5382 v = PyTuple_GET_ITEM(arg_tuple, i);
5383 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5385 if (PyString_Check(v)) {
5386 char *s = PyString_AsString(v);
5387 Py_ssize_t len = PyString_Size(v);
5389 isspace(Py_CHARMASK(s[len-1])) &&
5391 PyFile_SoftSpace(f, 0);
5395 if (PyFile_WriteString("\n", f) < 0)
5397 PyFile_SoftSpace(f, 0);
5402 #else /* Python 3 has a print function */
5404 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5405 PyObject* kwargs = 0;
5406 PyObject* result = 0;
5407 PyObject* end_string;
5408 if (unlikely(!%(PRINT_FUNCTION)s)) {
5409 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5410 if (!%(PRINT_FUNCTION)s)
5414 kwargs = PyDict_New();
5415 if (unlikely(!kwargs))
5417 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5420 end_string = PyUnicode_FromStringAndSize(" ", 1);
5421 if (unlikely(!end_string))
5423 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5424 Py_DECREF(end_string);
5427 Py_DECREF(end_string);
5429 } else if (!newline) {
5430 if (unlikely(!%(PRINT_KWARGS)s)) {
5431 %(PRINT_KWARGS)s = PyDict_New();
5432 if (unlikely(!%(PRINT_KWARGS)s))
5434 end_string = PyUnicode_FromStringAndSize(" ", 1);
5435 if (unlikely(!end_string))
5437 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5438 Py_DECREF(end_string);
5441 Py_DECREF(end_string);
5443 kwargs = %(PRINT_KWARGS)s;
5445 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5446 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5453 if (kwargs != %(PRINT_KWARGS)s)
5459 """ % {'BUILTINS' : Naming.builtins_cname,
5460 'PRINT_FUNCTION' : Naming.print_function,
5461 'PRINT_KWARGS' : Naming.print_function_kwargs}
5465 printing_one_utility_code = UtilityCode(
5467 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5470 #if PY_MAJOR_VERSION < 3
5472 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5474 if (!(f = __Pyx_GetStdout()))
5477 if (PyFile_SoftSpace(f, 0)) {
5478 if (PyFile_WriteString(" ", f) < 0)
5481 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5483 if (PyFile_WriteString("\n", f) < 0)
5486 /* the line below is just to avoid compiler
5487 * compiler warnings about unused functions */
5488 return __Pyx_Print(f, NULL, 0);
5491 #else /* Python 3 has a print function */
5493 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5495 PyObject* arg_tuple = PyTuple_New(1);
5496 if (unlikely(!arg_tuple))
5499 PyTuple_SET_ITEM(arg_tuple, 0, o);
5500 res = __Pyx_Print(stream, arg_tuple, 1);
5501 Py_DECREF(arg_tuple);
5507 requires=[printing_utility_code])
5511 #------------------------------------------------------------------------------------
5513 # Exception raising code
5515 # Exceptions are raised by __Pyx_Raise() and stored as plain
5516 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5517 # 'except' statement, curexc_* is moved over to exc_* by
5518 # __Pyx_GetException()
5520 restore_exception_utility_code = UtilityCode(
5522 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5523 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5526 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5527 PyObject *tmp_type, *tmp_value, *tmp_tb;
5528 PyThreadState *tstate = PyThreadState_GET();
5530 tmp_type = tstate->curexc_type;
5531 tmp_value = tstate->curexc_value;
5532 tmp_tb = tstate->curexc_traceback;
5533 tstate->curexc_type = type;
5534 tstate->curexc_value = value;
5535 tstate->curexc_traceback = tb;
5536 Py_XDECREF(tmp_type);
5537 Py_XDECREF(tmp_value);
5541 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5542 PyThreadState *tstate = PyThreadState_GET();
5543 *type = tstate->curexc_type;
5544 *value = tstate->curexc_value;
5545 *tb = tstate->curexc_traceback;
5547 tstate->curexc_type = 0;
5548 tstate->curexc_value = 0;
5549 tstate->curexc_traceback = 0;
5554 # The following function is based on do_raise() from ceval.c. There
5555 # are separate versions for Python2 and Python3 as exception handling
5556 # has changed quite a lot between the two versions.
5558 raise_utility_code = UtilityCode(
5560 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5563 #if PY_MAJOR_VERSION < 3
5564 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5568 /* First, check the traceback argument, replacing None with NULL. */
5569 if (tb == Py_None) {
5573 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5574 PyErr_SetString(PyExc_TypeError,
5575 "raise: arg 3 must be a traceback or None");
5578 /* Next, replace a missing value with None */
5579 if (value == NULL) {
5583 #if PY_VERSION_HEX < 0x02050000
5584 if (!PyClass_Check(type))
5586 if (!PyType_Check(type))
5589 /* Raising an instance. The value should be a dummy. */
5590 if (value != Py_None) {
5591 PyErr_SetString(PyExc_TypeError,
5592 "instance exception may not have a separate value");
5595 /* Normalize to raise <class>, <instance> */
5598 #if PY_VERSION_HEX < 0x02050000
5599 if (PyInstance_Check(type)) {
5600 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5605 PyErr_SetString(PyExc_TypeError,
5606 "raise: exception must be an old-style class or instance");
5610 type = (PyObject*) Py_TYPE(type);
5612 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5613 PyErr_SetString(PyExc_TypeError,
5614 "raise: exception class must be a subclass of BaseException");
5620 __Pyx_ErrRestore(type, value, tb);
5629 #else /* Python 3+ */
5631 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5632 if (tb == Py_None) {
5634 } else if (tb && !PyTraceBack_Check(tb)) {
5635 PyErr_SetString(PyExc_TypeError,
5636 "raise: arg 3 must be a traceback or None");
5639 if (value == Py_None)
5642 if (PyExceptionInstance_Check(type)) {
5644 PyErr_SetString(PyExc_TypeError,
5645 "instance exception may not have a separate value");
5649 type = (PyObject*) Py_TYPE(value);
5650 } else if (!PyExceptionClass_Check(type)) {
5651 PyErr_SetString(PyExc_TypeError,
5652 "raise: exception class must be a subclass of BaseException");
5656 PyErr_SetObject(type, value);
5659 PyThreadState *tstate = PyThreadState_GET();
5660 PyObject* tmp_tb = tstate->curexc_traceback;
5663 tstate->curexc_traceback = tb;
5673 requires=[restore_exception_utility_code])
5675 #------------------------------------------------------------------------------------
5677 get_exception_utility_code = UtilityCode(
5679 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5682 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5683 PyObject *local_type, *local_value, *local_tb;
5684 PyObject *tmp_type, *tmp_value, *tmp_tb;
5685 PyThreadState *tstate = PyThreadState_GET();
5686 local_type = tstate->curexc_type;
5687 local_value = tstate->curexc_value;
5688 local_tb = tstate->curexc_traceback;
5689 tstate->curexc_type = 0;
5690 tstate->curexc_value = 0;
5691 tstate->curexc_traceback = 0;
5692 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5693 if (unlikely(tstate->curexc_type))
5695 #if PY_MAJOR_VERSION >= 3
5696 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5700 *value = local_value;
5702 Py_INCREF(local_type);
5703 Py_INCREF(local_value);
5704 Py_INCREF(local_tb);
5705 tmp_type = tstate->exc_type;
5706 tmp_value = tstate->exc_value;
5707 tmp_tb = tstate->exc_traceback;
5708 tstate->exc_type = local_type;
5709 tstate->exc_value = local_value;
5710 tstate->exc_traceback = local_tb;
5711 /* Make sure tstate is in a consistent state when we XDECREF
5712 these objects (XDECREF may run arbitrary code). */
5713 Py_XDECREF(tmp_type);
5714 Py_XDECREF(tmp_value);
5721 Py_XDECREF(local_type);
5722 Py_XDECREF(local_value);
5723 Py_XDECREF(local_tb);
5729 #------------------------------------------------------------------------------------
5731 get_exception_tuple_utility_code = UtilityCode(proto="""
5732 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5734 # I doubt that calling __Pyx_GetException() here is correct as it moves
5735 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5736 # exception handlers later on from receiving it.
5738 static PyObject *__Pyx_GetExceptionTuple(void) {
5739 PyObject *type = NULL, *value = NULL, *tb = NULL;
5740 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5741 PyObject* exc_info = PyTuple_New(3);
5746 PyTuple_SET_ITEM(exc_info, 0, type);
5747 PyTuple_SET_ITEM(exc_info, 1, value);
5748 PyTuple_SET_ITEM(exc_info, 2, tb);
5755 requires=[get_exception_utility_code])
5757 #------------------------------------------------------------------------------------
5759 reset_exception_utility_code = UtilityCode(
5761 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5762 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5765 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5766 PyThreadState *tstate = PyThreadState_GET();
5767 *type = tstate->exc_type;
5768 *value = tstate->exc_value;
5769 *tb = tstate->exc_traceback;
5775 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5776 PyObject *tmp_type, *tmp_value, *tmp_tb;
5777 PyThreadState *tstate = PyThreadState_GET();
5778 tmp_type = tstate->exc_type;
5779 tmp_value = tstate->exc_value;
5780 tmp_tb = tstate->exc_traceback;
5781 tstate->exc_type = type;
5782 tstate->exc_value = value;
5783 tstate->exc_traceback = tb;
5784 Py_XDECREF(tmp_type);
5785 Py_XDECREF(tmp_value);
5790 #------------------------------------------------------------------------------------
5792 arg_type_test_utility_code = UtilityCode(
5794 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5795 const char *name, int exact); /*proto*/
5798 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5799 const char *name, int exact)
5802 PyErr_Format(PyExc_SystemError, "Missing type object");
5805 if (none_allowed && obj == Py_None) return 1;
5807 if (Py_TYPE(obj) == type) return 1;
5810 if (PyObject_TypeCheck(obj, type)) return 1;
5812 PyErr_Format(PyExc_TypeError,
5813 "Argument '%s' has incorrect type (expected %s, got %s)",
5814 name, type->tp_name, Py_TYPE(obj)->tp_name);
5819 #------------------------------------------------------------------------------------
5821 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5822 # many or too few positional arguments were found. This handles
5823 # Py_ssize_t formatting correctly.
5825 raise_argtuple_invalid_utility_code = UtilityCode(
5827 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5828 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5831 static void __Pyx_RaiseArgtupleInvalid(
5832 const char* func_name,
5836 Py_ssize_t num_found)
5838 Py_ssize_t num_expected;
5839 const char *number, *more_or_less;
5841 if (num_found < num_min) {
5842 num_expected = num_min;
5843 more_or_less = "at least";
5845 num_expected = num_max;
5846 more_or_less = "at most";
5849 more_or_less = "exactly";
5851 number = (num_expected == 1) ? "" : "s";
5852 PyErr_Format(PyExc_TypeError,
5853 #if PY_VERSION_HEX < 0x02050000
5854 "%s() takes %s %d positional argument%s (%d given)",
5856 "%s() takes %s %zd positional argument%s (%zd given)",
5858 func_name, more_or_less, num_expected, number, num_found);
5862 raise_keyword_required_utility_code = UtilityCode(
5864 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5867 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5868 const char* func_name,
5871 PyErr_Format(PyExc_TypeError,
5872 #if PY_MAJOR_VERSION >= 3
5873 "%s() needs keyword-only argument %U", func_name, kw_name);
5875 "%s() needs keyword-only argument %s", func_name,
5876 PyString_AS_STRING(kw_name));
5881 raise_double_keywords_utility_code = UtilityCode(
5883 static void __Pyx_RaiseDoubleKeywordsError(
5884 const char* func_name, PyObject* kw_name); /*proto*/
5887 static void __Pyx_RaiseDoubleKeywordsError(
5888 const char* func_name,
5891 PyErr_Format(PyExc_TypeError,
5892 #if PY_MAJOR_VERSION >= 3
5893 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5895 "%s() got multiple values for keyword argument '%s'", func_name,
5896 PyString_AS_STRING(kw_name));
5901 #------------------------------------------------------------------------------------
5903 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5904 # were passed to a function, or if any keywords were passed to a
5905 # function that does not accept them.
5907 keyword_string_check_utility_code = UtilityCode(
5909 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5910 const char* function_name, int kw_allowed); /*proto*/
5913 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5915 const char* function_name,
5920 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5921 #if PY_MAJOR_VERSION < 3
5922 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5924 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5926 goto invalid_keyword_type;
5928 if ((!kw_allowed) && unlikely(key))
5929 goto invalid_keyword;
5931 invalid_keyword_type:
5932 PyErr_Format(PyExc_TypeError,
5933 "%s() keywords must be strings", function_name);
5936 PyErr_Format(PyExc_TypeError,
5937 #if PY_MAJOR_VERSION < 3
5938 "%s() got an unexpected keyword argument '%s'",
5939 function_name, PyString_AsString(key));
5941 "%s() got an unexpected keyword argument '%U'",
5942 function_name, key);
5948 #------------------------------------------------------------------------------------
5950 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5951 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5952 # keywords will raise an invalid keyword error.
5954 # Three kinds of errors are checked: 1) non-string keywords, 2)
5955 # unexpected keywords and 3) overlap with positional arguments.
5957 # If num_posargs is greater 0, it denotes the number of positional
5958 # arguments that were passed and that must therefore not appear
5959 # amongst the keywords as well.
5961 # This method does not check for required keyword arguments.
5964 parse_keywords_utility_code = UtilityCode(
5966 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5967 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
5968 const char* function_name); /*proto*/
5971 static int __Pyx_ParseOptionalKeywords(
5973 PyObject **argnames[],
5976 Py_ssize_t num_pos_args,
5977 const char* function_name)
5979 PyObject *key = 0, *value = 0;
5982 PyObject*** first_kw_arg = argnames + num_pos_args;
5984 while (PyDict_Next(kwds, &pos, &key, &value)) {
5985 name = first_kw_arg;
5986 while (*name && (**name != key)) name++;
5988 values[name-argnames] = value;
5990 #if PY_MAJOR_VERSION < 3
5991 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
5993 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
5995 goto invalid_keyword_type;
5997 for (name = first_kw_arg; *name; name++) {
5998 #if PY_MAJOR_VERSION >= 3
5999 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6000 PyUnicode_Compare(**name, key) == 0) break;
6002 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6003 _PyString_Eq(**name, key)) break;
6007 values[name-argnames] = value;
6009 /* unexpected keyword found */
6010 for (name=argnames; name != first_kw_arg; name++) {
6011 if (**name == key) goto arg_passed_twice;
6012 #if PY_MAJOR_VERSION >= 3
6013 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6014 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6016 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6017 _PyString_Eq(**name, key)) goto arg_passed_twice;
6021 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6023 goto invalid_keyword;
6031 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6033 invalid_keyword_type:
6034 PyErr_Format(PyExc_TypeError,
6035 "%s() keywords must be strings", function_name);
6038 PyErr_Format(PyExc_TypeError,
6039 #if PY_MAJOR_VERSION < 3
6040 "%s() got an unexpected keyword argument '%s'",
6041 function_name, PyString_AsString(key));
6043 "%s() got an unexpected keyword argument '%U'",
6044 function_name, key);
6051 #------------------------------------------------------------------------------------
6053 traceback_utility_code = UtilityCode(
6055 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6058 #include "compile.h"
6059 #include "frameobject.h"
6060 #include "traceback.h"
6062 static void __Pyx_AddTraceback(const char *funcname) {
6063 PyObject *py_srcfile = 0;
6064 PyObject *py_funcname = 0;
6065 PyObject *py_globals = 0;
6066 PyCodeObject *py_code = 0;
6067 PyFrameObject *py_frame = 0;
6069 #if PY_MAJOR_VERSION < 3
6070 py_srcfile = PyString_FromString(%(FILENAME)s);
6072 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6074 if (!py_srcfile) goto bad;
6076 #if PY_MAJOR_VERSION < 3
6077 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6079 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6083 #if PY_MAJOR_VERSION < 3
6084 py_funcname = PyString_FromString(funcname);
6086 py_funcname = PyUnicode_FromString(funcname);
6089 if (!py_funcname) goto bad;
6090 py_globals = PyModule_GetDict(%(GLOBALS)s);
6091 if (!py_globals) goto bad;
6092 py_code = PyCode_New(
6093 0, /*int argcount,*/
6094 #if PY_MAJOR_VERSION >= 3
6095 0, /*int kwonlyargcount,*/
6098 0, /*int stacksize,*/
6100 %(EMPTY_BYTES)s, /*PyObject *code,*/
6101 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6102 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6103 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6104 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6105 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6106 py_srcfile, /*PyObject *filename,*/
6107 py_funcname, /*PyObject *name,*/
6108 %(LINENO)s, /*int firstlineno,*/
6109 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6111 if (!py_code) goto bad;
6112 py_frame = PyFrame_New(
6113 PyThreadState_GET(), /*PyThreadState *tstate,*/
6114 py_code, /*PyCodeObject *code,*/
6115 py_globals, /*PyObject *globals,*/
6116 0 /*PyObject *locals*/
6118 if (!py_frame) goto bad;
6119 py_frame->f_lineno = %(LINENO)s;
6120 PyTraceBack_Here(py_frame);
6122 Py_XDECREF(py_srcfile);
6123 Py_XDECREF(py_funcname);
6124 Py_XDECREF(py_code);
6125 Py_XDECREF(py_frame);
6128 'FILENAME': Naming.filename_cname,
6129 'LINENO': Naming.lineno_cname,
6130 'CFILENAME': Naming.cfilenm_cname,
6131 'CLINENO': Naming.clineno_cname,
6132 'GLOBALS': Naming.module_cname,
6133 'EMPTY_TUPLE' : Naming.empty_tuple,
6134 'EMPTY_BYTES' : Naming.empty_bytes,
6137 #------------------------------------------------------------------------------------
6139 unraisable_exception_utility_code = UtilityCode(
6141 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6144 static void __Pyx_WriteUnraisable(const char *name) {
6145 PyObject *old_exc, *old_val, *old_tb;
6147 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6148 #if PY_MAJOR_VERSION < 3
6149 ctx = PyString_FromString(name);
6151 ctx = PyUnicode_FromString(name);
6153 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6155 PyErr_WriteUnraisable(Py_None);
6157 PyErr_WriteUnraisable(ctx);
6162 requires=[restore_exception_utility_code])
6164 #------------------------------------------------------------------------------------
6166 set_vtable_utility_code = UtilityCode(
6168 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6171 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6172 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6173 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6175 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6179 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6189 #------------------------------------------------------------------------------------
6191 get_vtable_utility_code = UtilityCode(
6193 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6196 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6197 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6200 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6201 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6203 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6205 if (!*(void **)vtabptr)
6215 #------------------------------------------------------------------------------------
6217 init_string_tab_utility_code = UtilityCode(
6219 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6222 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6224 #if PY_MAJOR_VERSION < 3
6225 if (t->is_unicode) {
6226 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6227 } else if (t->intern) {
6228 *t->p = PyString_InternFromString(t->s);
6230 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6232 #else /* Python 3+ has unicode identifiers */
6233 if (t->is_unicode | t->is_str) {
6235 *t->p = PyUnicode_InternFromString(t->s);
6236 } else if (t->encoding) {
6237 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6239 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6242 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6253 #------------------------------------------------------------------------------------
6255 force_init_threads_utility_code = UtilityCode(
6257 #ifndef __PYX_FORCE_INIT_THREADS
6258 #if PY_VERSION_HEX < 0x02040200
6259 #define __PYX_FORCE_INIT_THREADS 1
6261 #define __PYX_FORCE_INIT_THREADS 0
6266 #------------------------------------------------------------------------------------
6268 # Note that cPython ignores PyTrace_EXCEPTION,
6269 # but maybe some other profilers don't.
6271 profile_utility_code = UtilityCode(proto="""
6272 #ifndef CYTHON_PROFILE
6273 #define CYTHON_PROFILE 1
6276 #ifndef CYTHON_PROFILE_REUSE_FRAME
6277 #define CYTHON_PROFILE_REUSE_FRAME 0
6282 #include "compile.h"
6283 #include "frameobject.h"
6284 #include "traceback.h"
6286 #if CYTHON_PROFILE_REUSE_FRAME
6287 #define CYTHON_FRAME_MODIFIER static
6288 #define CYTHON_FRAME_DEL
6290 #define CYTHON_FRAME_MODIFIER
6291 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6294 #define __Pyx_TraceDeclarations \\
6295 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6296 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6297 int __Pyx_use_tracing = 0;
6299 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6300 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6301 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6304 #define __Pyx_TraceException() \\
6305 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6306 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6308 PyThreadState_GET()->c_profilefunc( \\
6309 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6310 Py_DECREF(exc_info); \\
6314 #define __Pyx_TraceReturn(result) \\
6315 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6316 PyThreadState_GET()->c_profilefunc( \\
6317 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6318 CYTHON_FRAME_DEL; \\
6321 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6322 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6326 #define __Pyx_TraceDeclarations
6327 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6328 #define __Pyx_TraceException()
6329 #define __Pyx_TraceReturn(result)
6331 #endif /* CYTHON_PROFILE */
6334 "FRAME": Naming.frame_cname,
6335 "FRAME_CODE": Naming.frame_code_cname,
6341 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6342 PyFrameObject** frame,
6343 const char *funcname,
6344 const char *srcfile,
6346 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6347 if (*code == NULL) {
6348 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6349 if (*code == NULL) return 0;
6351 *frame = PyFrame_New(
6352 PyThreadState_GET(), /*PyThreadState *tstate*/
6353 *code, /*PyCodeObject *code*/
6354 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6355 0 /*PyObject *locals*/
6357 if (*frame == NULL) return 0;
6360 (*frame)->f_tstate = PyThreadState_GET();
6362 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6365 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6366 PyObject *py_srcfile = 0;
6367 PyObject *py_funcname = 0;
6368 PyCodeObject *py_code = 0;
6370 #if PY_MAJOR_VERSION < 3
6371 py_funcname = PyString_FromString(funcname);
6372 py_srcfile = PyString_FromString(srcfile);
6374 py_funcname = PyUnicode_FromString(funcname);
6375 py_srcfile = PyUnicode_FromString(srcfile);
6377 if (!py_funcname | !py_srcfile) goto bad;
6379 py_code = PyCode_New(
6380 0, /*int argcount,*/
6381 #if PY_MAJOR_VERSION >= 3
6382 0, /*int kwonlyargcount,*/
6385 0, /*int stacksize,*/
6387 %(EMPTY_BYTES)s, /*PyObject *code,*/
6388 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6389 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6390 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6391 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6392 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6393 py_srcfile, /*PyObject *filename,*/
6394 py_funcname, /*PyObject *name,*/
6395 firstlineno, /*int firstlineno,*/
6396 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6400 Py_XDECREF(py_srcfile);
6401 Py_XDECREF(py_funcname);
6406 #endif /* CYTHON_PROFILE */
6408 'EMPTY_TUPLE' : Naming.empty_tuple,
6409 'EMPTY_BYTES' : Naming.empty_bytes,
6410 "MODULE": Naming.module_cname,