3 # Pyrex - Parse tree nodes
6 import sys, os, time, copy
12 from sets import Set as set
16 from Errors import error, warning, InternalError
20 from PyrexTypes import py_object_type, error_type, CFuncType
21 from Symtab import ModuleScope, LocalScope, ClosureScope, \
22 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
23 from Cython.Utils import open_new_file, replace_suffix
24 from Code import UtilityCode
25 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
30 absolute_path_length = 0
32 def relative_position(pos):
34 We embed the relative filename in the generated C file, since we
35 don't want to have to regnerate and compile all the source code
36 whenever the Python install directory moves (which could happen,
37 e.g,. when distributing binaries.)
40 a position tuple -- (absolute filename, line number column position)
48 global absolute_path_length
49 if absolute_path_length==0:
50 absolute_path_length = len(os.path.abspath(os.getcwd()))
51 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
53 def embed_position(pos, docstring):
54 if not Options.embed_pos_in_docstring:
56 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
59 return EncodedString(pos_line)
61 # make sure we can encode the filename in the docstring encoding
62 # otherwise make the docstring a unicode string
63 encoding = docstring.encoding
64 if encoding is not None:
66 encoded_bytes = pos_line.encode(encoding)
67 except UnicodeEncodeError:
71 # reuse the string encoding of the original docstring
72 doc = EncodedString(pos_line)
74 doc = EncodedString(pos_line + u'\n' + docstring)
75 doc.encoding = encoding
79 from Code import CCodeWriter
80 from types import FunctionType
82 def write_func_call(func):
84 if len(args) > 1 and isinstance(args[1], CCodeWriter):
85 # here we annotate the code with this function call
86 # but only if new code is generated
88 marker = ' /* %s -> %s.%s %s */' % (
89 ' ' * code.call_level,
90 node.__class__.__name__,
93 pristine = code.buffer.stream.tell()
95 start = code.buffer.stream.tell()
97 res = func(*args, **kwds)
99 if start == code.buffer.stream.tell():
100 code.buffer.stream.seek(pristine)
102 marker = marker.replace('->', '<-')
106 return func(*args, **kwds)
109 class VerboseCodeWriter(type):
110 # Set this as a metaclass to trace function calls in code.
111 # This slows down code generation and makes much larger files.
112 def __new__(cls, name, bases, attrs):
114 for mname, m in attrs.items():
115 if isinstance(m, FunctionType):
116 attrs[mname] = write_func_call(m)
117 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
121 # pos (string, int, int) Source file position
122 # is_name boolean Is a NameNode
123 # is_literal boolean Is a ConstNode
125 if DebugFlags.debug_trace_code_generation:
126 __metaclass__ = VerboseCodeWriter
132 # All descandants should set child_attrs to a list of the attributes
133 # containing nodes considered "children" in the tree. Each such attribute
134 # can either contain a single node or a list of nodes. See Visitor.py.
137 def __init__(self, pos, **kw):
139 self.__dict__.update(kw)
141 gil_message = "Operation"
145 def gil_error(self, env=None):
146 error(self.pos, "%s not allowed without gil" % self.gil_message)
148 cpp_message = "Operation"
150 def cpp_check(self, env):
155 error(self.pos, "%s only allowed in c++" % self.cpp_message)
157 def clone_node(self):
158 """Clone the node. This is defined as a shallow copy, except for member lists
159 amongst the child attributes (from get_child_accessors) which are also
160 copied. Lists containing child nodes are thus seen as a way for the node
161 to hold multiple children directly; the list is not treated as a seperate
162 level in the tree."""
163 result = copy.copy(self)
164 for attrname in result.child_attrs:
165 value = getattr(result, attrname)
166 if isinstance(value, list):
167 setattr(result, attrname, [x for x in value])
172 # There are 4 phases of parse tree processing, applied in order to
173 # all the statements in a given scope-block:
175 # (0) analyse_control_flow
176 # Create the control flow tree into which state can be asserted and
179 # (1) analyse_declarations
180 # Make symbol table entries for all declarations at the current
181 # level, both explicit (def, cdef, etc.) and implicit (assignment
182 # to an otherwise undeclared name).
184 # (2) analyse_expressions
185 # Determine the result types of expressions and fill in the
186 # 'type' attribute of each ExprNode. Insert coercion nodes into the
187 # tree where needed to convert to and from Python objects.
188 # Allocate temporary locals for intermediate results. Fill
189 # in the 'result_code' attribute of each ExprNode with a C code
193 # Emit C code for all declarations, statements and expressions.
194 # Recursively applies the 3 processing phases to the bodies of
198 def analyse_control_flow(self, env):
201 def analyse_declarations(self, env):
204 def analyse_expressions(self, env):
205 raise InternalError("analyse_expressions not implemented for %s" % \
206 self.__class__.__name__)
208 def generate_code(self, code):
209 raise InternalError("generate_code not implemented for %s" % \
210 self.__class__.__name__)
212 def annotate(self, code):
213 # mro does the wrong thing
214 if isinstance(self, BlockNode):
215 self.body.annotate(code)
220 except AttributeError:
222 if not self.child_attrs:
225 for attr in self.child_attrs:
226 child = getattr(self, attr)
227 # Sometimes lists, sometimes nodes
230 elif isinstance(child, list):
232 pos = max(pos, c.end_pos())
234 pos = max(pos, child.end_pos())
238 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
240 return "<...nesting level cutoff...>"
241 if encountered is None:
243 if id(self) in encountered:
244 return "<%s (%d) -- already output>" % (self.__class__.__name__, id(self))
245 encountered.add(id(self))
247 def dump_child(x, level):
248 if isinstance(x, Node):
249 return x.dump(level, filter_out, cutoff-1, encountered)
250 elif isinstance(x, list):
251 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
256 attrs = [(key, value) for key, value in self.__dict__.iteritems() if key not in filter_out]
258 return "<%s (%d)>" % (self.__class__.__name__, id(self))
261 res = "<%s (%d)\n" % (self.__class__.__name__, id(self))
262 for key, value in attrs:
263 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
264 res += "%s>" % indent
267 class CompilerDirectivesNode(Node):
269 Sets compiler directives for the children nodes
271 # directives {string:value} A dictionary holding the right value for
272 # *all* possible directives.
274 child_attrs = ["body"]
276 def analyse_control_flow(self, env):
278 env.directives = self.directives
279 self.body.analyse_control_flow(env)
282 def analyse_declarations(self, env):
284 env.directives = self.directives
285 self.body.analyse_declarations(env)
288 def analyse_expressions(self, env):
290 env.directives = self.directives
291 self.body.analyse_expressions(env)
294 def generate_function_definitions(self, env, code):
295 env_old = env.directives
296 code_old = code.globalstate.directives
297 code.globalstate.directives = self.directives
298 self.body.generate_function_definitions(env, code)
299 env.directives = env_old
300 code.globalstate.directives = code_old
302 def generate_execution_code(self, code):
303 old = code.globalstate.directives
304 code.globalstate.directives = self.directives
305 self.body.generate_execution_code(code)
306 code.globalstate.directives = old
308 def annotate(self, code):
309 old = code.globalstate.directives
310 code.globalstate.directives = self.directives
311 self.body.annotate(code)
312 code.globalstate.directives = old
314 class BlockNode(object):
315 # Mixin class for nodes representing a declaration block.
317 def generate_cached_builtins_decls(self, env, code):
318 entries = env.global_scope().undeclared_cached_builtins
319 for entry in entries:
320 code.globalstate.add_cached_builtin_decl(entry)
324 class StatListNode(Node):
325 # stats a list of StatNode
327 child_attrs = ["stats"]
329 def create_analysed(pos, env, *args, **kw):
330 node = StatListNode(pos, *args, **kw)
331 return node # No node-specific analysis necesarry
332 create_analysed = staticmethod(create_analysed)
334 def analyse_control_flow(self, env):
335 for stat in self.stats:
336 stat.analyse_control_flow(env)
338 def analyse_declarations(self, env):
339 #print "StatListNode.analyse_declarations" ###
340 for stat in self.stats:
341 stat.analyse_declarations(env)
343 def analyse_expressions(self, env):
344 #print "StatListNode.analyse_expressions" ###
345 for stat in self.stats:
346 stat.analyse_expressions(env)
348 def generate_function_definitions(self, env, code):
349 #print "StatListNode.generate_function_definitions" ###
350 for stat in self.stats:
351 stat.generate_function_definitions(env, code)
353 def generate_execution_code(self, code):
354 #print "StatListNode.generate_execution_code" ###
355 for stat in self.stats:
356 code.mark_pos(stat.pos)
357 stat.generate_execution_code(code)
359 def annotate(self, code):
360 for stat in self.stats:
364 class StatNode(Node):
366 # Code generation for statements is split into the following subphases:
368 # (1) generate_function_definitions
369 # Emit C code for the definitions of any structs,
370 # unions, enums and functions defined in the current
373 # (2) generate_execution_code
374 # Emit C code for executable statements.
377 def generate_function_definitions(self, env, code):
380 def generate_execution_code(self, code):
381 raise InternalError("generate_execution_code not implemented for %s" % \
382 self.__class__.__name__)
385 class CDefExternNode(StatNode):
386 # include_file string or None
389 child_attrs = ["body"]
391 def analyse_declarations(self, env):
392 if self.include_file:
393 env.add_include_file(self.include_file)
394 old_cinclude_flag = env.in_cinclude
396 self.body.analyse_declarations(env)
397 env.in_cinclude = old_cinclude_flag
399 def analyse_expressions(self, env):
402 def generate_execution_code(self, code):
405 def annotate(self, code):
406 self.body.annotate(code)
409 class CDeclaratorNode(Node):
410 # Part of a C declaration.
412 # Processing during analyse_declarations phase:
415 # Returns (name, type) pair where name is the
416 # CNameDeclaratorNode of the name being declared
417 # and type is the type it is being declared as.
419 # calling_convention string Calling convention of CFuncDeclaratorNode
420 # for which this is a base
424 calling_convention = ""
427 class CNameDeclaratorNode(CDeclaratorNode):
428 # name string The Pyrex name being declared
429 # cname string or None C name, if specified
430 # default ExprNode or None the value assigned on declaration
432 child_attrs = ['default']
436 def analyse(self, base_type, env, nonempty = 0):
437 if nonempty and self.name == '':
438 # May have mistaken the name for the type.
439 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
440 error(self.pos, "Missing argument name")
441 elif base_type.is_void:
442 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
444 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
445 base_type = py_object_type
446 self.type = base_type
447 return self, base_type
449 class CPtrDeclaratorNode(CDeclaratorNode):
450 # base CDeclaratorNode
452 child_attrs = ["base"]
454 def analyse(self, base_type, env, nonempty = 0):
455 if base_type.is_pyobject:
457 "Pointer base type cannot be a Python object")
458 ptr_type = PyrexTypes.c_ptr_type(base_type)
459 return self.base.analyse(ptr_type, env, nonempty = nonempty)
461 class CReferenceDeclaratorNode(CDeclaratorNode):
462 # base CDeclaratorNode
464 child_attrs = ["base"]
466 def analyse(self, base_type, env, nonempty = 0):
467 if base_type.is_pyobject:
469 "Reference base type cannot be a Python object")
470 ref_type = PyrexTypes.c_ref_type(base_type)
471 return self.base.analyse(ref_type, env, nonempty = nonempty)
473 class CArrayDeclaratorNode(CDeclaratorNode):
474 # base CDeclaratorNode
477 child_attrs = ["base", "dimension"]
479 def analyse(self, base_type, env, nonempty = 0):
480 if base_type.is_cpp_class:
481 from ExprNodes import TupleNode
482 if isinstance(self.dimension, TupleNode):
483 args = self.dimension.args
485 args = self.dimension,
486 values = [v.analyse_as_type(env) for v in args]
488 ix = values.index(None)
489 error(args[ix].pos, "Template parameter not a type.")
491 base_type = base_type.specialize_here(self.pos, values)
492 return self.base.analyse(base_type, env, nonempty = nonempty)
494 self.dimension.analyse_const_expression(env)
495 if not self.dimension.type.is_int:
496 error(self.dimension.pos, "Array dimension not integer")
497 size = self.dimension.get_constant_c_result_code()
506 if not base_type.is_complete():
508 "Array element type '%s' is incomplete" % base_type)
509 if base_type.is_pyobject:
511 "Array element cannot be a Python object")
512 if base_type.is_cfunction:
514 "Array element cannot be a function")
515 array_type = PyrexTypes.c_array_type(base_type, size)
516 return self.base.analyse(array_type, env, nonempty = nonempty)
519 class CFuncDeclaratorNode(CDeclaratorNode):
520 # base CDeclaratorNode
521 # args [CArgDeclNode]
522 # has_varargs boolean
523 # exception_value ConstNode
524 # exception_check boolean True if PyErr_Occurred check needed
525 # nogil boolean Can be called without gil
526 # with_gil boolean Acquire gil around function body
528 child_attrs = ["base", "args", "exception_value"]
531 optional_arg_count = 0
533 def analyse(self, return_type, env, nonempty = 0):
537 for arg_node in self.args:
538 name_declarator, type = arg_node.analyse(env, nonempty = nonempty)
539 name = name_declarator.name
540 if name_declarator.cname:
542 "Function argument cannot have C name specification")
543 # Turn *[] argument into **
545 type = PyrexTypes.c_ptr_type(type.base_type)
546 # Catch attempted C-style func(void) decl
548 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
549 func_type_args.append(
550 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
552 self.optional_arg_count += 1
553 elif self.optional_arg_count:
554 error(self.pos, "Non-default argument follows default argument")
556 if self.optional_arg_count:
557 scope = StructOrUnionScope()
558 arg_count_member = '%sn' % Naming.pyrex_prefix
559 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
560 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
561 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
562 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
563 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
568 cname = struct_cname)
569 self.op_args_struct.defined_in_pxd = 1
570 self.op_args_struct.used = 1
574 if self.exception_check == '+':
575 env.add_include_file('stdexcept')
576 if return_type.is_pyobject \
577 and (self.exception_value or self.exception_check) \
578 and self.exception_check != '+':
580 "Exception clause not allowed for function returning Python object")
582 if self.exception_value:
583 self.exception_value.analyse_const_expression(env)
584 if self.exception_check == '+':
585 self.exception_value.analyse_types(env)
586 exc_val_type = self.exception_value.type
587 if not exc_val_type.is_error and \
588 not exc_val_type.is_pyobject and \
589 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
590 error(self.exception_value.pos,
591 "Exception value must be a Python exception or cdef function with no arguments.")
592 exc_val = self.exception_value
594 if self.exception_value.analyse_const_expression(env):
595 exc_val = self.exception_value.get_constant_c_result_code()
597 raise InternalError("get_constant_c_result_code not implemented for %s" %
598 self.exception_value.__class__.__name__)
599 if not return_type.assignable_from(self.exception_value.type):
600 error(self.exception_value.pos,
601 "Exception value incompatible with function return type")
602 exc_check = self.exception_check
603 if return_type.is_array:
605 "Function cannot return an array")
606 if return_type.is_cfunction:
608 "Function cannot return a function")
609 func_type = PyrexTypes.CFuncType(
610 return_type, func_type_args, self.has_varargs,
611 optional_arg_count = self.optional_arg_count,
612 exception_value = exc_val, exception_check = exc_check,
613 calling_convention = self.base.calling_convention,
614 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
615 if self.optional_arg_count:
616 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
617 callspec = env.directives['callspec']
619 current = func_type.calling_convention
620 if current and current != callspec:
621 error(self.pos, "cannot have both '%s' and '%s' "
622 "calling conventions" % (current, callspec))
623 func_type.calling_convention = callspec
624 return self.base.analyse(func_type, env)
627 class CArgDeclNode(Node):
628 # Item in a function declaration argument list.
630 # base_type CBaseTypeNode
631 # declarator CDeclaratorNode
632 # not_none boolean Tagged with 'not None'
633 # or_none boolean Tagged with 'or None'
634 # accept_none boolean Resolved boolean for not_none/or_none
635 # default ExprNode or None
636 # default_value PyObjectConst constant for default value
637 # annotation ExprNode or None Py3 function arg annotation
638 # is_self_arg boolean Is the "self" arg of an extension type method
639 # is_type_arg boolean Is the "class" arg of an extension type classmethod
640 # is_kw_only boolean Is a keyword-only argument
642 child_attrs = ["base_type", "declarator", "default"]
648 name_declarator = None
652 def analyse(self, env, nonempty = 0):
653 #print "CArgDeclNode.analyse: is_self_arg =", self.is_self_arg ###
654 if self.type is None:
655 # The parser may missinterpret names as types...
657 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
659 self.declarator.name = self.base_type.name
660 self.base_type.name = None
661 self.base_type.is_basic_c_type = False
664 could_be_name = False
665 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
666 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
667 self.declarator.name = self.base_type.arg_name
668 # The parser is unable to resolve the ambiguity of [] as part of the
669 # type (e.g. in buffers) or empty declarator (as with arrays).
670 # This is only arises for empty multi-dimensional arrays.
671 if (base_type.is_array
672 and isinstance(self.base_type, TemplatedTypeNode)
673 and isinstance(self.declarator, CArrayDeclaratorNode)):
674 declarator = self.declarator
675 while isinstance(declarator.base, CArrayDeclaratorNode):
676 declarator = declarator.base
677 declarator.base = self.base_type.array_declarator
678 base_type = base_type.base_type
679 return self.declarator.analyse(base_type, env, nonempty = nonempty)
681 return self.name_declarator, self.type
683 def calculate_default_value_code(self, code):
684 if self.default_value is None:
686 if self.default.is_literal:
687 # will not output any code, just assign the result_code
688 self.default.generate_evaluation_code(code)
689 return self.type.cast_code(self.default.result())
690 self.default_value = code.get_argument_default_const(self.type)
691 return self.default_value
693 def annotate(self, code):
695 self.default.annotate(code)
698 class CBaseTypeNode(Node):
699 # Abstract base class for C base type nodes.
701 # Processing during analyse_declarations phase:
708 def analyse_as_type(self, env):
709 return self.analyse(env)
711 class CAnalysedBaseTypeNode(Node):
716 def analyse(self, env, could_be_name = False):
719 class CSimpleBaseTypeNode(CBaseTypeNode):
721 # module_path [string] Qualifying name components
722 # is_basic_c_type boolean
726 # is_self_arg boolean Is self argument of C method
727 # ##is_type_arg boolean Is type argument of class method
730 arg_name = None # in case the argument name was interpreted as a type
732 def analyse(self, env, could_be_name = False):
733 # Return type descriptor.
734 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
736 if self.is_basic_c_type:
737 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
739 error(self.pos, "Unrecognised type modifier combination")
740 elif self.name == "object" and not self.module_path:
741 type = py_object_type
742 elif self.name is None:
743 if self.is_self_arg and env.is_c_class_scope:
744 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
745 type = env.parent_type
746 ## elif self.is_type_arg and env.is_c_class_scope:
747 ## type = Builtin.type_type
749 type = py_object_type
752 scope = env.find_imported_module(self.module_path, self.pos)
756 if scope.is_c_class_scope:
757 scope = scope.global_scope()
758 entry = scope.lookup(self.name)
759 if entry and entry.is_type:
762 if self.is_self_arg and env.is_c_class_scope:
763 type = env.parent_type
764 ## elif self.is_type_arg and env.is_c_class_scope:
765 ## type = Builtin.type_type
767 type = py_object_type
768 self.arg_name = self.name
771 if not self.name in self.templates:
772 error(self.pos, "'%s' is not a type identifier" % self.name)
773 type = PyrexTypes.TemplatePlaceholderType(self.name)
775 error(self.pos, "'%s' is not a type identifier" % self.name)
777 if not type.is_numeric or type.is_complex:
778 error(self.pos, "can only complexify c numeric types")
779 type = PyrexTypes.CComplexType(type)
780 type.create_declaration_utility_code(env)
784 return PyrexTypes.error_type
786 class CNestedBaseTypeNode(CBaseTypeNode):
787 # For C++ classes that live inside other C++ classes.
790 # base_type CBaseTypeNode
792 child_attrs = ['base_type']
794 def analyse(self, env, could_be_name = None):
795 base_type = self.base_type.analyse(env)
796 if base_type is PyrexTypes.error_type:
797 return PyrexTypes.error_type
798 if not base_type.is_cpp_class:
799 error(self.pos, "'%s' is not a valid type scope" % base_type)
800 return PyrexTypes.error_type
801 type_entry = base_type.scope.lookup_here(self.name)
802 if not type_entry or not type_entry.is_type:
803 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
804 return PyrexTypes.error_type
805 return type_entry.type
807 class TemplatedTypeNode(CBaseTypeNode):
809 # positional_args [ExprNode] List of positional arguments
810 # keyword_args DictNode Keyword arguments
811 # base_type_node CBaseTypeNode
814 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
817 child_attrs = ["base_type_node", "positional_args",
818 "keyword_args", "dtype_node"]
824 def analyse(self, env, could_be_name = False, base_type = None):
825 if base_type is None:
826 base_type = self.base_type_node.analyse(env)
827 if base_type.is_error: return base_type
829 if base_type.is_cpp_class:
831 if self.keyword_args and self.keyword_args.key_value_pairs:
832 error(self.pos, "c++ templates cannot take keyword arguments");
833 self.type = PyrexTypes.error_type
836 for template_node in self.positional_args:
837 type = template_node.analyse_as_type(env)
839 error(template_node.pos, "unknown type in template argument")
841 template_types.append(type)
842 self.type = base_type.specialize_here(self.pos, template_types)
844 elif base_type.is_pyobject:
848 options = Buffer.analyse_buffer_options(
851 self.positional_args,
853 base_type.buffer_defaults)
855 if sys.version_info[0] < 3:
856 # Py 2.x enforces byte strings as keyword arguments ...
857 options = dict([ (name.encode('ASCII'), value)
858 for name, value in options.iteritems() ])
860 self.type = PyrexTypes.BufferType(base_type, **options)
864 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
865 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
866 error(self.pos, "invalid array declaration")
867 self.type = PyrexTypes.error_type
869 # It would be nice to merge this class with CArrayDeclaratorNode,
870 # but arrays are part of the declaration, not the type...
871 if not self.positional_args:
874 dimension = self.positional_args[0]
875 self.array_declarator = CArrayDeclaratorNode(self.pos,
876 base = empty_declarator,
877 dimension = dimension)
878 self.type = self.array_declarator.analyse(base_type, env)[1]
882 class CComplexBaseTypeNode(CBaseTypeNode):
883 # base_type CBaseTypeNode
884 # declarator CDeclaratorNode
886 child_attrs = ["base_type", "declarator"]
888 def analyse(self, env, could_be_name = False):
889 base = self.base_type.analyse(env, could_be_name)
890 _, type = self.declarator.analyse(base, env)
894 class CVarDefNode(StatNode):
895 # C variable definition or forward/extern function declaration.
897 # visibility 'private' or 'public' or 'extern'
898 # base_type CBaseTypeNode
899 # declarators [CDeclaratorNode]
904 # decorators [cython.locals(...)] or None
905 # directive_locals { string : NameNode } locals defined by cython.locals(...)
907 child_attrs = ["base_type", "declarators"]
911 directive_locals = {}
913 def analyse_declarations(self, env, dest_scope = None):
916 self.dest_scope = dest_scope
917 base_type = self.base_type.analyse(env)
919 # If the field is an external typedef, we cannot be sure about the type,
920 # so do conversion ourself rather than rely on the CPython mechanism (through
921 # a property; made in AnalyseDeclarationsTransform).
922 if (dest_scope.is_c_class_scope
923 and self.visibility in ('public', 'readonly')):
927 need_property = False
928 visibility = self.visibility
930 for declarator in self.declarators:
931 name_declarator, type = declarator.analyse(base_type, env)
932 if not type.is_complete():
933 if not (self.visibility == 'extern' and type.is_array):
934 error(declarator.pos,
935 "Variable type '%s' is incomplete" % type)
936 if self.visibility == 'extern' and type.is_pyobject:
937 error(declarator.pos,
938 "Python object cannot be declared extern")
939 name = name_declarator.name
940 cname = name_declarator.cname
942 error(declarator.pos, "Missing name in declaration.")
944 if type.is_cfunction:
945 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
946 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
948 if entry is not None:
949 entry.directive_locals = self.directive_locals
951 if self.directive_locals:
952 s.error("Decorators can only be followed by functions")
953 if self.in_pxd and self.visibility != 'extern':
955 "Only 'extern' C variable declaration allowed in .pxd file")
956 entry = dest_scope.declare_var(name, type, declarator.pos,
957 cname = cname, visibility = visibility, is_cdef = 1)
959 self.properties.append(entry)
962 class CStructOrUnionDefNode(StatNode):
964 # cname string or None
965 # kind "struct" or "union"
966 # typedef_flag boolean
967 # visibility "public" or "private"
969 # attributes [CVarDefNode] or None
973 child_attrs = ["attributes"]
975 def analyse_declarations(self, env):
977 if self.visibility == 'extern' and self.packed:
978 error(self.pos, "Cannot declare extern struct as 'packed'")
979 if self.attributes is not None:
980 scope = StructOrUnionScope(self.name)
981 self.entry = env.declare_struct_or_union(
982 self.name, self.kind, scope, self.typedef_flag, self.pos,
983 self.cname, visibility = self.visibility, packed = self.packed)
984 if self.attributes is not None:
985 if self.in_pxd and not env.in_cinclude:
986 self.entry.defined_in_pxd = 1
987 for attr in self.attributes:
988 attr.analyse_declarations(env, scope)
989 if self.visibility != 'extern':
990 need_typedef_indirection = False
991 for attr in scope.var_entries:
994 type = type.base_type
995 if type == self.entry.type:
996 error(attr.pos, "Struct cannot contain itself as a member.")
997 if self.typedef_flag:
999 type = type.base_type
1000 if type == self.entry.type:
1001 need_typedef_indirection = True
1002 if need_typedef_indirection:
1003 # C can't handle typedef structs that refer to themselves.
1004 struct_entry = self.entry
1005 self.entry = env.declare_typedef(
1006 self.name, struct_entry.type, self.pos,
1007 cname = self.cname, visibility='ignore')
1008 struct_entry.type.typedef_flag = False
1009 # FIXME: this might be considered a hack ;-)
1010 struct_entry.cname = struct_entry.type.cname = \
1011 '_' + self.entry.type.typedef_cname
1013 def analyse_expressions(self, env):
1016 def generate_execution_code(self, code):
1020 class CppClassNode(CStructOrUnionDefNode):
1023 # cname string or None
1024 # visibility "extern"
1026 # attributes [CVarDefNode] or None
1028 # base_classes [string]
1029 # templates [string] or None
1031 def analyse_declarations(self, env):
1033 if self.attributes is not None:
1034 scope = CppClassScope(self.name, env)
1035 base_class_types = []
1036 for base_class_name in self.base_classes:
1037 base_class_entry = env.lookup(base_class_name)
1038 if base_class_entry is None:
1039 error(self.pos, "'%s' not found" % base_class_name)
1040 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1041 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1043 base_class_types.append(base_class_entry.type)
1044 if self.templates is None:
1045 template_types = None
1047 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1048 self.entry = env.declare_cpp_class(
1049 self.name, scope, self.pos,
1050 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1051 self.entry.is_cpp_class = 1
1052 if self.attributes is not None:
1053 if self.in_pxd and not env.in_cinclude:
1054 self.entry.defined_in_pxd = 1
1055 for attr in self.attributes:
1056 attr.analyse_declarations(scope)
1058 class CEnumDefNode(StatNode):
1059 # name string or None
1060 # cname string or None
1061 # items [CEnumDefItemNode]
1062 # typedef_flag boolean
1063 # visibility "public" or "private"
1067 child_attrs = ["items"]
1069 def analyse_declarations(self, env):
1070 self.entry = env.declare_enum(self.name, self.pos,
1071 cname = self.cname, typedef_flag = self.typedef_flag,
1072 visibility = self.visibility)
1073 if self.items is not None:
1074 if self.in_pxd and not env.in_cinclude:
1075 self.entry.defined_in_pxd = 1
1076 for item in self.items:
1077 item.analyse_declarations(env, self.entry)
1079 def analyse_expressions(self, env):
1082 def generate_execution_code(self, code):
1083 if self.visibility == 'public':
1084 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1085 for item in self.entry.enum_values:
1086 code.putln("%s = PyInt_FromLong(%s); %s" % (
1089 code.error_goto_if_null(temp, item.pos)))
1090 code.put_gotref(temp)
1091 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1092 Naming.module_cname,
1095 code.error_goto(item.pos)))
1096 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1097 code.funcstate.release_temp(temp)
1100 class CEnumDefItemNode(StatNode):
1102 # cname string or None
1103 # value ExprNode or None
1105 child_attrs = ["value"]
1107 def analyse_declarations(self, env, enum_entry):
1109 self.value.analyse_const_expression(env)
1110 if not self.value.type.is_int:
1111 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1112 self.value.analyse_const_expression(env)
1113 entry = env.declare_const(self.name, enum_entry.type,
1114 self.value, self.pos, cname = self.cname,
1115 visibility = enum_entry.visibility)
1116 enum_entry.enum_values.append(entry)
1119 class CTypeDefNode(StatNode):
1120 # base_type CBaseTypeNode
1121 # declarator CDeclaratorNode
1122 # visibility "public" or "private"
1125 child_attrs = ["base_type", "declarator"]
1127 def analyse_declarations(self, env):
1128 base = self.base_type.analyse(env)
1129 name_declarator, type = self.declarator.analyse(base, env)
1130 name = name_declarator.name
1131 cname = name_declarator.cname
1132 entry = env.declare_typedef(name, type, self.pos,
1133 cname = cname, visibility = self.visibility)
1134 if self.in_pxd and not env.in_cinclude:
1135 entry.defined_in_pxd = 1
1137 def analyse_expressions(self, env):
1139 def generate_execution_code(self, code):
1143 class FuncDefNode(StatNode, BlockNode):
1144 # Base class for function definition nodes.
1146 # return_type PyrexType
1147 # #filename string C name of filename string const
1148 # entry Symtab.Entry
1149 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1150 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1154 needs_closure = False
1157 def analyse_default_values(self, env):
1158 genv = env.global_scope()
1160 for arg in self.args:
1164 arg.default.analyse_types(env)
1165 arg.default = arg.default.coerce_to(arg.type, genv)
1168 "This argument cannot have a default value")
1173 error(arg.pos, "Non-default argument following default argument")
1175 def need_gil_acquisition(self, lenv):
1178 def create_local_scope(self, env):
1180 while genv.is_py_class_scope or genv.is_c_class_scope:
1181 genv = env.outer_scope
1182 if self.needs_closure:
1183 lenv = ClosureScope(name=self.entry.name,
1185 scope_name=self.entry.cname)
1187 lenv = LocalScope(name=self.entry.name,
1190 lenv.return_type = self.return_type
1191 type = self.entry.type
1192 if type.is_cfunction:
1193 lenv.nogil = type.nogil and not type.with_gil
1194 self.local_scope = lenv
1195 lenv.directives = env.directives
1198 def generate_function_definitions(self, env, code):
1201 lenv = self.local_scope
1202 if lenv.is_closure_scope:
1203 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1204 Naming.outer_scope_cname)
1206 outer_scope_cname = Naming.outer_scope_cname
1207 lenv.mangle_closure_cnames(outer_scope_cname)
1208 # Generate closure function definitions
1209 self.body.generate_function_definitions(lenv, code)
1210 # generate lambda function definitions
1211 for node in lenv.lambda_defs:
1212 node.generate_function_definitions(lenv, code)
1214 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1215 self.entry.scope.is_c_class_scope)
1216 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1217 self.entry.scope.is_c_class_scope)
1218 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1220 if 'cython_unused' not in self.modifiers:
1221 self.modifiers = self.modifiers + ['cython_unused']
1223 preprocessor_guard = None
1224 if self.entry.is_special and not is_buffer_slot:
1225 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1227 preprocessor_guard = slot.preprocessor_guard_code()
1228 if (self.entry.name == '__long__' and
1229 not self.entry.scope.lookup_here('__int__')):
1230 preprocessor_guard = None
1232 profile = code.globalstate.directives['profile']
1235 error(self.pos, "Cannot profile nogil function.")
1236 code.globalstate.use_utility_code(profile_utility_code)
1238 # Generate C code for header and body of function
1239 code.enter_cfunc_scope()
1240 code.return_from_error_cleanup_label = code.new_label()
1242 # ----- Top-level constants used by this function
1243 code.mark_pos(self.pos)
1244 self.generate_cached_builtins_decls(lenv, code)
1245 # ----- Function header
1248 if preprocessor_guard:
1249 code.putln(preprocessor_guard)
1251 with_pymethdef = self.needs_assignment_synthesis(env, code)
1253 self.py_func.generate_function_header(code,
1254 with_pymethdef = with_pymethdef,
1256 self.generate_function_header(code,
1257 with_pymethdef = with_pymethdef)
1258 # ----- Local variable declarations
1259 if lenv.is_closure_scope:
1260 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1262 elif env.is_closure_scope:
1263 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1265 self.generate_argument_declarations(lenv, code)
1266 for entry in lenv.var_entries:
1267 if not entry.in_closure:
1268 code.put_var_declaration(entry)
1270 if not self.return_type.is_void:
1271 if self.return_type.is_pyobject:
1275 (self.return_type.declaration_code(Naming.retval_cname),
1277 tempvardecl_code = code.insertion_point()
1278 self.generate_keyword_list(code)
1280 code.put_trace_declarations()
1281 # ----- Extern library function declarations
1282 lenv.generate_library_function_declarations(code)
1283 # ----- GIL acquisition
1284 acquire_gil = self.acquire_gil
1286 env.use_utility_code(force_init_threads_utility_code)
1287 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1288 # ----- set up refnanny
1290 code.put_setup_refcount_context(self.entry.name)
1291 # ----- Automatic lead-ins for certain special functions
1292 if is_getbuffer_slot:
1293 self.getbuffer_init(code)
1294 # ----- Create closure scope object
1295 if self.needs_closure:
1296 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1297 Naming.cur_scope_cname,
1298 lenv.scope_class.type.declaration_code(''),
1299 lenv.scope_class.type.typeptr_cname,
1300 lenv.scope_class.type.typeptr_cname,
1301 Naming.empty_tuple))
1302 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1303 if is_getbuffer_slot:
1304 self.getbuffer_error_cleanup(code)
1306 code.put_finish_refcount_context()
1307 # FIXME: what if the error return value is a Python value?
1308 code.putln("return %s;" % self.error_value())
1310 code.put_gotref(Naming.cur_scope_cname)
1311 # Note that it is unsafe to decref the scope at this point.
1312 if env.is_closure_scope:
1313 code.putln("%s = (%s)%s;" % (
1315 env.scope_class.type.declaration_code(''),
1317 if self.needs_closure:
1318 # inner closures own a reference to their outer parent
1319 code.put_incref(outer_scope_cname, env.scope_class.type)
1320 code.put_giveref(outer_scope_cname)
1321 # ----- Trace function call
1323 # this looks a bit late, but if we don't get here due to a
1324 # fatal error before hand, it's not really worth tracing
1325 code.put_trace_call(self.entry.name, self.pos)
1326 # ----- Fetch arguments
1327 self.generate_argument_parsing_code(env, code)
1328 # If an argument is assigned to in the body, we must
1329 # incref it to properly keep track of refcounts.
1330 for entry in lenv.arg_entries:
1331 if entry.type.is_pyobject:
1332 if entry.assignments and not entry.in_closure:
1333 code.put_var_incref(entry)
1334 # ----- Initialise local variables
1335 for entry in lenv.var_entries:
1336 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1337 code.put_init_var_to_py_none(entry)
1338 # ----- Initialise local buffer auxiliary variables
1339 for entry in lenv.var_entries + lenv.arg_entries:
1340 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1341 code.putln("%s.buf = NULL;" %
1342 entry.buffer_aux.buffer_info_var.cname)
1343 # ----- Check and convert arguments
1344 self.generate_argument_type_tests(code)
1345 # ----- Acquire buffer arguments
1346 for entry in lenv.arg_entries:
1347 if entry.type.is_buffer:
1348 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1350 # -------------------------
1351 # ----- Function body -----
1352 # -------------------------
1353 self.body.generate_execution_code(code)
1355 # ----- Default return value
1357 if self.return_type.is_pyobject:
1358 #if self.return_type.is_extension_type:
1359 # lhs = "(PyObject *)%s" % Naming.retval_cname
1361 lhs = Naming.retval_cname
1362 code.put_init_to_py_none(lhs, self.return_type)
1364 val = self.return_type.default_value
1366 code.putln("%s = %s;" % (Naming.retval_cname, val))
1367 # ----- Error cleanup
1368 if code.error_label in code.labels_used:
1369 code.put_goto(code.return_label)
1370 code.put_label(code.error_label)
1371 for cname, type in code.funcstate.all_managed_temps():
1372 code.put_xdecref(cname, type)
1374 # Clean up buffers -- this calls a Python function
1375 # so need to save and restore error state
1376 buffers_present = len(lenv.buffer_entries) > 0
1378 code.globalstate.use_utility_code(restore_exception_utility_code)
1379 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1380 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1381 for entry in lenv.buffer_entries:
1382 Buffer.put_release_buffer_code(code, entry)
1383 #code.putln("%s = 0;" % entry.cname)
1384 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1386 err_val = self.error_value()
1387 exc_check = self.caller_will_check_exceptions()
1388 if err_val is not None or exc_check:
1389 # TODO: Fix exception tracing (though currently unused by cProfile).
1390 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1391 # code.put_trace_exception()
1392 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1394 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1395 % self.entry.qualified_name, 0)
1397 '__Pyx_WriteUnraisable("%s");' %
1398 self.entry.qualified_name)
1399 env.use_utility_code(unraisable_exception_utility_code)
1400 env.use_utility_code(restore_exception_utility_code)
1401 default_retval = self.return_type.default_value
1402 if err_val is None and default_retval:
1403 err_val = default_retval
1404 if err_val is not None:
1405 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1407 if is_getbuffer_slot:
1408 self.getbuffer_error_cleanup(code)
1410 # If we are using the non-error cleanup section we should
1411 # jump past it if we have an error. The if-test below determine
1412 # whether this section is used.
1413 if buffers_present or is_getbuffer_slot:
1414 code.put_goto(code.return_from_error_cleanup_label)
1417 # ----- Non-error return cleanup
1418 code.put_label(code.return_label)
1419 for entry in lenv.buffer_entries:
1421 Buffer.put_release_buffer_code(code, entry)
1422 if is_getbuffer_slot:
1423 self.getbuffer_normal_cleanup(code)
1424 # ----- Return cleanup for both error and no-error return
1425 code.put_label(code.return_from_error_cleanup_label)
1426 if not Options.init_local_none:
1427 for entry in lenv.var_entries:
1428 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1429 entry.xdecref_cleanup = 1
1431 for entry in lenv.var_entries:
1432 if entry.type.is_pyobject:
1433 if entry.used and not entry.in_closure:
1434 code.put_var_decref(entry)
1435 elif entry.in_closure and self.needs_closure:
1436 code.put_giveref(entry.cname)
1437 # Decref any increfed args
1438 for entry in lenv.arg_entries:
1439 if entry.type.is_pyobject:
1440 if entry.in_closure:
1441 code.put_var_giveref(entry)
1442 elif entry.assignments:
1443 code.put_var_decref(entry)
1444 if self.needs_closure:
1445 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1448 # This code is duplicated in ModuleNode.generate_module_init_func
1450 default_retval = self.return_type.default_value
1451 err_val = self.error_value()
1452 if err_val is None and default_retval:
1453 err_val = default_retval
1454 if self.return_type.is_pyobject:
1455 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1457 if self.entry.is_special and self.entry.name == "__hash__":
1458 # Returning -1 for __hash__ is supposed to signal an error
1459 # We do as Python instances and coerce -1 into -2.
1460 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1461 Naming.retval_cname, Naming.retval_cname))
1464 if self.return_type.is_pyobject:
1465 code.put_trace_return(Naming.retval_cname)
1467 code.put_trace_return("Py_None")
1469 code.put_finish_refcount_context()
1472 code.putln("PyGILState_Release(_save);")
1474 if not self.return_type.is_void:
1475 code.putln("return %s;" % Naming.retval_cname)
1479 if preprocessor_guard:
1480 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1482 # ----- Go back and insert temp variable declarations
1483 tempvardecl_code.put_temp_declarations(code.funcstate)
1484 # ----- Python version
1485 code.exit_cfunc_scope()
1487 self.py_func.generate_function_definitions(env, code)
1488 self.generate_wrapper_functions(code)
1490 def declare_argument(self, env, arg):
1491 if arg.type.is_void:
1492 error(arg.pos, "Invalid use of 'void'")
1493 elif not arg.type.is_complete() and not arg.type.is_array:
1495 "Argument type '%s' is incomplete" % arg.type)
1496 return env.declare_arg(arg.name, arg.type, arg.pos)
1498 def generate_arg_type_test(self, arg, code):
1499 # Generate type test for one argument.
1500 if arg.type.typeobj_is_available():
1501 code.globalstate.use_utility_code(arg_type_test_utility_code)
1502 typeptr_cname = arg.type.typeptr_cname
1503 arg_code = "((PyObject *)%s)" % arg.entry.cname
1505 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1510 arg.type.is_builtin_type,
1511 code.error_goto(arg.pos)))
1513 error(arg.pos, "Cannot test type of extern C class "
1514 "without type object name specification")
1516 def generate_arg_none_check(self, arg, code):
1517 # Generate None check for one argument.
1518 code.globalstate.use_utility_code(arg_type_test_utility_code)
1519 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1520 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1522 code.error_goto(arg.pos)))
1525 def generate_wrapper_functions(self, code):
1528 def generate_execution_code(self, code):
1529 # Evaluate and store argument default values
1530 for arg in self.args:
1531 default = arg.default
1533 if not default.is_literal:
1534 default.generate_evaluation_code(code)
1535 default.make_owned_reference(code)
1536 result = default.result_as(arg.type)
1539 arg.calculate_default_value_code(code),
1541 if arg.type.is_pyobject:
1542 code.put_giveref(default.result())
1543 default.generate_post_assignment_code(code)
1544 default.free_temps(code)
1545 # For Python class methods, create and store function object
1547 self.assmt.generate_execution_code(code)
1550 # Special code for the __getbuffer__ function
1552 def getbuffer_init(self, code):
1553 info = self.local_scope.arg_entries[1].cname
1554 # Python 3.0 betas have a bug in memoryview which makes it call
1555 # getbuffer with a NULL parameter. For now we work around this;
1556 # the following line should be removed when this bug is fixed.
1557 code.putln("if (%s == NULL) return 0;" % info)
1558 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1559 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1561 def getbuffer_error_cleanup(self, code):
1562 info = self.local_scope.arg_entries[1].cname
1563 code.put_gotref("%s->obj" % info)
1564 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1567 def getbuffer_normal_cleanup(self, code):
1568 info = self.local_scope.arg_entries[1].cname
1569 code.putln("if (%s->obj == Py_None) {" % info)
1570 code.put_gotref("Py_None")
1571 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1574 class CFuncDefNode(FuncDefNode):
1575 # C function definition.
1577 # modifiers ['inline']
1578 # visibility 'private' or 'public' or 'extern'
1579 # base_type CBaseTypeNode
1580 # declarator CDeclaratorNode
1583 # decorators [DecoratorNode] list of decorators
1585 # with_gil boolean Acquire GIL around body
1587 # py_func wrapper for calling from Python
1588 # overridable whether or not this is a cpdef function
1589 # inline_in_pxd whether this is an inline function in a pxd file
1591 child_attrs = ["base_type", "declarator", "body", "py_func"]
1593 inline_in_pxd = False
1595 directive_locals = {}
1597 def unqualified_name(self):
1598 return self.entry.name
1600 def analyse_declarations(self, env):
1601 self.directive_locals.update(env.directives['locals'])
1602 base_type = self.base_type.analyse(env)
1603 # The 2 here is because we need both function and argument names.
1604 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1605 if not type.is_cfunction:
1607 "Suite attached to non-function declaration")
1608 # Remember the actual type according to the function header
1609 # written here, because the type in the symbol table entry
1610 # may be different if we're overriding a C method inherited
1611 # from the base type of an extension type.
1613 type.is_overridable = self.overridable
1614 declarator = self.declarator
1615 while not hasattr(declarator, 'args'):
1616 declarator = declarator.base
1617 self.args = declarator.args
1618 for formal_arg, type_arg in zip(self.args, type.args):
1619 formal_arg.type = type_arg.type
1620 formal_arg.name = type_arg.name
1621 formal_arg.cname = type_arg.cname
1622 name = name_declarator.name
1623 cname = name_declarator.cname
1624 self.entry = env.declare_cfunction(
1625 name, type, self.pos,
1626 cname = cname, visibility = self.visibility,
1627 defining = self.body is not None,
1628 api = self.api, modifiers = self.modifiers)
1629 self.entry.inline_func_in_pxd = self.inline_in_pxd
1630 self.return_type = type.return_type
1632 if self.overridable and not env.is_module_scope:
1633 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1634 # An error will be produced in the cdef function
1635 self.overridable = False
1637 if self.overridable:
1639 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1640 self.py_func = DefNode(pos = self.pos,
1641 name = self.entry.name,
1644 starstar_arg = None,
1646 body = py_func_body,
1648 self.py_func.is_module_scope = env.is_module_scope
1649 self.py_func.analyse_declarations(env)
1650 self.entry.as_variable = self.py_func.entry
1651 # Reset scope entry the above cfunction
1652 env.entries[name] = self.entry
1653 if not env.is_module_scope or Options.lookup_module_cpdef:
1654 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1655 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1656 self.create_local_scope(env)
1658 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1660 args = self.type.args
1661 if omit_optional_args:
1662 args = args[:len(args) - self.type.optional_arg_count]
1663 arg_names = [arg.name for arg in args]
1665 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1667 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1668 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1669 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1670 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)
1671 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1673 def declare_arguments(self, env):
1674 for arg in self.type.args:
1676 error(arg.pos, "Missing argument name")
1677 self.declare_argument(env, arg)
1679 def need_gil_acquisition(self, lenv):
1680 return self.type.with_gil
1682 def nogil_check(self, env):
1684 with_gil = type.with_gil
1685 if type.nogil and not with_gil:
1686 if type.return_type.is_pyobject:
1688 "Function with Python return type cannot be declared nogil")
1689 for entry in self.local_scope.var_entries:
1690 if entry.type.is_pyobject:
1691 error(self.pos, "Function declared nogil has Python locals or temporaries")
1693 def analyse_expressions(self, env):
1694 self.local_scope.directives = env.directives
1695 if self.py_func is not None:
1696 # this will also analyse the default values
1697 self.py_func.analyse_expressions(env)
1699 self.analyse_default_values(env)
1700 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1702 def needs_assignment_synthesis(self, env, code=None):
1705 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1708 visibility = self.entry.visibility
1709 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1710 arg_decls.append(arg.declaration_code())
1711 if with_dispatch and self.overridable:
1712 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1713 if type.optional_arg_count and with_opt_args:
1714 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1715 if type.has_varargs:
1716 arg_decls.append("...")
1718 arg_decls = ["void"]
1720 cname = self.entry.func_cname
1721 entity = type.function_header_code(cname, ', '.join(arg_decls))
1722 if visibility == 'public':
1723 dll_linkage = "DL_EXPORT"
1726 header = self.return_type.declaration_code(entity,
1727 dll_linkage = dll_linkage)
1728 if visibility == 'extern':
1729 storage_class = "%s " % Naming.extern_c_macro
1730 elif visibility == 'public':
1733 storage_class = "static "
1734 if 'inline' in self.modifiers:
1735 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1736 code.putln("%s%s %s {" % (
1738 ' '.join(self.modifiers).upper(), # macro forms
1741 def generate_argument_declarations(self, env, code):
1742 for arg in self.args:
1744 result = arg.calculate_default_value_code(code)
1745 code.putln('%s = %s;' % (
1746 arg.type.declaration_code(arg.cname), result))
1748 def generate_keyword_list(self, code):
1751 def generate_argument_parsing_code(self, env, code):
1753 if self.type.optional_arg_count:
1754 code.putln('if (%s) {' % Naming.optional_args_cname)
1755 for arg in self.args:
1757 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1758 declarator = arg.declarator
1759 while not hasattr(declarator, 'name'):
1760 declarator = declarator.base
1761 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1763 for _ in range(self.type.optional_arg_count):
1767 def generate_argument_conversion_code(self, code):
1770 def generate_argument_type_tests(self, code):
1771 # Generate type tests for args whose type in a parent
1772 # class is a supertype of the declared type.
1773 for arg in self.type.args:
1774 if arg.needs_type_test:
1775 self.generate_arg_type_test(arg, code)
1776 elif arg.type.is_pyobject and not arg.accept_none:
1777 self.generate_arg_none_check(arg, code)
1779 def error_value(self):
1780 if self.return_type.is_pyobject:
1784 return self.entry.type.exception_value
1786 def caller_will_check_exceptions(self):
1787 return self.entry.type.exception_check
1789 def generate_wrapper_functions(self, code):
1790 # If the C signature of a function has changed, we need to generate
1791 # wrappers to put in the slots here.
1794 func_type = entry.type
1795 while entry.prev_entry is not None:
1797 entry = entry.prev_entry
1798 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1800 self.generate_function_header(code,
1802 with_dispatch = entry.type.is_overridable,
1803 with_opt_args = entry.type.optional_arg_count,
1804 cname = entry.func_cname)
1805 if not self.return_type.is_void:
1807 args = self.type.args
1808 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1809 if entry.type.is_overridable:
1810 arglist.append(Naming.skip_dispatch_cname)
1811 elif func_type.is_overridable:
1813 if entry.type.optional_arg_count:
1814 arglist.append(Naming.optional_args_cname)
1815 elif func_type.optional_arg_count:
1816 arglist.append('NULL')
1817 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1821 class PyArgDeclNode(Node):
1822 # Argument which must be a Python object (used
1823 # for * and ** arguments).
1826 # entry Symtab.Entry
1827 # annotation ExprNode or None Py3 argument annotation
1830 def generate_function_definitions(self, env, code):
1831 self.entry.generate_function_definitions(env, code)
1833 class DecoratorNode(Node):
1836 # decorator NameNode or CallNode or AttributeNode
1837 child_attrs = ['decorator']
1840 class DefNode(FuncDefNode):
1841 # A Python function definition.
1843 # name string the Python name of the function
1844 # lambda_name string the internal name of a lambda 'function'
1845 # decorators [DecoratorNode] list of decorators
1846 # args [CArgDeclNode] formal arguments
1847 # star_arg PyArgDeclNode or None * argument
1848 # starstar_arg PyArgDeclNode or None ** argument
1849 # doc EncodedString or None
1851 # return_type_annotation
1852 # ExprNode or None the Py3 return type annotation
1854 # The following subnode is constructed internally
1855 # when the def statement is inside a Python class definition.
1857 # assmt AssignmentNode Function construction/assignment
1859 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1864 num_required_kw_args = 0
1865 reqd_kw_flags_cname = "0"
1868 return_type_annotation = None
1873 def __init__(self, pos, **kwds):
1874 FuncDefNode.__init__(self, pos, **kwds)
1876 for arg in self.args:
1883 self.num_kwonly_args = k
1884 self.num_required_kw_args = rk
1885 self.num_required_args = r
1887 def as_cfunction(self, cfunc=None, scope=None):
1889 error(self.star_arg.pos, "cdef function cannot have star argument")
1890 if self.starstar_arg:
1891 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1894 for formal_arg in self.args:
1895 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1896 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1898 type = py_object_type,
1899 pos = formal_arg.pos))
1900 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1902 has_varargs = False,
1903 exception_value = None,
1904 exception_check = False,
1907 is_overridable = True)
1908 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1910 cfunc_type = cfunc.type
1911 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1912 error(self.pos, "wrong number of arguments")
1913 error(cfunc.pos, "previous declaration here")
1914 for formal_arg, type_arg in zip(self.args, cfunc_type.args):
1915 name_declarator, type = formal_arg.analyse(cfunc.scope, nonempty=1)
1916 if type is None or type is PyrexTypes.py_object_type or formal_arg.is_self:
1917 formal_arg.type = type_arg.type
1918 formal_arg.name_declarator = name_declarator
1920 if cfunc_type.exception_value is None:
1921 exception_value = None
1923 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1924 declarator = CFuncDeclaratorNode(self.pos,
1925 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1927 has_varargs = False,
1928 exception_check = cfunc_type.exception_check,
1929 exception_value = exception_value,
1930 with_gil = cfunc_type.with_gil,
1931 nogil = cfunc_type.nogil)
1932 return CFuncDefNode(self.pos,
1934 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1935 declarator = declarator,
1938 overridable = cfunc_type.is_overridable,
1940 with_gil = cfunc_type.with_gil,
1941 nogil = cfunc_type.nogil,
1942 visibility = 'private',
1944 directive_locals = getattr(cfunc, 'directive_locals', {}))
1946 def analyse_declarations(self, env):
1947 self.is_classmethod = self.is_staticmethod = False
1949 for decorator in self.decorators:
1950 func = decorator.decorator
1952 self.is_classmethod |= func.name == 'classmethod'
1953 self.is_staticmethod |= func.name == 'staticmethod'
1955 if self.is_classmethod and env.lookup_here('classmethod'):
1956 # classmethod() was overridden - not much we can do here ...
1957 self.is_classmethod = False
1958 if self.is_staticmethod and env.lookup_here('staticmethod'):
1959 # staticmethod() was overridden - not much we can do here ...
1960 self.is_staticmethod = False
1962 self.analyse_argument_types(env)
1963 if self.name == '<lambda>':
1964 self.declare_lambda_function(env)
1966 self.declare_pyfunction(env)
1967 self.analyse_signature(env)
1968 self.return_type = self.entry.signature.return_type()
1969 self.create_local_scope(env)
1971 def analyse_argument_types(self, env):
1972 directive_locals = self.directive_locals = env.directives['locals']
1973 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1974 for arg in self.args:
1975 if hasattr(arg, 'name'):
1977 name_declarator = None
1979 base_type = arg.base_type.analyse(env)
1980 name_declarator, type = \
1981 arg.declarator.analyse(base_type, env)
1982 arg.name = name_declarator.name
1983 if arg.name in directive_locals:
1984 type_node = directive_locals[arg.name]
1985 other_type = type_node.analyse_as_type(env)
1986 if other_type is None:
1987 error(type_node.pos, "Not a type")
1988 elif (type is not PyrexTypes.py_object_type
1989 and not type.same_as(other_type)):
1990 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1991 error(type_node.pos, "Previous declaration here")
1994 if name_declarator and name_declarator.cname:
1996 "Python function argument cannot have C name specification")
1997 arg.type = type.as_argument_type()
1999 arg.needs_conversion = 0
2000 arg.needs_type_test = 0
2002 if arg.type.is_pyobject:
2004 arg.accept_none = True
2006 arg.accept_none = False
2007 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2008 if arg.default and arg.default.constant_result is None:
2009 # special case: def func(MyType obj = None)
2010 arg.accept_none = True
2012 # default depends on compiler directive
2013 arg.accept_none = allow_none_for_extension_args
2015 # probably just a plain 'object'
2016 arg.accept_none = True
2018 arg.accept_none = True # won't be used, but must be there
2020 error(arg.pos, "Only Python type arguments can have 'not None'")
2022 error(arg.pos, "Only Python type arguments can have 'or None'")
2024 def analyse_signature(self, env):
2025 if self.entry.is_special:
2026 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2027 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2028 # Use the simpler calling signature for zero- and one-argument functions.
2029 if self.entry.signature is TypeSlots.pyfunction_signature:
2030 if len(self.args) == 0:
2031 self.entry.signature = TypeSlots.pyfunction_noargs
2032 elif len(self.args) == 1:
2033 if self.args[0].default is None and not self.args[0].kw_only:
2034 self.entry.signature = TypeSlots.pyfunction_onearg
2035 elif self.entry.signature is TypeSlots.pymethod_signature:
2036 if len(self.args) == 1:
2037 self.entry.signature = TypeSlots.unaryfunc
2038 elif len(self.args) == 2:
2039 if self.args[1].default is None and not self.args[1].kw_only:
2040 self.entry.signature = TypeSlots.ibinaryfunc
2042 sig = self.entry.signature
2043 nfixed = sig.num_fixed_args()
2044 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2045 and len(self.args) == 0 and self.star_arg:
2046 # this is the only case where a diverging number of
2047 # arguments is not an error - when we have no explicit
2048 # 'self' parameter as in method(*args)
2049 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2050 self.self_in_stararg = 1
2053 for i in range(min(nfixed, len(self.args))):
2056 if sig.is_self_arg(i) and not self.is_staticmethod:
2057 if self.is_classmethod:
2059 arg.hdr_type = arg.type = Builtin.type_type
2062 arg.hdr_type = arg.type = env.parent_type
2063 arg.needs_conversion = 0
2065 arg.hdr_type = sig.fixed_arg_type(i)
2066 if not arg.type.same_as(arg.hdr_type):
2067 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2068 arg.needs_type_test = 1
2070 arg.needs_conversion = 1
2071 if arg.needs_conversion:
2072 arg.hdr_cname = Naming.arg_prefix + arg.name
2074 arg.hdr_cname = Naming.var_prefix + arg.name
2076 if nfixed > len(self.args):
2077 self.bad_signature()
2079 elif nfixed < len(self.args):
2080 if not sig.has_generic_args:
2081 self.bad_signature()
2082 for arg in self.args:
2083 if arg.is_generic and \
2084 (arg.type.is_extension_type or arg.type.is_builtin_type):
2085 arg.needs_type_test = 1
2087 def bad_signature(self):
2088 sig = self.entry.signature
2089 expected_str = "%d" % sig.num_fixed_args()
2090 if sig.has_generic_args:
2091 expected_str = expected_str + " or more"
2093 if name.startswith("__") and name.endswith("__"):
2094 desc = "Special method"
2098 "%s %s has wrong number of arguments "
2099 "(%d declared, %s expected)" % (
2100 desc, self.name, len(self.args), expected_str))
2102 def signature_has_nongeneric_args(self):
2103 argcount = len(self.args)
2104 if argcount == 0 or (
2105 argcount == 1 and (self.args[0].is_self_arg or
2106 self.args[0].is_type_arg)):
2110 def signature_has_generic_args(self):
2111 return self.entry.signature.has_generic_args
2113 def declare_pyfunction(self, env):
2114 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2116 entry = env.lookup_here(name)
2117 if entry and entry.type.is_cfunction and not self.is_wrapper:
2118 warning(self.pos, "Overriding cdef method with def method.", 5)
2119 entry = env.declare_pyfunction(name, self.pos)
2121 prefix = env.scope_prefix
2122 entry.func_cname = \
2123 Naming.pyfunc_prefix + prefix + name
2124 entry.pymethdef_cname = \
2125 Naming.pymethdef_prefix + prefix + name
2126 if Options.docstrings:
2127 entry.doc = embed_position(self.pos, self.doc)
2129 Naming.funcdoc_prefix + prefix + name
2130 if entry.is_special:
2131 if entry.name in TypeSlots.invisible or not entry.doc:
2132 entry.wrapperbase_cname = None
2134 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2138 def declare_lambda_function(self, env):
2140 prefix = env.scope_prefix
2142 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2143 entry = env.declare_lambda_function(func_cname, self.pos)
2144 entry.pymethdef_cname = \
2145 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2146 entry.qualified_name = env.qualify_name(self.lambda_name)
2150 def declare_arguments(self, env):
2151 for arg in self.args:
2153 error(arg.pos, "Missing argument name")
2155 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2156 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2157 if arg.needs_conversion:
2158 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2159 if arg.type.is_pyobject:
2160 arg.entry.init = "0"
2161 arg.entry.init_to_none = 0
2163 arg.entry = self.declare_argument(env, arg)
2165 arg.entry.is_self_arg = arg.is_self_arg
2167 if arg.is_self_arg or arg.is_type_arg or \
2168 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2169 arg.entry.is_declared_generic = 1
2170 self.declare_python_arg(env, self.star_arg)
2171 self.declare_python_arg(env, self.starstar_arg)
2173 def declare_python_arg(self, env, arg):
2175 if env.directives['infer_types'] != False:
2176 type = PyrexTypes.unspecified_type
2178 type = py_object_type
2179 entry = env.declare_var(arg.name, type, arg.pos)
2182 entry.init_to_none = 0
2183 entry.xdecref_cleanup = 1
2185 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2187 def analyse_expressions(self, env):
2188 self.local_scope.directives = env.directives
2189 self.analyse_default_values(env)
2190 if self.needs_assignment_synthesis(env):
2191 # Shouldn't we be doing this at the module level too?
2192 self.synthesize_assignment_node(env)
2194 def needs_assignment_synthesis(self, env, code=None):
2195 # Should enable for module level as well, that will require more testing...
2196 if env.is_module_scope:
2198 return env.directives['binding']
2200 return code.globalstate.directives['binding']
2201 return env.is_py_class_scope or env.is_closure_scope
2203 def synthesize_assignment_node(self, env):
2205 if env.is_py_class_scope:
2206 rhs = ExprNodes.UnboundMethodNode(self.pos,
2207 function = ExprNodes.PyCFunctionNode(self.pos,
2208 pymethdef_cname = self.entry.pymethdef_cname))
2209 elif env.is_closure_scope:
2210 rhs = ExprNodes.InnerFunctionNode(
2211 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2213 rhs = ExprNodes.PyCFunctionNode(
2214 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2215 self.assmt = SingleAssignmentNode(self.pos,
2216 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2218 self.assmt.analyse_declarations(env)
2219 self.assmt.analyse_expressions(env)
2221 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2223 sig = self.entry.signature
2224 if sig.has_dummy_arg or self.self_in_stararg:
2225 arg_code_list.append(
2226 "PyObject *%s" % Naming.self_cname)
2227 for arg in self.args:
2228 if not arg.is_generic:
2229 if arg.is_self_arg or arg.is_type_arg:
2230 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2232 arg_code_list.append(
2233 arg.hdr_type.declaration_code(arg.hdr_cname))
2234 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2235 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2236 if sig.has_generic_args:
2237 arg_code_list.append(
2238 "PyObject *%s, PyObject *%s"
2239 % (Naming.args_cname, Naming.kwds_cname))
2240 arg_code = ", ".join(arg_code_list)
2241 dc = self.return_type.declaration_code(self.entry.func_cname)
2242 mf = " ".join(self.modifiers).upper()
2244 header = "static %s%s(%s)" % (mf, dc, arg_code)
2245 code.putln("%s; /*proto*/" % header)
2248 if (Options.docstrings and self.entry.doc and
2249 not self.entry.scope.is_property_scope and
2250 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2251 docstr = self.entry.doc
2252 if docstr.is_unicode:
2253 docstr = docstr.utf8encode()
2255 'static char %s[] = "%s";' % (
2256 self.entry.doc_cname,
2257 split_string_literal(escape_byte_string(docstr))))
2258 if self.entry.is_special:
2260 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2263 "static PyMethodDef %s = " %
2264 self.entry.pymethdef_cname)
2265 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2266 code.putln("%s {" % header)
2268 def generate_argument_declarations(self, env, code):
2269 for arg in self.args:
2270 if arg.is_generic: # or arg.needs_conversion:
2271 if arg.needs_conversion:
2272 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2273 elif not arg.entry.in_closure:
2274 code.put_var_declaration(arg.entry)
2276 def generate_keyword_list(self, code):
2277 if self.signature_has_generic_args() and \
2278 self.signature_has_nongeneric_args():
2280 "static PyObject **%s[] = {" %
2281 Naming.pykwdlist_cname)
2282 for arg in self.args:
2284 pystring_cname = code.intern_identifier(arg.name)
2285 code.put('&%s,' % pystring_cname)
2288 def generate_argument_parsing_code(self, env, code):
2289 # Generate PyArg_ParseTuple call for generic
2290 # arguments, if any.
2291 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2292 # get rid of unused argument warning
2293 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2295 old_error_label = code.new_error_label()
2296 our_error_label = code.error_label
2297 end_label = code.new_label("argument_unpacking_done")
2299 has_kwonly_args = self.num_kwonly_args > 0
2300 has_star_or_kw_args = self.star_arg is not None \
2301 or self.starstar_arg is not None or has_kwonly_args
2303 for arg in self.args:
2304 if not arg.type.is_pyobject:
2305 done = arg.type.create_from_py_utility_code(env)
2306 if not done: pass # will fail later
2308 if not self.signature_has_generic_args():
2309 if has_star_or_kw_args:
2310 error(self.pos, "This method cannot have * or keyword arguments")
2311 self.generate_argument_conversion_code(code)
2313 elif not self.signature_has_nongeneric_args():
2314 # func(*args) or func(**kw) or func(*args, **kw)
2315 self.generate_stararg_copy_code(code)
2318 positional_args = []
2320 for arg in self.args:
2321 arg_entry = arg.entry
2324 if not arg.is_self_arg and not arg.is_type_arg:
2326 kw_only_args.append(arg)
2328 positional_args.append(arg)
2330 kw_only_args.append(arg)
2331 elif not arg.is_self_arg and not arg.is_type_arg:
2332 positional_args.append(arg)
2334 self.generate_tuple_and_keyword_parsing_code(
2335 positional_args, kw_only_args, end_label, code)
2337 code.error_label = old_error_label
2338 if code.label_used(our_error_label):
2339 if not code.label_used(end_label):
2340 code.put_goto(end_label)
2341 code.put_label(our_error_label)
2342 if has_star_or_kw_args:
2343 self.generate_arg_decref(self.star_arg, code)
2344 if self.starstar_arg:
2345 if self.starstar_arg.entry.xdecref_cleanup:
2346 code.put_var_xdecref(self.starstar_arg.entry)
2348 code.put_var_decref(self.starstar_arg.entry)
2349 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2350 # The arguments are put into the closure one after the
2351 # other, so when type errors are found, all references in
2352 # the closure instance must be properly ref-counted to
2353 # facilitate generic closure instance deallocation. In
2354 # the case of an argument type error, it's best to just
2355 # DECREF+clear the already handled references, as this
2356 # frees their references as early as possible.
2357 for arg in self.args:
2358 if arg.type.is_pyobject and arg.entry.in_closure:
2359 code.put_var_xdecref_clear(arg.entry)
2360 if self.needs_closure:
2361 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2362 code.put_finish_refcount_context()
2363 code.putln("return %s;" % self.error_value())
2364 if code.label_used(end_label):
2365 code.put_label(end_label)
2367 def generate_arg_assignment(self, arg, item, code):
2368 if arg.type.is_pyobject:
2370 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2372 code.putln("%s = %s;" % (entry.cname, item))
2373 if entry.in_closure:
2374 code.put_var_incref(entry)
2376 func = arg.type.from_py_function
2378 code.putln("%s = %s(%s); %s" % (
2382 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2384 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2386 def generate_arg_xdecref(self, arg, code):
2388 code.put_var_xdecref(arg.entry)
2390 def generate_arg_decref(self, arg, code):
2392 code.put_var_decref(arg.entry)
2394 def generate_stararg_copy_code(self, code):
2395 if not self.star_arg:
2396 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2397 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2399 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2400 self.name, Naming.args_cname, self.error_value()))
2403 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2405 if self.starstar_arg:
2407 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2409 kwarg_check = "%s" % Naming.kwds_cname
2411 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2412 Naming.kwds_cname, Naming.kwds_cname)
2414 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2415 kwarg_check, Naming.kwds_cname, self.name,
2416 bool(self.starstar_arg), self.error_value()))
2418 if self.starstar_arg:
2419 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2420 self.starstar_arg.entry.cname,
2423 code.putln("if (unlikely(!%s)) return %s;" % (
2424 self.starstar_arg.entry.cname, self.error_value()))
2425 self.starstar_arg.entry.xdecref_cleanup = 0
2426 code.put_gotref(self.starstar_arg.entry.cname)
2428 if self.self_in_stararg:
2429 # need to create a new tuple with 'self' inserted as first item
2430 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2431 self.star_arg.entry.cname,
2433 self.star_arg.entry.cname))
2434 if self.starstar_arg:
2436 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2437 code.putln("return %s;" % self.error_value())
2440 code.putln("return %s;" % self.error_value())
2441 code.put_gotref(self.star_arg.entry.cname)
2442 code.put_incref(Naming.self_cname, py_object_type)
2443 code.put_giveref(Naming.self_cname)
2444 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2445 self.star_arg.entry.cname, Naming.self_cname))
2446 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2447 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2448 temp, temp, Naming.args_cname, temp))
2449 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2450 Naming.args_cname, temp))
2451 code.put_incref("item", py_object_type)
2452 code.put_giveref("item")
2453 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2454 self.star_arg.entry.cname, temp))
2456 code.funcstate.release_temp(temp)
2457 self.star_arg.entry.xdecref_cleanup = 0
2459 code.put_incref(Naming.args_cname, py_object_type)
2460 code.putln("%s = %s;" % (
2461 self.star_arg.entry.cname,
2463 self.star_arg.entry.xdecref_cleanup = 0
2465 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2466 kw_only_args, success_label, code):
2467 argtuple_error_label = code.new_label("argtuple_error")
2469 min_positional_args = self.num_required_args - self.num_required_kw_args
2470 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2471 min_positional_args -= 1
2472 max_positional_args = len(positional_args)
2473 has_fixed_positional_count = not self.star_arg and \
2474 min_positional_args == max_positional_args
2476 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2477 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2478 if self.num_required_kw_args:
2479 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2481 if self.starstar_arg or self.star_arg:
2482 self.generate_stararg_init_code(max_positional_args, code)
2484 # --- optimised code when we receive keyword arguments
2485 if self.num_required_kw_args:
2486 likely_hint = "likely"
2488 likely_hint = "unlikely"
2489 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2490 self.generate_keyword_unpacking_code(
2491 min_positional_args, max_positional_args,
2492 has_fixed_positional_count,
2493 positional_args, kw_only_args, argtuple_error_label, code)
2495 # --- optimised code when we do not receive any keyword arguments
2496 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2497 # Python raises arg tuple related errors first, so we must
2498 # check the length here
2499 if min_positional_args == max_positional_args and not self.star_arg:
2503 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2504 Naming.args_cname, compare, min_positional_args))
2505 code.put_goto(argtuple_error_label)
2507 if self.num_required_kw_args:
2508 # pure error case: keywords required but not passed
2509 if max_positional_args > min_positional_args and not self.star_arg:
2510 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2511 Naming.args_cname, max_positional_args))
2512 code.put_goto(argtuple_error_label)
2513 code.putln('} else {')
2514 for i, arg in enumerate(kw_only_args):
2516 pystring_cname = code.intern_identifier(arg.name)
2517 # required keyword-only argument missing
2518 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2521 code.putln(code.error_goto(self.pos))
2524 elif min_positional_args == max_positional_args:
2525 # parse the exact number of positional arguments from the
2527 code.putln('} else {')
2528 for i, arg in enumerate(positional_args):
2529 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2530 self.generate_arg_assignment(arg, item, code)
2531 self.generate_arg_default_assignments(code)
2534 # parse the positional arguments from the variable length
2536 code.putln('} else {')
2537 self.generate_arg_default_assignments(code)
2538 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2540 code.putln('default:')
2541 reversed_args = list(enumerate(positional_args))[::-1]
2542 for i, arg in reversed_args:
2543 if i >= min_positional_args-1:
2544 if min_positional_args > 1:
2545 code.putln('case %2d:' % (i+1)) # pure code beautification
2547 code.put('case %2d: ' % (i+1))
2548 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2549 self.generate_arg_assignment(arg, item, code)
2550 if min_positional_args == 0:
2551 code.put('case 0: ')
2552 code.putln('break;')
2554 if min_positional_args:
2555 for i in range(min_positional_args-1, -1, -1):
2556 code.putln('case %2d:' % i)
2557 code.put_goto(argtuple_error_label)
2559 code.put('default: ')
2560 code.put_goto(argtuple_error_label)
2565 if code.label_used(argtuple_error_label):
2566 code.put_goto(success_label)
2567 code.put_label(argtuple_error_label)
2568 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2569 self.name, has_fixed_positional_count,
2570 min_positional_args, max_positional_args,
2572 code.putln(code.error_goto(self.pos))
2574 def generate_arg_default_assignments(self, code):
2575 for arg in self.args:
2576 if arg.is_generic and arg.default:
2580 arg.calculate_default_value_code(code)))
2582 def generate_stararg_init_code(self, max_positional_args, code):
2583 if self.starstar_arg:
2584 self.starstar_arg.entry.xdecref_cleanup = 0
2585 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2586 self.starstar_arg.entry.cname,
2587 self.starstar_arg.entry.cname,
2588 self.error_value()))
2589 code.put_gotref(self.starstar_arg.entry.cname)
2591 self.star_arg.entry.xdecref_cleanup = 0
2592 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2594 max_positional_args))
2595 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2596 self.star_arg.entry.cname, Naming.args_cname,
2597 max_positional_args, Naming.args_cname))
2598 code.put_gotref(self.star_arg.entry.cname)
2599 if self.starstar_arg:
2601 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2602 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2603 code.putln('return %s;' % self.error_value())
2606 code.putln("if (unlikely(!%s)) return %s;" % (
2607 self.star_arg.entry.cname, self.error_value()))
2608 code.putln('} else {')
2609 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2610 code.put_incref(Naming.empty_tuple, py_object_type)
2613 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2614 has_fixed_positional_count, positional_args,
2615 kw_only_args, argtuple_error_label, code):
2616 all_args = tuple(positional_args) + tuple(kw_only_args)
2617 max_args = len(all_args)
2619 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2621 # the 'values' array collects borrowed references to arguments
2622 # before doing any type coercion etc.
2623 code.putln("PyObject* values[%d] = {%s};" % (
2624 max_args, ','.join('0'*max_args)))
2626 # assign borrowed Python default values to the values array,
2627 # so that they can be overwritten by received arguments below
2628 for i, arg in enumerate(all_args):
2629 if arg.default and arg.type.is_pyobject:
2630 default_value = arg.calculate_default_value_code(code)
2631 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2633 # parse the args tuple and check that it's not too long
2634 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2636 code.putln('default:')
2637 for i in range(max_positional_args-1, -1, -1):
2638 code.put('case %2d: ' % (i+1))
2639 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2640 i, Naming.args_cname, i))
2641 code.putln('case 0: break;')
2642 if not self.star_arg:
2643 code.put('default: ') # more arguments than allowed
2644 code.put_goto(argtuple_error_label)
2647 # now fill up the positional/required arguments with values
2649 if self.num_required_args or max_positional_args > 0:
2650 last_required_arg = -1
2651 for i, arg in enumerate(all_args):
2653 last_required_arg = i
2654 if last_required_arg < max_positional_args:
2655 last_required_arg = max_positional_args-1
2656 num_required_args = self.num_required_args
2657 if max_positional_args > 0:
2658 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2659 for i, arg in enumerate(all_args[:last_required_arg+1]):
2660 if max_positional_args > 0 and i <= max_positional_args:
2661 if self.star_arg and i == max_positional_args:
2662 code.putln('default:')
2664 code.putln('case %2d:' % i)
2665 pystring_cname = code.intern_identifier(arg.name)
2668 # handled separately below
2670 code.putln('if (kw_args > 0) {')
2671 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2672 Naming.kwds_cname, pystring_cname))
2673 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2676 num_required_args -= 1
2677 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2678 i, Naming.kwds_cname, pystring_cname))
2679 code.putln('if (likely(values[%d])) kw_args--;' % i);
2680 if i < min_positional_args:
2682 # special case: we know arg 0 is missing
2684 code.put_goto(argtuple_error_label)
2686 # print the correct number of values (args or
2687 # kwargs) that were passed into positional
2688 # arguments up to this point
2689 code.putln('else {')
2690 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2691 self.name, has_fixed_positional_count,
2692 min_positional_args, max_positional_args, i))
2693 code.putln(code.error_goto(self.pos))
2696 code.putln('else {')
2697 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2698 self.name, pystring_cname))
2699 code.putln(code.error_goto(self.pos))
2701 if max_positional_args > 0:
2704 if kw_only_args and not self.starstar_arg:
2705 # unpack optional keyword-only arguments
2706 # checking for interned strings in a dict is faster than iterating
2707 # but it's too likely that we must iterate if we expect **kwargs
2709 for i, arg in enumerate(all_args[max_positional_args:]):
2710 if not arg.kw_only or not arg.default:
2712 optional_args.append((i+max_positional_args, arg))
2714 # this mimics an unrolled loop so that we can "break" out of it
2715 code.putln('while (kw_args > 0) {')
2716 code.putln('PyObject* value;')
2717 for i, arg in optional_args:
2718 pystring_cname = code.intern_identifier(arg.name)
2720 'value = PyDict_GetItem(%s, %s);' % (
2721 Naming.kwds_cname, pystring_cname))
2723 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2724 code.putln('break;')
2727 code.putln('if (unlikely(kw_args > 0)) {')
2728 # non-positional/-required kw args left in dict: default args,
2729 # kw-only args, **kwargs or error
2731 # This is sort of a catch-all: except for checking required
2732 # arguments, this will always do the right thing for unpacking
2733 # keyword arguments, so that we can concentrate on optimising
2734 # common cases above.
2735 if max_positional_args == 0:
2738 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2739 Naming.args_cname, max_positional_args,
2740 Naming.args_cname, max_positional_args))
2741 pos_arg_count = "used_pos_args"
2743 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2744 code.globalstate.use_utility_code(parse_keywords_utility_code)
2746 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2748 Naming.pykwdlist_cname,
2749 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2752 code.putln(code.error_goto(self.pos))
2755 # convert arg values to their final type and assign them
2756 for i, arg in enumerate(all_args):
2757 if arg.default and not arg.type.is_pyobject:
2758 code.putln("if (values[%d]) {" % i)
2759 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2760 if arg.default and not arg.type.is_pyobject:
2761 code.putln('} else {')
2765 arg.calculate_default_value_code(code)))
2768 def generate_argument_conversion_code(self, code):
2769 # Generate code to convert arguments from signature type to
2770 # declared type, if needed. Also copies signature arguments
2771 # into closure fields.
2772 for arg in self.args:
2773 if arg.needs_conversion:
2774 self.generate_arg_conversion(arg, code)
2775 elif arg.entry.in_closure:
2776 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2777 if arg.type.is_pyobject:
2778 code.put_var_incref(arg.entry)
2780 def generate_arg_conversion(self, arg, code):
2781 # Generate conversion code for one argument.
2782 old_type = arg.hdr_type
2784 if old_type.is_pyobject:
2786 code.putln("if (%s) {" % arg.hdr_cname)
2788 code.putln("assert(%s); {" % arg.hdr_cname)
2789 self.generate_arg_conversion_from_pyobject(arg, code)
2791 elif new_type.is_pyobject:
2792 self.generate_arg_conversion_to_pyobject(arg, code)
2794 if new_type.assignable_from(old_type):
2796 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2799 "Cannot convert 1 argument from '%s' to '%s'" %
2800 (old_type, new_type))
2802 def generate_arg_conversion_from_pyobject(self, arg, code):
2804 func = new_type.from_py_function
2805 # copied from CoerceFromPyTypeNode
2807 lhs = arg.entry.cname
2808 rhs = "%s(%s)" % (func, arg.hdr_cname)
2809 if new_type.is_enum:
2810 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2811 code.putln("%s = %s; %s" % (
2814 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2817 "Cannot convert Python object argument to type '%s'"
2820 def generate_arg_conversion_to_pyobject(self, arg, code):
2821 old_type = arg.hdr_type
2822 func = old_type.to_py_function
2824 code.putln("%s = %s(%s); %s" % (
2828 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2829 code.put_var_gotref(arg.entry)
2832 "Cannot convert argument of type '%s' to Python object"
2835 def generate_argument_type_tests(self, code):
2836 # Generate type tests for args whose signature
2837 # type is PyObject * and whose declared type is
2838 # a subtype thereof.
2839 for arg in self.args:
2840 if arg.needs_type_test:
2841 self.generate_arg_type_test(arg, code)
2842 elif not arg.accept_none and arg.type.is_pyobject:
2843 self.generate_arg_none_check(arg, code)
2845 def error_value(self):
2846 return self.entry.signature.error_value
2848 def caller_will_check_exceptions(self):
2851 class OverrideCheckNode(StatNode):
2852 # A Node for dispatching to the def method if it
2861 child_attrs = ['body']
2865 def analyse_expressions(self, env):
2866 self.args = env.arg_entries
2867 if self.py_func.is_module_scope:
2872 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2873 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2874 call_node = ExprNodes.SimpleCallNode(self.pos,
2875 function=self.func_node,
2876 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2877 self.body = ReturnStatNode(self.pos, value=call_node)
2878 self.body.analyse_expressions(env)
2880 def generate_execution_code(self, code):
2881 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2882 # Check to see if we are an extension type
2883 if self.py_func.is_module_scope:
2884 self_arg = "((PyObject *)%s)" % Naming.module_cname
2886 self_arg = "((PyObject *)%s)" % self.args[0].cname
2887 code.putln("/* Check if called by wrapper */")
2888 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2889 code.putln("/* Check if overriden in Python */")
2890 if self.py_func.is_module_scope:
2891 code.putln("else {")
2893 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2894 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2895 self.func_node.set_cname(func_node_temp)
2896 # need to get attribute manually--scope would return cdef method
2897 err = code.error_goto_if_null(func_node_temp, self.pos)
2898 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2899 func_node_temp, self_arg, interned_attr_cname, err))
2900 code.put_gotref(func_node_temp)
2901 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2902 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2903 func_node_temp, self.py_func.entry.func_cname)
2904 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2905 self.body.generate_execution_code(code)
2907 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2908 code.funcstate.release_temp(func_node_temp)
2911 class ClassDefNode(StatNode, BlockNode):
2914 class PyClassDefNode(ClassDefNode):
2915 # A Python class definition.
2917 # name EncodedString Name of the class
2918 # doc string or None
2919 # body StatNode Attribute definition code
2920 # entry Symtab.Entry
2921 # scope PyClassScope
2922 # decorators [DecoratorNode] list of decorators or None
2924 # The following subnodes are constructed internally:
2926 # dict DictNode Class dictionary
2927 # classobj ClassNode Class object
2928 # target NameNode Variable to assign class object to
2930 child_attrs = ["body", "dict", "classobj", "target"]
2933 def __init__(self, pos, name, bases, doc, body, decorators = None):
2934 StatNode.__init__(self, pos)
2938 self.decorators = decorators
2940 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2941 if self.doc and Options.docstrings:
2942 doc = embed_position(self.pos, self.doc)
2943 # FIXME: correct string node?
2944 doc_node = ExprNodes.StringNode(pos, value = doc)
2947 self.classobj = ExprNodes.ClassNode(pos, name = name,
2948 bases = bases, dict = self.dict, doc = doc_node)
2949 self.target = ExprNodes.NameNode(pos, name = name)
2951 def as_cclass(self):
2953 Return this node as if it were declared as an extension class
2955 bases = self.classobj.bases.args
2957 base_class_name = None
2958 base_class_module = None
2959 elif len(bases) == 1:
2962 from ExprNodes import AttributeNode, NameNode
2963 while isinstance(base, AttributeNode):
2964 path.insert(0, base.attribute)
2966 if isinstance(base, NameNode):
2967 path.insert(0, base.name)
2968 base_class_name = path[-1]
2970 base_class_module = u'.'.join(path[:-1])
2972 base_class_module = None
2974 error(self.classobj.bases.args.pos, "Invalid base class")
2976 error(self.classobj.bases.args.pos, "C class may only have one base class")
2979 return CClassDefNode(self.pos,
2980 visibility = 'private',
2982 class_name = self.name,
2983 base_class_module = base_class_module,
2984 base_class_name = base_class_name,
2985 decorators = self.decorators,
2990 def create_scope(self, env):
2992 while env.is_py_class_scope or env.is_c_class_scope:
2993 env = env.outer_scope
2994 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
2997 def analyse_declarations(self, env):
2998 self.target.analyse_target_declaration(env)
2999 cenv = self.create_scope(env)
3000 cenv.directives = env.directives
3001 cenv.class_obj_cname = self.target.entry.cname
3002 self.body.analyse_declarations(cenv)
3004 def analyse_expressions(self, env):
3005 self.dict.analyse_expressions(env)
3006 self.classobj.analyse_expressions(env)
3007 genv = env.global_scope()
3009 self.body.analyse_expressions(cenv)
3010 self.target.analyse_target_expression(env, self.classobj)
3012 def generate_function_definitions(self, env, code):
3013 self.body.generate_function_definitions(self.scope, code)
3015 def generate_execution_code(self, code):
3016 code.pyclass_stack.append(self)
3018 self.dict.generate_evaluation_code(code)
3019 self.classobj.generate_evaluation_code(code)
3020 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3021 self.body.generate_execution_code(code)
3022 self.target.generate_assignment_code(self.classobj, code)
3023 self.dict.generate_disposal_code(code)
3024 self.dict.free_temps(code)
3025 code.pyclass_stack.pop()
3028 class CClassDefNode(ClassDefNode):
3029 # An extension type definition.
3031 # visibility 'private' or 'public' or 'extern'
3032 # typedef_flag boolean
3034 # module_name string or None For import of extern type objects
3035 # class_name string Unqualified name of class
3036 # as_name string or None Name to declare as in this scope
3037 # base_class_module string or None Module containing the base class
3038 # base_class_name string or None Name of the base class
3039 # objstruct_name string or None Specified C name of object struct
3040 # typeobj_name string or None Specified C name of type object
3041 # in_pxd boolean Is in a .pxd file
3042 # decorators [DecoratorNode] list of decorators or None
3043 # doc string or None
3044 # body StatNode or None
3045 # entry Symtab.Entry
3046 # base_type PyExtensionType or None
3047 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3048 # buffer_defaults_pos
3050 child_attrs = ["body"]
3051 buffer_defaults_node = None
3052 buffer_defaults_pos = None
3053 typedef_flag = False
3055 objstruct_name = None
3059 def analyse_declarations(self, env):
3060 #print "CClassDefNode.analyse_declarations:", self.class_name
3061 #print "...visibility =", self.visibility
3062 #print "...module_name =", self.module_name
3065 if self.buffer_defaults_node:
3066 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3067 env, [], self.buffer_defaults_node,
3068 need_complete=False)
3070 buffer_defaults = None
3072 if env.in_cinclude and not self.objstruct_name:
3073 error(self.pos, "Object struct name specification required for "
3074 "C class defined in 'extern from' block")
3075 self.base_type = None
3076 # Now that module imports are cached, we need to
3077 # import the modules for extern classes.
3078 if self.module_name:
3080 for module in env.cimported_modules:
3081 if module.name == self.module_name:
3082 self.module = module
3083 if self.module is None:
3084 self.module = ModuleScope(self.module_name, None, env.context)
3085 self.module.has_extern_class = 1
3086 env.add_imported_module(self.module)
3088 if self.base_class_name:
3089 if self.base_class_module:
3090 base_class_scope = env.find_module(self.base_class_module, self.pos)
3092 base_class_scope = env
3093 if self.base_class_name == 'object':
3094 # extension classes are special and don't need to inherit from object
3095 if base_class_scope is None or base_class_scope.lookup('object') is None:
3096 self.base_class_name = None
3097 self.base_class_module = None
3098 base_class_scope = None
3099 if base_class_scope:
3100 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3101 if base_class_entry:
3102 if not base_class_entry.is_type:
3103 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3104 elif not base_class_entry.type.is_extension_type:
3105 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3106 elif not base_class_entry.type.is_complete():
3107 error(self.pos, "Base class '%s' is incomplete" % self.base_class_name)
3109 self.base_type = base_class_entry.type
3110 has_body = self.body is not None
3111 if self.module_name and self.visibility != 'extern':
3112 module_path = self.module_name.split(".")
3113 home_scope = env.find_imported_module(module_path, self.pos)
3119 if self.visibility == 'extern':
3120 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3121 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3123 self.entry = home_scope.declare_c_class(
3124 name = self.class_name,
3126 defining = has_body and self.in_pxd,
3127 implementing = has_body and not self.in_pxd,
3128 module_name = self.module_name,
3129 base_type = self.base_type,
3130 objstruct_cname = self.objstruct_name,
3131 typeobj_cname = self.typeobj_name,
3132 visibility = self.visibility,
3133 typedef_flag = self.typedef_flag,
3135 buffer_defaults = buffer_defaults)
3136 if home_scope is not env and self.visibility == 'extern':
3137 env.add_imported_entry(self.class_name, self.entry, pos)
3138 self.scope = scope = self.entry.type.scope
3139 if scope is not None:
3140 scope.directives = env.directives
3142 if self.doc and Options.docstrings:
3143 scope.doc = embed_position(self.pos, self.doc)
3146 self.body.analyse_declarations(scope)
3150 scope.implemented = 1
3151 env.allocate_vtable_names(self.entry)
3153 def analyse_expressions(self, env):
3155 scope = self.entry.type.scope
3156 self.body.analyse_expressions(scope)
3158 def generate_function_definitions(self, env, code):
3160 self.body.generate_function_definitions(
3161 self.entry.type.scope, code)
3163 def generate_execution_code(self, code):
3164 # This is needed to generate evaluation code for
3165 # default values of method arguments.
3167 self.body.generate_execution_code(code)
3169 def annotate(self, code):
3171 self.body.annotate(code)
3174 class PropertyNode(StatNode):
3175 # Definition of a property in an extension type.
3178 # doc EncodedString or None Doc string
3181 child_attrs = ["body"]
3183 def analyse_declarations(self, env):
3184 entry = env.declare_property(self.name, self.doc, self.pos)
3186 entry.scope.directives = env.directives
3187 self.body.analyse_declarations(entry.scope)
3189 def analyse_expressions(self, env):
3190 self.body.analyse_expressions(env)
3192 def generate_function_definitions(self, env, code):
3193 self.body.generate_function_definitions(env, code)
3195 def generate_execution_code(self, code):
3198 def annotate(self, code):
3199 self.body.annotate(code)
3202 class GlobalNode(StatNode):
3203 # Global variable declaration.
3209 def analyse_declarations(self, env):
3210 for name in self.names:
3211 env.declare_global(name, self.pos)
3213 def analyse_expressions(self, env):
3216 def generate_execution_code(self, code):
3220 class ExprStatNode(StatNode):
3221 # Expression used as a statement.
3225 child_attrs = ["expr"]
3227 def analyse_declarations(self, env):
3229 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3230 func = self.expr.function.as_cython_attribute()
3231 if func == u'declare':
3232 args, kwds = self.expr.explicit_args_kwds()
3234 error(self.expr.pos, "Variable names must be specified.")
3235 for var, type_node in kwds.key_value_pairs:
3236 type = type_node.analyse_as_type(env)
3238 error(type_node.pos, "Unknown type")
3240 env.declare_var(var.value, type, var.pos, is_cdef = True)
3241 self.__class__ = PassStatNode
3243 def analyse_expressions(self, env):
3244 self.expr.analyse_expressions(env)
3246 def generate_execution_code(self, code):
3247 self.expr.generate_evaluation_code(code)
3248 if not self.expr.is_temp and self.expr.result():
3249 code.putln("%s;" % self.expr.result())
3250 self.expr.generate_disposal_code(code)
3251 self.expr.free_temps(code)
3253 def generate_function_definitions(self, env, code):
3254 self.expr.generate_function_definitions(env, code)
3256 def annotate(self, code):
3257 self.expr.annotate(code)
3260 class AssignmentNode(StatNode):
3261 # Abstract base class for assignment nodes.
3263 # The analyse_expressions and generate_execution_code
3264 # phases of assignments are split into two sub-phases
3265 # each, to enable all the right hand sides of a
3266 # parallel assignment to be evaluated before assigning
3267 # to any of the left hand sides.
3269 def analyse_expressions(self, env):
3270 self.analyse_types(env)
3272 # def analyse_expressions(self, env):
3273 # self.analyse_expressions_1(env)
3274 # self.analyse_expressions_2(env)
3276 def generate_execution_code(self, code):
3277 self.generate_rhs_evaluation_code(code)
3278 self.generate_assignment_code(code)
3281 class SingleAssignmentNode(AssignmentNode):
3282 # The simplest case:
3286 # lhs ExprNode Left hand side
3287 # rhs ExprNode Right hand side
3288 # first bool Is this guaranteed the first assignment to lhs?
3290 child_attrs = ["lhs", "rhs"]
3292 declaration_only = False
3294 def analyse_declarations(self, env):
3297 # handle declarations of the form x = cython.foo()
3298 if isinstance(self.rhs, ExprNodes.CallNode):
3299 func_name = self.rhs.function.as_cython_attribute()
3301 args, kwds = self.rhs.explicit_args_kwds()
3303 if func_name in ['declare', 'typedef']:
3304 if len(args) > 2 or kwds is not None:
3305 error(rhs.pos, "Can only declare one type at a time.")
3307 type = args[0].analyse_as_type(env)
3309 error(args[0].pos, "Unknown type")
3312 if func_name == 'declare':
3313 if isinstance(lhs, ExprNodes.NameNode):
3314 vars = [(lhs.name, lhs.pos)]
3315 elif isinstance(lhs, ExprNodes.TupleNode):
3316 vars = [(var.name, var.pos) for var in lhs.args]
3318 error(lhs.pos, "Invalid declaration")
3320 for var, pos in vars:
3321 env.declare_var(var, type, pos, is_cdef = True)
3326 self.declaration_only = True
3328 self.declaration_only = True
3329 if not isinstance(lhs, ExprNodes.NameNode):
3330 error(lhs.pos, "Invalid declaration.")
3331 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3333 elif func_name in ['struct', 'union']:
3334 self.declaration_only = True
3335 if len(args) > 0 or kwds is None:
3336 error(rhs.pos, "Struct or union members must be given by name.")
3339 for member, type_node in kwds.key_value_pairs:
3340 type = type_node.analyse_as_type(env)
3342 error(type_node.pos, "Unknown type")
3344 members.append((member.value, type, member.pos))
3345 if len(members) < len(kwds.key_value_pairs):
3347 if not isinstance(self.lhs, ExprNodes.NameNode):
3348 error(self.lhs.pos, "Invalid declaration.")
3349 name = self.lhs.name
3350 scope = StructOrUnionScope(name)
3351 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3352 for member, type, pos in members:
3353 scope.declare_var(member, type, pos)
3355 if self.declaration_only:
3358 self.lhs.analyse_target_declaration(env)
3360 def analyse_types(self, env, use_temp = 0):
3361 self.rhs.analyse_types(env)
3362 self.lhs.analyse_target_types(env)
3363 self.lhs.gil_assignment_check(env)
3364 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3366 self.rhs = self.rhs.coerce_to_temp(env)
3368 def generate_rhs_evaluation_code(self, code):
3369 self.rhs.generate_evaluation_code(code)
3371 def generate_assignment_code(self, code):
3372 self.lhs.generate_assignment_code(self.rhs, code)
3374 def generate_function_definitions(self, env, code):
3375 self.rhs.generate_function_definitions(env, code)
3377 def annotate(self, code):
3378 self.lhs.annotate(code)
3379 self.rhs.annotate(code)
3382 class CascadedAssignmentNode(AssignmentNode):
3383 # An assignment with multiple left hand sides:
3387 # lhs_list [ExprNode] Left hand sides
3388 # rhs ExprNode Right hand sides
3392 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3394 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3395 coerced_rhs_list = None
3397 def analyse_declarations(self, env):
3398 for lhs in self.lhs_list:
3399 lhs.analyse_target_declaration(env)
3401 def analyse_types(self, env, use_temp = 0):
3402 self.rhs.analyse_types(env)
3403 if not self.rhs.is_simple():
3405 self.rhs = self.rhs.coerce_to_temp(env)
3407 self.rhs = self.rhs.coerce_to_simple(env)
3408 from ExprNodes import CloneNode
3409 self.coerced_rhs_list = []
3410 for lhs in self.lhs_list:
3411 lhs.analyse_target_types(env)
3412 lhs.gil_assignment_check(env)
3413 rhs = CloneNode(self.rhs)
3414 rhs = rhs.coerce_to(lhs.type, env)
3415 self.coerced_rhs_list.append(rhs)
3417 def generate_rhs_evaluation_code(self, code):
3418 self.rhs.generate_evaluation_code(code)
3420 def generate_assignment_code(self, code):
3421 for i in range(len(self.lhs_list)):
3422 lhs = self.lhs_list[i]
3423 rhs = self.coerced_rhs_list[i]
3424 rhs.generate_evaluation_code(code)
3425 lhs.generate_assignment_code(rhs, code)
3426 # Assignment has disposed of the cloned RHS
3427 self.rhs.generate_disposal_code(code)
3428 self.rhs.free_temps(code)
3430 def generate_function_definitions(self, env, code):
3431 self.rhs.generate_function_definitions(env, code)
3433 def annotate(self, code):
3434 for i in range(len(self.lhs_list)):
3435 lhs = self.lhs_list[i].annotate(code)
3436 rhs = self.coerced_rhs_list[i].annotate(code)
3437 self.rhs.annotate(code)
3440 class ParallelAssignmentNode(AssignmentNode):
3441 # A combined packing/unpacking assignment:
3445 # This has been rearranged by the parser into
3447 # a = d ; b = e ; c = f
3449 # but we must evaluate all the right hand sides
3450 # before assigning to any of the left hand sides.
3452 # stats [AssignmentNode] The constituent assignments
3454 child_attrs = ["stats"]
3456 def analyse_declarations(self, env):
3457 for stat in self.stats:
3458 stat.analyse_declarations(env)
3460 def analyse_expressions(self, env):
3461 for stat in self.stats:
3462 stat.analyse_types(env, use_temp = 1)
3464 # def analyse_expressions(self, env):
3465 # for stat in self.stats:
3466 # stat.analyse_expressions_1(env, use_temp = 1)
3467 # for stat in self.stats:
3468 # stat.analyse_expressions_2(env)
3470 def generate_execution_code(self, code):
3471 for stat in self.stats:
3472 stat.generate_rhs_evaluation_code(code)
3473 for stat in self.stats:
3474 stat.generate_assignment_code(code)
3476 def generate_function_definitions(self, env, code):
3477 for stat in self.stats:
3478 stat.generate_function_definitions(env, code)
3480 def annotate(self, code):
3481 for stat in self.stats:
3485 class InPlaceAssignmentNode(AssignmentNode):
3486 # An in place arithmetic operand:
3492 # lhs ExprNode Left hand side
3493 # rhs ExprNode Right hand side
3494 # op char one of "+-*/%^&|"
3495 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3497 # This code is a bit tricky because in order to obey Python
3498 # semantics the sub-expressions (e.g. indices) of the lhs must
3499 # not be evaluated twice. So we must re-use the values calculated
3500 # in evaluation phase for the assignment phase as well.
3501 # Fortunately, the type of the lhs node is fairly constrained
3502 # (it must be a NameNode, AttributeNode, or IndexNode).
3504 child_attrs = ["lhs", "rhs"]
3507 def analyse_declarations(self, env):
3508 self.lhs.analyse_target_declaration(env)
3510 def analyse_types(self, env):
3511 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3512 self.rhs.analyse_types(env)
3513 self.lhs.analyse_target_types(env)
3515 if self.lhs.type.is_pyobject:
3516 self.rhs = self.rhs.coerce_to_pyobject(env)
3517 elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3518 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3519 if self.lhs.type.is_pyobject:
3520 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3521 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3523 def generate_execution_code(self, code):
3525 self.rhs.generate_evaluation_code(code)
3526 self.dup.generate_subexpr_evaluation_code(code)
3527 if self.dup.is_temp:
3528 self.dup.allocate_temp_result(code)
3529 # self.dup.generate_result_code is run only if it is not buffer access
3530 if self.operator == "**":
3534 if self.lhs.type.is_pyobject:
3535 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3536 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3537 self.dup.generate_result_code(code)
3538 self.result_value_temp.allocate(code)
3540 "%s = %s(%s, %s%s); %s" % (
3541 self.result_value.result(),
3542 self.py_operation_function(),
3543 self.dup.py_result(),
3544 self.rhs.py_result(),
3546 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3547 code.put_gotref(self.result_value.py_result())
3548 self.result_value.generate_evaluation_code(code) # May be a type check...
3549 self.rhs.generate_disposal_code(code)
3550 self.rhs.free_temps(code)
3551 self.dup.generate_disposal_code(code)
3552 self.dup.free_temps(code)
3553 self.lhs.generate_assignment_code(self.result_value, code)
3554 self.result_value_temp.release(code)
3556 c_op = self.operator
3560 error(self.pos, "No C inplace power operator")
3561 elif self.lhs.type.is_complex:
3562 error(self.pos, "Inplace operators not implemented for complex types.")
3564 # have to do assignment directly to avoid side-effects
3565 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3566 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3568 self.dup.generate_result_code(code)
3569 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3570 self.rhs.generate_disposal_code(code)
3571 self.rhs.free_temps(code)
3572 if self.dup.is_temp:
3573 self.dup.generate_subexpr_disposal_code(code)
3574 self.dup.free_subexpr_temps(code)
3576 def create_dup_node(self, env):
3579 self.dup.analyse_types(env)
3580 if isinstance(self.lhs, ExprNodes.NameNode):
3581 target_lhs = ExprNodes.NameNode(self.dup.pos,
3582 name = self.dup.name,
3583 is_temp = self.dup.is_temp,
3584 entry = self.dup.entry)
3585 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3586 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3587 obj = ExprNodes.CloneNode(self.lhs.obj),
3588 attribute = self.dup.attribute,
3589 is_temp = self.dup.is_temp)
3590 elif isinstance(self.lhs, ExprNodes.IndexNode):
3592 index = ExprNodes.CloneNode(self.lhs.index)
3595 if self.lhs.indices:
3596 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3599 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3600 base = ExprNodes.CloneNode(self.dup.base),
3603 is_temp = self.dup.is_temp)
3605 assert False, "Unsupported node: %s" % type(self.lhs)
3606 self.lhs = target_lhs
3609 def py_operation_function(self):
3610 return self.py_functions[self.operator]
3613 "|": "PyNumber_InPlaceOr",
3614 "^": "PyNumber_InPlaceXor",
3615 "&": "PyNumber_InPlaceAnd",
3616 "+": "PyNumber_InPlaceAdd",
3617 "-": "PyNumber_InPlaceSubtract",
3618 "*": "PyNumber_InPlaceMultiply",
3619 "/": "__Pyx_PyNumber_InPlaceDivide",
3620 "%": "PyNumber_InPlaceRemainder",
3621 "<<": "PyNumber_InPlaceLshift",
3622 ">>": "PyNumber_InPlaceRshift",
3623 "**": "PyNumber_InPlacePower",
3624 "//": "PyNumber_InPlaceFloorDivide",
3627 def annotate(self, code):
3628 self.lhs.annotate(code)
3629 self.rhs.annotate(code)
3630 self.dup.annotate(code)
3632 def create_binop_node(self):
3634 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3637 class PrintStatNode(StatNode):
3640 # arg_tuple TupleNode
3641 # stream ExprNode or None (stdout)
3642 # append_newline boolean
3644 child_attrs = ["arg_tuple", "stream"]
3646 def analyse_expressions(self, env):
3648 self.stream.analyse_expressions(env)
3649 self.stream = self.stream.coerce_to_pyobject(env)
3650 self.arg_tuple.analyse_expressions(env)
3651 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3652 env.use_utility_code(printing_utility_code)
3653 if len(self.arg_tuple.args) == 1 and self.append_newline:
3654 env.use_utility_code(printing_one_utility_code)
3656 nogil_check = Node.gil_error
3657 gil_message = "Python print statement"
3659 def generate_execution_code(self, code):
3661 self.stream.generate_evaluation_code(code)
3662 stream_result = self.stream.py_result()
3665 if len(self.arg_tuple.args) == 1 and self.append_newline:
3666 arg = self.arg_tuple.args[0]
3667 arg.generate_evaluation_code(code)
3670 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3673 code.error_goto(self.pos)))
3674 arg.generate_disposal_code(code)
3675 arg.free_temps(code)
3677 self.arg_tuple.generate_evaluation_code(code)
3679 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3681 self.arg_tuple.py_result(),
3682 self.append_newline,
3683 code.error_goto(self.pos)))
3684 self.arg_tuple.generate_disposal_code(code)
3685 self.arg_tuple.free_temps(code)
3688 self.stream.generate_disposal_code(code)
3689 self.stream.free_temps(code)
3691 def generate_function_definitions(self, env, code):
3693 self.stream.generate_function_definitions(env, code)
3694 self.arg_tuple.generate_function_definitions(env, code)
3696 def annotate(self, code):
3698 self.stream.annotate(code)
3699 self.arg_tuple.annotate(code)
3702 class ExecStatNode(StatNode):
3707 child_attrs = ["args"]
3709 def analyse_expressions(self, env):
3710 for i, arg in enumerate(self.args):
3711 arg.analyse_expressions(env)
3712 arg = arg.coerce_to_pyobject(env)
3714 env.use_utility_code(Builtin.pyexec_utility_code)
3716 nogil_check = Node.gil_error
3717 gil_message = "Python exec statement"
3719 def generate_execution_code(self, code):
3721 for arg in self.args:
3722 arg.generate_evaluation_code(code)
3723 args.append( arg.py_result() )
3724 args = tuple(args + ['0', '0'][:3-len(args)])
3725 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3726 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3727 (temp_result,) + args))
3728 for arg in self.args:
3729 arg.generate_disposal_code(code)
3730 arg.free_temps(code)
3732 code.error_goto_if_null(temp_result, self.pos))
3733 code.put_gotref(temp_result)
3734 code.put_decref_clear(temp_result, py_object_type)
3735 code.funcstate.release_temp(temp_result)
3737 def annotate(self, code):
3738 for arg in self.args:
3742 class DelStatNode(StatNode):
3747 child_attrs = ["args"]
3749 def analyse_declarations(self, env):
3750 for arg in self.args:
3751 arg.analyse_target_declaration(env)
3753 def analyse_expressions(self, env):
3754 for arg in self.args:
3755 arg.analyse_target_expression(env, None)
3756 if arg.type.is_pyobject:
3758 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3760 elif arg.type.is_cpp_class:
3761 error(arg.pos, "Deletion of non-heap C++ object")
3763 error(arg.pos, "Deletion of non-Python, non-C++ object")
3764 #arg.release_target_temp(env)
3766 def nogil_check(self, env):
3767 for arg in self.args:
3768 if arg.type.is_pyobject:
3771 gil_message = "Deleting Python object"
3773 def generate_execution_code(self, code):
3774 for arg in self.args:
3775 if arg.type.is_pyobject:
3776 arg.generate_deletion_code(code)
3777 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3778 arg.generate_result_code(code)
3779 code.putln("delete %s;" % arg.result())
3780 # else error reported earlier
3782 def annotate(self, code):
3783 for arg in self.args:
3787 class PassStatNode(StatNode):
3792 def analyse_expressions(self, env):
3795 def generate_execution_code(self, code):
3799 class BreakStatNode(StatNode):
3803 def analyse_expressions(self, env):
3806 def generate_execution_code(self, code):
3807 if not code.break_label:
3808 error(self.pos, "break statement not inside loop")
3810 code.put_goto(code.break_label)
3813 class ContinueStatNode(StatNode):
3817 def analyse_expressions(self, env):
3820 def generate_execution_code(self, code):
3821 if code.funcstate.in_try_finally:
3822 error(self.pos, "continue statement inside try of try...finally")
3823 elif not code.continue_label:
3824 error(self.pos, "continue statement not inside loop")
3826 code.put_goto(code.continue_label)
3829 class ReturnStatNode(StatNode):
3832 # value ExprNode or None
3833 # return_type PyrexType
3835 child_attrs = ["value"]
3837 def analyse_expressions(self, env):
3838 return_type = env.return_type
3839 self.return_type = return_type
3841 error(self.pos, "Return not inside a function body")
3844 self.value.analyse_types(env)
3845 if return_type.is_void or return_type.is_returncode:
3846 error(self.value.pos,
3847 "Return with value in void function")
3849 self.value = self.value.coerce_to(env.return_type, env)
3851 if (not return_type.is_void
3852 and not return_type.is_pyobject
3853 and not return_type.is_returncode):
3854 error(self.pos, "Return value required")
3856 def nogil_check(self, env):
3857 if self.return_type.is_pyobject:
3860 gil_message = "Returning Python object"
3862 def generate_execution_code(self, code):
3863 code.mark_pos(self.pos)
3864 if not self.return_type:
3865 # error reported earlier
3867 if self.return_type.is_pyobject:
3868 code.put_xdecref(Naming.retval_cname,
3871 self.value.generate_evaluation_code(code)
3872 self.value.make_owned_reference(code)
3875 Naming.retval_cname,
3876 self.value.result_as(self.return_type)))
3877 self.value.generate_post_assignment_code(code)
3878 self.value.free_temps(code)
3880 if self.return_type.is_pyobject:
3881 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3882 elif self.return_type.is_returncode:
3885 Naming.retval_cname,
3886 self.return_type.default_value))
3887 for cname, type in code.funcstate.temps_holding_reference():
3888 code.put_decref_clear(cname, type)
3889 code.put_goto(code.return_label)
3891 def generate_function_definitions(self, env, code):
3892 if self.value is not None:
3893 self.value.generate_function_definitions(env, code)
3895 def annotate(self, code):
3897 self.value.annotate(code)
3900 class RaiseStatNode(StatNode):
3903 # exc_type ExprNode or None
3904 # exc_value ExprNode or None
3905 # exc_tb ExprNode or None
3907 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3909 def analyse_expressions(self, env):
3911 self.exc_type.analyse_types(env)
3912 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3914 self.exc_value.analyse_types(env)
3915 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3917 self.exc_tb.analyse_types(env)
3918 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3919 env.use_utility_code(raise_utility_code)
3921 nogil_check = Node.gil_error
3922 gil_message = "Raising exception"
3924 def generate_execution_code(self, code):
3926 self.exc_type.generate_evaluation_code(code)
3927 type_code = self.exc_type.py_result()
3931 self.exc_value.generate_evaluation_code(code)
3932 value_code = self.exc_value.py_result()
3936 self.exc_tb.generate_evaluation_code(code)
3937 tb_code = self.exc_tb.py_result()
3941 "__Pyx_Raise(%s, %s, %s);" % (
3945 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3947 obj.generate_disposal_code(code)
3948 obj.free_temps(code)
3950 code.error_goto(self.pos))
3952 def generate_function_definitions(self, env, code):
3953 if self.exc_type is not None:
3954 self.exc_type.generate_function_definitions(env, code)
3955 if self.exc_value is not None:
3956 self.exc_value.generate_function_definitions(env, code)
3957 if self.exc_tb is not None:
3958 self.exc_tb.generate_function_definitions(env, code)
3960 def annotate(self, code):
3962 self.exc_type.annotate(code)
3964 self.exc_value.annotate(code)
3966 self.exc_tb.annotate(code)
3969 class ReraiseStatNode(StatNode):
3973 def analyse_expressions(self, env):
3974 env.use_utility_code(restore_exception_utility_code)
3976 nogil_check = Node.gil_error
3977 gil_message = "Raising exception"
3979 def generate_execution_code(self, code):
3980 vars = code.funcstate.exc_vars
3982 for varname in vars:
3983 code.put_giveref(varname)
3984 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3985 for varname in vars:
3986 code.put("%s = 0; " % varname)
3988 code.putln(code.error_goto(self.pos))
3990 error(self.pos, "Reraise not inside except clause")
3993 class AssertStatNode(StatNode):
3997 # value ExprNode or None
3999 child_attrs = ["cond", "value"]
4001 def analyse_expressions(self, env):
4002 self.cond = self.cond.analyse_boolean_expression(env)
4004 self.value.analyse_types(env)
4005 self.value = self.value.coerce_to_pyobject(env)
4007 nogil_check = Node.gil_error
4008 gil_message = "Raising exception"
4010 def generate_execution_code(self, code):
4011 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
4012 self.cond.generate_evaluation_code(code)
4014 "if (unlikely(!%s)) {" %
4017 self.value.generate_evaluation_code(code)
4019 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4020 self.value.py_result())
4021 self.value.generate_disposal_code(code)
4022 self.value.free_temps(code)
4025 "PyErr_SetNone(PyExc_AssertionError);")
4027 code.error_goto(self.pos))
4030 self.cond.generate_disposal_code(code)
4031 self.cond.free_temps(code)
4032 code.putln("#endif")
4034 def generate_function_definitions(self, env, code):
4035 self.cond.generate_function_definitions(env, code)
4036 if self.value is not None:
4037 self.value.generate_function_definitions(env, code)
4039 def annotate(self, code):
4040 self.cond.annotate(code)
4042 self.value.annotate(code)
4045 class IfStatNode(StatNode):
4048 # if_clauses [IfClauseNode]
4049 # else_clause StatNode or None
4051 child_attrs = ["if_clauses", "else_clause"]
4053 def analyse_control_flow(self, env):
4054 env.start_branching(self.pos)
4055 for if_clause in self.if_clauses:
4056 if_clause.analyse_control_flow(env)
4057 env.next_branch(if_clause.end_pos())
4058 if self.else_clause:
4059 self.else_clause.analyse_control_flow(env)
4060 env.finish_branching(self.end_pos())
4062 def analyse_declarations(self, env):
4063 for if_clause in self.if_clauses:
4064 if_clause.analyse_declarations(env)
4065 if self.else_clause:
4066 self.else_clause.analyse_declarations(env)
4068 def analyse_expressions(self, env):
4069 for if_clause in self.if_clauses:
4070 if_clause.analyse_expressions(env)
4071 if self.else_clause:
4072 self.else_clause.analyse_expressions(env)
4074 def generate_execution_code(self, code):
4075 code.mark_pos(self.pos)
4076 end_label = code.new_label()
4077 for if_clause in self.if_clauses:
4078 if_clause.generate_execution_code(code, end_label)
4079 if self.else_clause:
4080 code.putln("/*else*/ {")
4081 self.else_clause.generate_execution_code(code)
4083 code.put_label(end_label)
4085 def generate_function_definitions(self, env, code):
4086 for clause in self.if_clauses:
4087 clause.generate_function_definitions(env, code)
4088 if self.else_clause is not None:
4089 self.else_clause.generate_function_definitions(env, code)
4091 def annotate(self, code):
4092 for if_clause in self.if_clauses:
4093 if_clause.annotate(code)
4094 if self.else_clause:
4095 self.else_clause.annotate(code)
4098 class IfClauseNode(Node):
4099 # if or elif clause in an if statement
4101 # condition ExprNode
4104 child_attrs = ["condition", "body"]
4106 def analyse_control_flow(self, env):
4107 self.body.analyse_control_flow(env)
4109 def analyse_declarations(self, env):
4110 self.condition.analyse_declarations(env)
4111 self.body.analyse_declarations(env)
4113 def analyse_expressions(self, env):
4115 self.condition.analyse_temp_boolean_expression(env)
4116 self.body.analyse_expressions(env)
4118 def get_constant_condition_result(self):
4119 if self.condition.has_constant_result():
4120 return bool(self.condition.constant_result)
4124 def generate_execution_code(self, code, end_label):
4125 self.condition.generate_evaluation_code(code)
4128 self.condition.result())
4129 self.condition.generate_disposal_code(code)
4130 self.condition.free_temps(code)
4131 self.body.generate_execution_code(code)
4132 code.put_goto(end_label)
4135 def generate_function_definitions(self, env, code):
4136 self.condition.generate_function_definitions(env, code)
4137 self.body.generate_function_definitions(env, code)
4139 def annotate(self, code):
4140 self.condition.annotate(code)
4141 self.body.annotate(code)
4144 class SwitchCaseNode(StatNode):
4145 # Generated in the optimization of an if-elif-else node
4147 # conditions [ExprNode]
4150 child_attrs = ['conditions', 'body']
4152 def generate_execution_code(self, code):
4153 for cond in self.conditions:
4154 code.mark_pos(cond.pos)
4155 cond.generate_evaluation_code(code)
4156 code.putln("case %s:" % cond.result())
4157 self.body.generate_execution_code(code)
4158 code.putln("break;")
4160 def generate_function_definitions(self, env, code):
4161 for cond in self.conditions:
4162 cond.generate_function_definitions(env, code)
4163 self.body.generate_function_definitions(env, code)
4165 def annotate(self, code):
4166 for cond in self.conditions:
4168 self.body.annotate(code)
4170 class SwitchStatNode(StatNode):
4171 # Generated in the optimization of an if-elif-else node
4174 # cases [SwitchCaseNode]
4175 # else_clause StatNode or None
4177 child_attrs = ['test', 'cases', 'else_clause']
4179 def generate_execution_code(self, code):
4180 code.putln("switch (%s) {" % self.test.result())
4181 for case in self.cases:
4182 case.generate_execution_code(code)
4183 if self.else_clause is not None:
4184 code.putln("default:")
4185 self.else_clause.generate_execution_code(code)
4186 code.putln("break;")
4189 def generate_function_definitions(self, env, code):
4190 self.test.generate_function_definitions(env, code)
4191 for case in self.cases:
4192 case.generate_function_definitions(env, code)
4193 if self.else_clause is not None:
4194 self.else_clause.generate_function_definitions(env, code)
4196 def annotate(self, code):
4197 self.test.annotate(code)
4198 for case in self.cases:
4200 if self.else_clause is not None:
4201 self.else_clause.annotate(code)
4203 class LoopNode(object):
4205 def analyse_control_flow(self, env):
4206 env.start_branching(self.pos)
4207 self.body.analyse_control_flow(env)
4208 env.next_branch(self.body.end_pos())
4209 if self.else_clause:
4210 self.else_clause.analyse_control_flow(env)
4211 env.finish_branching(self.end_pos())
4214 class WhileStatNode(LoopNode, StatNode):
4217 # condition ExprNode
4219 # else_clause StatNode
4221 child_attrs = ["condition", "body", "else_clause"]
4223 def analyse_declarations(self, env):
4224 self.body.analyse_declarations(env)
4225 if self.else_clause:
4226 self.else_clause.analyse_declarations(env)
4228 def analyse_expressions(self, env):
4230 self.condition.analyse_temp_boolean_expression(env)
4231 self.body.analyse_expressions(env)
4232 if self.else_clause:
4233 self.else_clause.analyse_expressions(env)
4235 def generate_execution_code(self, code):
4236 old_loop_labels = code.new_loop_labels()
4239 self.condition.generate_evaluation_code(code)
4240 self.condition.generate_disposal_code(code)
4243 self.condition.result())
4244 self.condition.free_temps(code)
4245 self.body.generate_execution_code(code)
4246 code.put_label(code.continue_label)
4248 break_label = code.break_label
4249 code.set_loop_labels(old_loop_labels)
4250 if self.else_clause:
4251 code.putln("/*else*/ {")
4252 self.else_clause.generate_execution_code(code)
4254 code.put_label(break_label)
4256 def generate_function_definitions(self, env, code):
4257 self.condition.generate_function_definitions(env, code)
4258 self.body.generate_function_definitions(env, code)
4259 if self.else_clause is not None:
4260 self.else_clause.generate_function_definitions(env, code)
4262 def annotate(self, code):
4263 self.condition.annotate(code)
4264 self.body.annotate(code)
4265 if self.else_clause:
4266 self.else_clause.annotate(code)
4269 def ForStatNode(pos, **kw):
4270 if 'iterator' in kw:
4271 return ForInStatNode(pos, **kw)
4273 return ForFromStatNode(pos, **kw)
4275 class ForInStatNode(LoopNode, StatNode):
4279 # iterator IteratorNode
4281 # else_clause StatNode
4282 # item NextNode used internally
4284 child_attrs = ["target", "iterator", "body", "else_clause"]
4287 def analyse_declarations(self, env):
4288 self.target.analyse_target_declaration(env)
4289 self.body.analyse_declarations(env)
4290 if self.else_clause:
4291 self.else_clause.analyse_declarations(env)
4293 def analyse_expressions(self, env):
4295 self.target.analyse_target_types(env)
4296 self.iterator.analyse_expressions(env)
4297 self.item = ExprNodes.NextNode(self.iterator, env)
4298 if not self.target.type.assignable_from(self.item.type) and \
4299 (self.iterator.sequence.type.is_ptr or self.iterator.sequence.type.is_array):
4300 self.item.type = self.iterator.sequence.type.base_type
4301 self.item = self.item.coerce_to(self.target.type, env)
4302 self.body.analyse_expressions(env)
4303 if self.else_clause:
4304 self.else_clause.analyse_expressions(env)
4306 def generate_execution_code(self, code):
4307 old_loop_labels = code.new_loop_labels()
4308 self.iterator.allocate_counter_temp(code)
4309 self.iterator.generate_evaluation_code(code)
4312 self.item.generate_evaluation_code(code)
4313 self.target.generate_assignment_code(self.item, code)
4314 self.body.generate_execution_code(code)
4315 code.put_label(code.continue_label)
4318 break_label = code.break_label
4319 code.set_loop_labels(old_loop_labels)
4321 if self.else_clause:
4322 # in nested loops, the 'else' block can contain a
4323 # 'continue' statement for the outer loop, but we may need
4324 # to generate cleanup code before taking that path, so we
4326 orig_continue_label = code.continue_label
4327 code.continue_label = code.new_label('outer_continue')
4329 code.putln("/*else*/ {")
4330 self.else_clause.generate_execution_code(code)
4333 if code.label_used(code.continue_label):
4334 code.put_goto(break_label)
4335 code.put_label(code.continue_label)
4336 self.iterator.generate_disposal_code(code)
4337 code.put_goto(orig_continue_label)
4338 code.set_loop_labels(old_loop_labels)
4340 if code.label_used(break_label):
4341 code.put_label(break_label)
4342 self.iterator.release_counter_temp(code)
4343 self.iterator.generate_disposal_code(code)
4344 self.iterator.free_temps(code)
4346 def generate_function_definitions(self, env, code):
4347 self.target.generate_function_definitions(env, code)
4348 self.iterator.generate_function_definitions(env, code)
4349 self.body.generate_function_definitions(env, code)
4350 if self.else_clause is not None:
4351 self.else_clause.generate_function_definitions(env, code)
4353 def annotate(self, code):
4354 self.target.annotate(code)
4355 self.iterator.annotate(code)
4356 self.body.annotate(code)
4357 if self.else_clause:
4358 self.else_clause.annotate(code)
4359 self.item.annotate(code)
4362 class ForFromStatNode(LoopNode, StatNode):
4363 # for name from expr rel name rel expr
4370 # step ExprNode or None
4372 # else_clause StatNode or None
4378 # loopvar_node ExprNode (usually a NameNode or temp node)
4379 # py_loopvar_node PyTempNode or None
4380 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4382 is_py_target = False
4384 py_loopvar_node = None
4387 gil_message = "For-loop using object bounds or target"
4389 def nogil_check(self, env):
4390 for x in (self.target, self.bound1, self.bound2):
4391 if x.type.is_pyobject:
4394 def analyse_declarations(self, env):
4395 self.target.analyse_target_declaration(env)
4396 self.body.analyse_declarations(env)
4397 if self.else_clause:
4398 self.else_clause.analyse_declarations(env)
4400 def analyse_expressions(self, env):
4402 self.target.analyse_target_types(env)
4403 self.bound1.analyse_types(env)
4404 self.bound2.analyse_types(env)
4405 if self.step is not None:
4406 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4407 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4408 self.step.analyse_types(env)
4410 target_type = self.target.type
4411 if self.target.type.is_numeric:
4412 loop_type = self.target.type
4414 loop_type = PyrexTypes.c_int_type
4415 if not self.bound1.type.is_pyobject:
4416 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4417 if not self.bound2.type.is_pyobject:
4418 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4419 if self.step is not None and not self.step.type.is_pyobject:
4420 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4421 self.bound1 = self.bound1.coerce_to(loop_type, env)
4422 self.bound2 = self.bound2.coerce_to(loop_type, env)
4423 if not self.bound2.is_literal:
4424 self.bound2 = self.bound2.coerce_to_temp(env)
4425 if self.step is not None:
4426 self.step = self.step.coerce_to(loop_type, env)
4427 if not self.step.is_literal:
4428 self.step = self.step.coerce_to_temp(env)
4430 target_type = self.target.type
4431 if not (target_type.is_pyobject or target_type.is_numeric):
4432 error(self.target.pos,
4433 "for-from loop variable must be c numeric type or Python object")
4434 if target_type.is_numeric:
4435 self.is_py_target = False
4436 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4437 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4438 self.loopvar_node = self.target
4439 self.py_loopvar_node = None
4441 self.is_py_target = True
4442 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4443 self.loopvar_node = c_loopvar_node
4444 self.py_loopvar_node = \
4445 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4446 self.body.analyse_expressions(env)
4447 if self.else_clause:
4448 self.else_clause.analyse_expressions(env)
4450 def generate_execution_code(self, code):
4451 old_loop_labels = code.new_loop_labels()
4452 from_range = self.from_range
4453 self.bound1.generate_evaluation_code(code)
4454 self.bound2.generate_evaluation_code(code)
4455 offset, incop = self.relation_table[self.relation1]
4456 if self.step is not None:
4457 self.step.generate_evaluation_code(code)
4458 step = self.step.result()
4459 incop = "%s=%s" % (incop[0], step)
4461 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4462 self.loopvar_node.allocate(code)
4463 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4464 self.py_loopvar_node.allocate(code)
4466 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4468 loopvar_name = self.loopvar_node.result()
4470 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4472 self.bound1.result(), offset,
4473 loopvar_name, self.relation2, self.bound2.result(),
4474 loopvar_name, incop))
4475 if self.py_loopvar_node:
4476 self.py_loopvar_node.generate_evaluation_code(code)
4477 self.target.generate_assignment_code(self.py_loopvar_node, code)
4479 code.putln("%s = %s;" % (
4480 self.target.result(), loopvar_name))
4481 self.body.generate_execution_code(code)
4482 code.put_label(code.continue_label)
4483 if self.py_loopvar_node:
4484 # This mess is to make for..from loops with python targets behave
4485 # exactly like those with C targets with regards to re-assignment
4486 # of the loop variable.
4488 if self.target.entry.is_pyglobal:
4489 # We know target is a NameNode, this is the only ugly case.
4490 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4491 target_node.allocate(code)
4492 interned_cname = code.intern_identifier(self.target.entry.name)
4493 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4494 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4495 target_node.result(),
4496 Naming.module_cname,
4498 code.error_goto_if_null(target_node.result(), self.target.pos)))
4499 code.put_gotref(target_node.result())
4501 target_node = self.target
4502 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4503 from_py_node.temp_code = loopvar_name
4504 from_py_node.generate_result_code(code)
4505 if self.target.entry.is_pyglobal:
4506 code.put_decref(target_node.result(), target_node.type)
4507 target_node.release(code)
4509 if self.py_loopvar_node:
4510 # This is potentially wasteful, but we don't want the semantics to
4511 # depend on whether or not the loop is a python type.
4512 self.py_loopvar_node.generate_evaluation_code(code)
4513 self.target.generate_assignment_code(self.py_loopvar_node, code)
4515 code.funcstate.release_temp(loopvar_name)
4516 break_label = code.break_label
4517 code.set_loop_labels(old_loop_labels)
4518 if self.else_clause:
4519 code.putln("/*else*/ {")
4520 self.else_clause.generate_execution_code(code)
4522 code.put_label(break_label)
4523 self.bound1.generate_disposal_code(code)
4524 self.bound1.free_temps(code)
4525 self.bound2.generate_disposal_code(code)
4526 self.bound2.free_temps(code)
4527 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4528 self.loopvar_node.release(code)
4529 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4530 self.py_loopvar_node.release(code)
4531 if self.step is not None:
4532 self.step.generate_disposal_code(code)
4533 self.step.free_temps(code)
4536 # {relop : (initial offset, increment op)}
4543 def generate_function_definitions(self, env, code):
4544 self.target.generate_function_definitions(env, code)
4545 self.bound1.generate_function_definitions(env, code)
4546 self.bound2.generate_function_definitions(env, code)
4547 if self.step is not None:
4548 self.step.generate_function_definitions(env, code)
4549 self.body.generate_function_definitions(env, code)
4550 if self.else_clause is not None:
4551 self.else_clause.generate_function_definitions(env, code)
4553 def annotate(self, code):
4554 self.target.annotate(code)
4555 self.bound1.annotate(code)
4556 self.bound2.annotate(code)
4558 self.step.annotate(code)
4559 self.body.annotate(code)
4560 if self.else_clause:
4561 self.else_clause.annotate(code)
4564 class WithStatNode(StatNode):
4566 Represents a Python with statement.
4568 This is only used at parse tree level; and is not present in
4569 analysis or generation phases.
4571 # manager The with statement manager object
4572 # target Node (lhs expression)
4574 child_attrs = ["manager", "target", "body"]
4576 class TryExceptStatNode(StatNode):
4577 # try .. except statement
4580 # except_clauses [ExceptClauseNode]
4581 # else_clause StatNode or None
4583 child_attrs = ["body", "except_clauses", "else_clause"]
4585 def analyse_control_flow(self, env):
4586 env.start_branching(self.pos)
4587 self.body.analyse_control_flow(env)
4588 successful_try = env.control_flow # grab this for later
4589 env.next_branch(self.body.end_pos())
4590 env.finish_branching(self.body.end_pos())
4592 env.start_branching(self.except_clauses[0].pos)
4593 for except_clause in self.except_clauses:
4594 except_clause.analyse_control_flow(env)
4595 env.next_branch(except_clause.end_pos())
4597 # the else cause it executed only when the try clause finishes
4598 env.control_flow.incoming = successful_try
4599 if self.else_clause:
4600 self.else_clause.analyse_control_flow(env)
4601 env.finish_branching(self.end_pos())
4603 def analyse_declarations(self, env):
4604 self.body.analyse_declarations(env)
4605 for except_clause in self.except_clauses:
4606 except_clause.analyse_declarations(env)
4607 if self.else_clause:
4608 self.else_clause.analyse_declarations(env)
4609 env.use_utility_code(reset_exception_utility_code)
4611 def analyse_expressions(self, env):
4612 self.body.analyse_expressions(env)
4613 default_clause_seen = 0
4614 for except_clause in self.except_clauses:
4615 except_clause.analyse_expressions(env)
4616 if default_clause_seen:
4617 error(except_clause.pos, "default 'except:' must be last")
4618 if not except_clause.pattern:
4619 default_clause_seen = 1
4620 self.has_default_clause = default_clause_seen
4621 if self.else_clause:
4622 self.else_clause.analyse_expressions(env)
4624 nogil_check = Node.gil_error
4625 gil_message = "Try-except statement"
4627 def generate_execution_code(self, code):
4628 old_return_label = code.return_label
4629 old_break_label = code.break_label
4630 old_continue_label = code.continue_label
4631 old_error_label = code.new_error_label()
4632 our_error_label = code.error_label
4633 except_end_label = code.new_label('exception_handled')
4634 except_error_label = code.new_label('except_error')
4635 except_return_label = code.new_label('except_return')
4636 try_return_label = code.new_label('try_return')
4637 try_break_label = code.new_label('try_break')
4638 try_continue_label = code.new_label('try_continue')
4639 try_end_label = code.new_label('try_end')
4642 code.putln("PyObject %s;" %
4643 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4644 code.putln("__Pyx_ExceptionSave(%s);" %
4645 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4646 for var in Naming.exc_save_vars:
4647 code.put_xgotref(var)
4650 code.return_label = try_return_label
4651 code.break_label = try_break_label
4652 code.continue_label = try_continue_label
4653 self.body.generate_execution_code(code)
4656 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4657 code.error_label = except_error_label
4658 code.return_label = except_return_label
4659 if self.else_clause:
4662 self.else_clause.generate_execution_code(code)
4665 for var in Naming.exc_save_vars:
4666 code.put_xdecref_clear(var, py_object_type)
4667 code.put_goto(try_end_label)
4668 if code.label_used(try_return_label):
4669 code.put_label(try_return_label)
4670 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4671 code.putln("__Pyx_ExceptionReset(%s);" %
4672 ', '.join(Naming.exc_save_vars))
4673 code.put_goto(old_return_label)
4674 code.put_label(our_error_label)
4675 for temp_name, type in temps_to_clean_up:
4676 code.put_xdecref_clear(temp_name, type)
4677 for except_clause in self.except_clauses:
4678 except_clause.generate_handling_code(code, except_end_label)
4680 error_label_used = code.label_used(except_error_label)
4681 if error_label_used or not self.has_default_clause:
4682 if error_label_used:
4683 code.put_label(except_error_label)
4684 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4685 code.putln("__Pyx_ExceptionReset(%s);" %
4686 ', '.join(Naming.exc_save_vars))
4687 code.put_goto(old_error_label)
4689 for exit_label, old_label in zip(
4690 [try_break_label, try_continue_label, except_return_label],
4691 [old_break_label, old_continue_label, old_return_label]):
4693 if code.label_used(exit_label):
4694 code.put_label(exit_label)
4695 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4696 code.putln("__Pyx_ExceptionReset(%s);" %
4697 ', '.join(Naming.exc_save_vars))
4698 code.put_goto(old_label)
4700 if code.label_used(except_end_label):
4701 code.put_label(except_end_label)
4702 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4703 code.putln("__Pyx_ExceptionReset(%s);" %
4704 ', '.join(Naming.exc_save_vars))
4705 code.put_label(try_end_label)
4708 code.return_label = old_return_label
4709 code.break_label = old_break_label
4710 code.continue_label = old_continue_label
4711 code.error_label = old_error_label
4713 def generate_function_definitions(self, env, code):
4714 self.body.generate_function_definitions(env, code)
4715 for except_clause in self.except_clauses:
4716 except_clause.generate_function_definitions(env, code)
4717 if self.else_clause is not None:
4718 self.else_clause.generate_function_definitions(env, code)
4720 def annotate(self, code):
4721 self.body.annotate(code)
4722 for except_node in self.except_clauses:
4723 except_node.annotate(code)
4724 if self.else_clause:
4725 self.else_clause.annotate(code)
4728 class ExceptClauseNode(Node):
4729 # Part of try ... except statement.
4731 # pattern [ExprNode]
4732 # target ExprNode or None
4734 # excinfo_target NameNode or None optional target for exception info
4735 # match_flag string result of exception match
4736 # exc_value ExcValueNode used internally
4737 # function_name string qualified name of enclosing function
4738 # exc_vars (string * 3) local exception variables
4740 # excinfo_target is never set by the parser, but can be set by a transform
4741 # in order to extract more extensive information about the exception as a
4742 # sys.exc_info()-style tuple into a target variable
4744 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4747 excinfo_target = None
4749 def analyse_declarations(self, env):
4751 self.target.analyse_target_declaration(env)
4752 if self.excinfo_target is not None:
4753 self.excinfo_target.analyse_target_declaration(env)
4754 self.body.analyse_declarations(env)
4756 def analyse_expressions(self, env):
4758 genv = env.global_scope()
4759 self.function_name = env.qualified_name
4761 # normalise/unpack self.pattern into a list
4762 for i, pattern in enumerate(self.pattern):
4763 pattern.analyse_expressions(env)
4764 self.pattern[i] = pattern.coerce_to_pyobject(env)
4767 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4768 self.target.analyse_target_expression(env, self.exc_value)
4769 if self.excinfo_target is not None:
4771 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4772 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4773 self.excinfo_tuple.analyse_expressions(env)
4774 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4776 self.body.analyse_expressions(env)
4778 def generate_handling_code(self, code, end_label):
4779 code.mark_pos(self.pos)
4782 for pattern in self.pattern:
4783 pattern.generate_evaluation_code(code)
4784 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4786 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4788 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4789 for pattern in self.pattern:
4790 pattern.generate_disposal_code(code)
4791 pattern.free_temps(code)
4795 code.funcstate.release_temp(match_flag)
4797 code.putln("/*except:*/ {")
4799 if not getattr(self.body, 'stats', True) and \
4800 self.excinfo_target is None and self.target is None:
4801 # most simple case: no exception variable, empty body (pass)
4802 # => reset the exception state, done
4803 code.putln("PyErr_Restore(0,0,0);")
4804 code.put_goto(end_label)
4808 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4811 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4812 # We always have to fetch the exception value even if
4813 # there is no target, because this also normalises the
4814 # exception and stores it in the thread state.
4815 code.globalstate.use_utility_code(get_exception_utility_code)
4816 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4817 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4818 code.error_goto(self.pos)))
4822 self.exc_value.set_var(exc_vars[1])
4823 self.exc_value.generate_evaluation_code(code)
4824 self.target.generate_assignment_code(self.exc_value, code)
4825 if self.excinfo_target is not None:
4826 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4827 node.set_var(tempvar)
4828 self.excinfo_tuple.generate_evaluation_code(code)
4829 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4831 old_break_label, old_continue_label = code.break_label, code.continue_label
4832 code.break_label = code.new_label('except_break')
4833 code.continue_label = code.new_label('except_continue')
4835 old_exc_vars = code.funcstate.exc_vars
4836 code.funcstate.exc_vars = exc_vars
4837 self.body.generate_execution_code(code)
4838 code.funcstate.exc_vars = old_exc_vars
4839 for var in exc_vars:
4840 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4841 code.put_goto(end_label)
4843 if code.label_used(code.break_label):
4844 code.put_label(code.break_label)
4845 for var in exc_vars:
4846 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4847 code.put_goto(old_break_label)
4848 code.break_label = old_break_label
4850 if code.label_used(code.continue_label):
4851 code.put_label(code.continue_label)
4852 for var in exc_vars:
4853 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4854 code.put_goto(old_continue_label)
4855 code.continue_label = old_continue_label
4857 for temp in exc_vars:
4858 code.funcstate.release_temp(temp)
4863 def generate_function_definitions(self, env, code):
4864 if self.target is not None:
4865 self.target.generate_function_definitions(env, code)
4866 self.body.generate_function_definitions(env, code)
4868 def annotate(self, code):
4870 for pattern in self.pattern:
4871 pattern.annotate(code)
4873 self.target.annotate(code)
4874 self.body.annotate(code)
4877 class TryFinallyStatNode(StatNode):
4878 # try ... finally statement
4881 # finally_clause StatNode
4883 # The plan is that we funnel all continue, break
4884 # return and error gotos into the beginning of the
4885 # finally block, setting a variable to remember which
4886 # one we're doing. At the end of the finally block, we
4887 # switch on the variable to figure out where to go.
4888 # In addition, if we're doing an error, we save the
4889 # exception on entry to the finally block and restore
4892 child_attrs = ["body", "finally_clause"]
4894 preserve_exception = 1
4896 disallow_continue_in_try_finally = 0
4897 # There doesn't seem to be any point in disallowing
4898 # continue in the try block, since we have no problem
4901 def create_analysed(pos, env, body, finally_clause):
4902 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4904 create_analysed = staticmethod(create_analysed)
4906 def analyse_control_flow(self, env):
4907 env.start_branching(self.pos)
4908 self.body.analyse_control_flow(env)
4909 env.next_branch(self.body.end_pos())
4910 env.finish_branching(self.body.end_pos())
4911 self.finally_clause.analyse_control_flow(env)
4913 def analyse_declarations(self, env):
4914 self.body.analyse_declarations(env)
4915 self.finally_clause.analyse_declarations(env)
4917 def analyse_expressions(self, env):
4918 self.body.analyse_expressions(env)
4919 self.finally_clause.analyse_expressions(env)
4921 nogil_check = Node.gil_error
4922 gil_message = "Try-finally statement"
4924 def generate_execution_code(self, code):
4925 old_error_label = code.error_label
4926 old_labels = code.all_new_labels()
4927 new_labels = code.get_all_labels()
4928 new_error_label = code.error_label
4929 catch_label = code.new_label()
4932 if self.disallow_continue_in_try_finally:
4933 was_in_try_finally = code.funcstate.in_try_finally
4934 code.funcstate.in_try_finally = 1
4935 self.body.generate_execution_code(code)
4936 if self.disallow_continue_in_try_finally:
4937 code.funcstate.in_try_finally = was_in_try_finally
4940 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4941 code.mark_pos(self.finally_clause.pos)
4945 error_label_used = 0
4946 for i, new_label in enumerate(new_labels):
4947 if new_label in code.labels_used:
4948 cases_used.append(i)
4949 if new_label == new_error_label:
4950 error_label_used = 1
4951 error_label_case = i
4955 if error_label_used and self.preserve_exception:
4957 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4959 "int %s;" % Naming.exc_lineno_name)
4960 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4961 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4962 code.putln(exc_var_init_zero)
4964 exc_var_init_zero = None
4965 code.use_label(catch_label)
4967 "__pyx_why = 0; goto %s;" % catch_label)
4968 for i in cases_used:
4969 new_label = new_labels[i]
4970 #if new_label and new_label != "<try>":
4971 if new_label == new_error_label and self.preserve_exception:
4972 self.put_error_catcher(code,
4973 new_error_label, i+1, catch_label, temps_to_clean_up)
4975 code.put('%s: ' % new_label)
4976 if exc_var_init_zero:
4977 code.putln(exc_var_init_zero)
4978 code.putln("__pyx_why = %s; goto %s;" % (
4981 code.put_label(catch_label)
4982 code.set_all_labels(old_labels)
4983 if error_label_used:
4984 code.new_error_label()
4985 finally_error_label = code.error_label
4986 self.finally_clause.generate_execution_code(code)
4987 if error_label_used:
4988 if finally_error_label in code.labels_used and self.preserve_exception:
4989 over_label = code.new_label()
4990 code.put_goto(over_label);
4991 code.put_label(finally_error_label)
4992 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
4993 for var in Naming.exc_vars:
4994 code.putln("Py_XDECREF(%s);" % var)
4996 code.put_goto(old_error_label)
4997 code.put_label(over_label)
4998 code.error_label = old_error_label
5001 "switch (__pyx_why) {")
5002 for i in cases_used:
5003 old_label = old_labels[i]
5004 if old_label == old_error_label and self.preserve_exception:
5005 self.put_error_uncatcher(code, i+1, old_error_label)
5007 code.use_label(old_label)
5009 "case %s: goto %s;" % (
5017 def generate_function_definitions(self, env, code):
5018 self.body.generate_function_definitions(env, code)
5019 self.finally_clause.generate_function_definitions(env, code)
5021 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5022 code.globalstate.use_utility_code(restore_exception_utility_code)
5029 for temp_name, type in temps_to_clean_up:
5030 code.put_xdecref_clear(temp_name, type)
5032 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5036 Naming.exc_lineno_name, Naming.lineno_cname))
5037 code.put_goto(catch_label)
5040 def put_error_uncatcher(self, code, i, error_label):
5041 code.globalstate.use_utility_code(restore_exception_utility_code)
5046 "__Pyx_ErrRestore(%s, %s, %s);" %
5050 Naming.lineno_cname, Naming.exc_lineno_name))
5051 for var in Naming.exc_vars:
5055 code.put_goto(error_label)
5059 def annotate(self, code):
5060 self.body.annotate(code)
5061 self.finally_clause.annotate(code)
5064 class GILStatNode(TryFinallyStatNode):
5065 # 'with gil' or 'with nogil' statement
5067 # state string 'gil' or 'nogil'
5071 preserve_exception = 0
5073 def __init__(self, pos, state, body):
5075 TryFinallyStatNode.__init__(self, pos,
5077 finally_clause = GILExitNode(pos, state = state))
5079 def analyse_expressions(self, env):
5080 env.use_utility_code(force_init_threads_utility_code)
5081 was_nogil = env.nogil
5083 TryFinallyStatNode.analyse_expressions(self, env)
5084 env.nogil = was_nogil
5088 def generate_execution_code(self, code):
5089 code.mark_pos(self.pos)
5090 if self.state == 'gil':
5091 code.putln("{ PyGILState_STATE _save = PyGILState_Ensure();")
5093 code.putln("{ PyThreadState *_save;")
5094 code.putln("Py_UNBLOCK_THREADS")
5095 TryFinallyStatNode.generate_execution_code(self, code)
5099 class GILExitNode(StatNode):
5100 # Used as the 'finally' block in a GILStatNode
5102 # state string 'gil' or 'nogil'
5106 def analyse_expressions(self, env):
5109 def generate_execution_code(self, code):
5110 if self.state == 'gil':
5111 code.putln("PyGILState_Release();")
5113 code.putln("Py_BLOCK_THREADS")
5116 class CImportStatNode(StatNode):
5119 # module_name string Qualified name of module being imported
5120 # as_name string or None Name specified in "as" clause, if any
5124 def analyse_declarations(self, env):
5125 if not env.is_module_scope:
5126 error(self.pos, "cimport only allowed at module level")
5128 module_scope = env.find_module(self.module_name, self.pos)
5129 if "." in self.module_name:
5130 names = [EncodedString(name) for name in self.module_name.split(".")]
5132 top_module_scope = env.context.find_submodule(top_name)
5133 module_scope = top_module_scope
5134 for name in names[1:]:
5135 submodule_scope = module_scope.find_submodule(name)
5136 module_scope.declare_module(name, submodule_scope, self.pos)
5137 module_scope = submodule_scope
5139 env.declare_module(self.as_name, module_scope, self.pos)
5141 env.declare_module(top_name, top_module_scope, self.pos)
5143 name = self.as_name or self.module_name
5144 env.declare_module(name, module_scope, self.pos)
5146 def analyse_expressions(self, env):
5149 def generate_execution_code(self, code):
5153 class FromCImportStatNode(StatNode):
5154 # from ... cimport statement
5156 # module_name string Qualified name of module
5157 # imported_names [(pos, name, as_name, kind)] Names to be imported
5161 def analyse_declarations(self, env):
5162 if not env.is_module_scope:
5163 error(self.pos, "cimport only allowed at module level")
5165 module_scope = env.find_module(self.module_name, self.pos)
5166 env.add_imported_module(module_scope)
5167 for pos, name, as_name, kind in self.imported_names:
5169 for local_name, entry in module_scope.entries.items():
5170 env.add_imported_entry(local_name, entry, pos)
5172 entry = module_scope.lookup(name)
5174 if kind and not self.declaration_matches(entry, kind):
5175 entry.redeclared(pos)
5177 if kind == 'struct' or kind == 'union':
5178 entry = module_scope.declare_struct_or_union(name,
5179 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5180 elif kind == 'class':
5181 entry = module_scope.declare_c_class(name, pos = pos,
5182 module_name = self.module_name)
5184 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5185 if submodule_scope.parent_module is module_scope:
5186 env.declare_module(as_name or name, submodule_scope, self.pos)
5188 error(pos, "Name '%s' not declared in module '%s'"
5189 % (name, self.module_name))
5192 local_name = as_name or name
5193 env.add_imported_entry(local_name, entry, pos)
5195 def declaration_matches(self, entry, kind):
5196 if not entry.is_type:
5200 if not type.is_extension_type:
5203 if not type.is_struct_or_union:
5205 if kind != type.kind:
5209 def analyse_expressions(self, env):
5212 def generate_execution_code(self, code):
5216 class FromImportStatNode(StatNode):
5217 # from ... import statement
5220 # items [(string, NameNode)]
5221 # interned_items [(string, NameNode, ExprNode)]
5222 # item PyTempNode used internally
5223 # import_star boolean used internally
5225 child_attrs = ["module"]
5228 def analyse_declarations(self, env):
5229 for name, target in self.items:
5231 if not env.is_module_scope:
5232 error(self.pos, "import * only allowed at module level")
5234 env.has_import_star = 1
5235 self.import_star = 1
5237 target.analyse_target_declaration(env)
5239 def analyse_expressions(self, env):
5241 self.module.analyse_expressions(env)
5242 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5243 self.interned_items = []
5244 for name, target in self.items:
5246 for _, entry in env.entries.items():
5247 if not entry.is_type and entry.type.is_extension_type:
5248 env.use_utility_code(ExprNodes.type_test_utility_code)
5251 entry = env.lookup(target.name)
5252 # check whether or not entry is already cimported
5253 if (entry.is_type and entry.type.name == name
5254 and hasattr(entry.type, 'module_name')):
5255 if entry.type.module_name == self.module.module_name.value:
5256 # cimported with absolute name
5259 # cimported with relative name
5260 module = env.find_module(self.module.module_name.value,
5262 if entry.type.module_name == module.qualified_name:
5264 except AttributeError:
5266 target.analyse_target_expression(env, None)
5267 if target.type is py_object_type:
5270 coerced_item = self.item.coerce_to(target.type, env)
5271 self.interned_items.append((name, target, coerced_item))
5273 def generate_execution_code(self, code):
5274 self.module.generate_evaluation_code(code)
5275 if self.import_star:
5277 'if (%s(%s) < 0) %s;' % (
5279 self.module.py_result(),
5280 code.error_goto(self.pos)))
5281 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5282 self.item.set_cname(item_temp)
5283 for name, target, coerced_item in self.interned_items:
5284 cname = code.intern_identifier(name)
5286 '%s = PyObject_GetAttr(%s, %s); %s' % (
5288 self.module.py_result(),
5290 code.error_goto_if_null(item_temp, self.pos)))
5291 code.put_gotref(item_temp)
5292 if coerced_item is None:
5293 target.generate_assignment_code(self.item, code)
5295 coerced_item.allocate_temp_result(code)
5296 coerced_item.generate_result_code(code)
5297 target.generate_assignment_code(coerced_item, code)
5298 code.put_decref_clear(item_temp, py_object_type)
5299 code.funcstate.release_temp(item_temp)
5300 self.module.generate_disposal_code(code)
5301 self.module.free_temps(code)
5305 #------------------------------------------------------------------------------------
5307 # Runtime support code
5309 #------------------------------------------------------------------------------------
5311 utility_function_predeclarations = \
5313 /* inline attribute */
5314 #ifndef CYTHON_INLINE
5315 #if defined(__GNUC__)
5316 #define CYTHON_INLINE __inline__
5317 #elif defined(_MSC_VER)
5318 #define CYTHON_INLINE __inline
5319 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5320 #define CYTHON_INLINE inline
5322 #define CYTHON_INLINE
5326 /* unused attribute */
5327 #ifndef CYTHON_UNUSED
5328 # if defined(__GNUC__)
5329 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5330 # define CYTHON_UNUSED __attribute__ ((__unused__))
5332 # define CYTHON_UNUSED
5334 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5335 # define CYTHON_UNUSED __attribute__ ((__unused__))
5337 # define CYTHON_UNUSED
5341 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*/
5345 if Options.gcc_branch_hints:
5346 branch_prediction_macros = \
5349 /* Test for GCC > 2.95 */
5350 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5351 #define likely(x) __builtin_expect(!!(x), 1)
5352 #define unlikely(x) __builtin_expect(!!(x), 0)
5353 #else /* __GNUC__ > 2 ... */
5354 #define likely(x) (x)
5355 #define unlikely(x) (x)
5356 #endif /* __GNUC__ > 2 ... */
5357 #else /* __GNUC__ */
5358 #define likely(x) (x)
5359 #define unlikely(x) (x)
5360 #endif /* __GNUC__ */
5363 branch_prediction_macros = \
5365 #define likely(x) (x)
5366 #define unlikely(x) (x)
5369 #get_name_predeclaration = \
5370 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5372 #get_name_interned_predeclaration = \
5373 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5375 #------------------------------------------------------------------------------------
5377 printing_utility_code = UtilityCode(
5379 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5380 #if PY_MAJOR_VERSION >= 3
5381 static PyObject* %s = 0;
5382 static PyObject* %s = 0;
5384 """ % (Naming.print_function, Naming.print_function_kwargs),
5386 #if PY_MAJOR_VERSION >= 3
5390 """ % (Naming.print_function, Naming.print_function_kwargs),
5392 #if PY_MAJOR_VERSION < 3
5393 static PyObject *__Pyx_GetStdout(void) {
5394 PyObject *f = PySys_GetObject((char *)"stdout");
5396 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5401 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5406 if (!(f = __Pyx_GetStdout()))
5409 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5410 if (PyFile_SoftSpace(f, 1)) {
5411 if (PyFile_WriteString(" ", f) < 0)
5414 v = PyTuple_GET_ITEM(arg_tuple, i);
5415 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5417 if (PyString_Check(v)) {
5418 char *s = PyString_AsString(v);
5419 Py_ssize_t len = PyString_Size(v);
5421 isspace(Py_CHARMASK(s[len-1])) &&
5423 PyFile_SoftSpace(f, 0);
5427 if (PyFile_WriteString("\n", f) < 0)
5429 PyFile_SoftSpace(f, 0);
5434 #else /* Python 3 has a print function */
5436 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5437 PyObject* kwargs = 0;
5438 PyObject* result = 0;
5439 PyObject* end_string;
5440 if (unlikely(!%(PRINT_FUNCTION)s)) {
5441 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5442 if (!%(PRINT_FUNCTION)s)
5446 kwargs = PyDict_New();
5447 if (unlikely(!kwargs))
5449 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5452 end_string = PyUnicode_FromStringAndSize(" ", 1);
5453 if (unlikely(!end_string))
5455 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5456 Py_DECREF(end_string);
5459 Py_DECREF(end_string);
5461 } else if (!newline) {
5462 if (unlikely(!%(PRINT_KWARGS)s)) {
5463 %(PRINT_KWARGS)s = PyDict_New();
5464 if (unlikely(!%(PRINT_KWARGS)s))
5466 end_string = PyUnicode_FromStringAndSize(" ", 1);
5467 if (unlikely(!end_string))
5469 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5470 Py_DECREF(end_string);
5473 Py_DECREF(end_string);
5475 kwargs = %(PRINT_KWARGS)s;
5477 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5478 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5485 if (kwargs != %(PRINT_KWARGS)s)
5491 """ % {'BUILTINS' : Naming.builtins_cname,
5492 'PRINT_FUNCTION' : Naming.print_function,
5493 'PRINT_KWARGS' : Naming.print_function_kwargs}
5497 printing_one_utility_code = UtilityCode(
5499 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5502 #if PY_MAJOR_VERSION < 3
5504 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5506 if (!(f = __Pyx_GetStdout()))
5509 if (PyFile_SoftSpace(f, 0)) {
5510 if (PyFile_WriteString(" ", f) < 0)
5513 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5515 if (PyFile_WriteString("\n", f) < 0)
5518 /* the line below is just to avoid compiler
5519 * compiler warnings about unused functions */
5520 return __Pyx_Print(f, NULL, 0);
5523 #else /* Python 3 has a print function */
5525 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5527 PyObject* arg_tuple = PyTuple_New(1);
5528 if (unlikely(!arg_tuple))
5531 PyTuple_SET_ITEM(arg_tuple, 0, o);
5532 res = __Pyx_Print(stream, arg_tuple, 1);
5533 Py_DECREF(arg_tuple);
5539 requires=[printing_utility_code])
5543 #------------------------------------------------------------------------------------
5545 # Exception raising code
5547 # Exceptions are raised by __Pyx_Raise() and stored as plain
5548 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5549 # 'except' statement, curexc_* is moved over to exc_* by
5550 # __Pyx_GetException()
5552 restore_exception_utility_code = UtilityCode(
5554 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5555 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5558 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5559 PyObject *tmp_type, *tmp_value, *tmp_tb;
5560 PyThreadState *tstate = PyThreadState_GET();
5562 tmp_type = tstate->curexc_type;
5563 tmp_value = tstate->curexc_value;
5564 tmp_tb = tstate->curexc_traceback;
5565 tstate->curexc_type = type;
5566 tstate->curexc_value = value;
5567 tstate->curexc_traceback = tb;
5568 Py_XDECREF(tmp_type);
5569 Py_XDECREF(tmp_value);
5573 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5574 PyThreadState *tstate = PyThreadState_GET();
5575 *type = tstate->curexc_type;
5576 *value = tstate->curexc_value;
5577 *tb = tstate->curexc_traceback;
5579 tstate->curexc_type = 0;
5580 tstate->curexc_value = 0;
5581 tstate->curexc_traceback = 0;
5586 # The following function is based on do_raise() from ceval.c. There
5587 # are separate versions for Python2 and Python3 as exception handling
5588 # has changed quite a lot between the two versions.
5590 raise_utility_code = UtilityCode(
5592 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5595 #if PY_MAJOR_VERSION < 3
5596 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5600 /* First, check the traceback argument, replacing None with NULL. */
5601 if (tb == Py_None) {
5605 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5606 PyErr_SetString(PyExc_TypeError,
5607 "raise: arg 3 must be a traceback or None");
5610 /* Next, replace a missing value with None */
5611 if (value == NULL) {
5615 #if PY_VERSION_HEX < 0x02050000
5616 if (!PyClass_Check(type))
5618 if (!PyType_Check(type))
5621 /* Raising an instance. The value should be a dummy. */
5622 if (value != Py_None) {
5623 PyErr_SetString(PyExc_TypeError,
5624 "instance exception may not have a separate value");
5627 /* Normalize to raise <class>, <instance> */
5630 #if PY_VERSION_HEX < 0x02050000
5631 if (PyInstance_Check(type)) {
5632 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5637 PyErr_SetString(PyExc_TypeError,
5638 "raise: exception must be an old-style class or instance");
5642 type = (PyObject*) Py_TYPE(type);
5644 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5645 PyErr_SetString(PyExc_TypeError,
5646 "raise: exception class must be a subclass of BaseException");
5652 __Pyx_ErrRestore(type, value, tb);
5661 #else /* Python 3+ */
5663 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5664 if (tb == Py_None) {
5666 } else if (tb && !PyTraceBack_Check(tb)) {
5667 PyErr_SetString(PyExc_TypeError,
5668 "raise: arg 3 must be a traceback or None");
5671 if (value == Py_None)
5674 if (PyExceptionInstance_Check(type)) {
5676 PyErr_SetString(PyExc_TypeError,
5677 "instance exception may not have a separate value");
5681 type = (PyObject*) Py_TYPE(value);
5682 } else if (!PyExceptionClass_Check(type)) {
5683 PyErr_SetString(PyExc_TypeError,
5684 "raise: exception class must be a subclass of BaseException");
5688 PyErr_SetObject(type, value);
5691 PyThreadState *tstate = PyThreadState_GET();
5692 PyObject* tmp_tb = tstate->curexc_traceback;
5695 tstate->curexc_traceback = tb;
5705 requires=[restore_exception_utility_code])
5707 #------------------------------------------------------------------------------------
5709 get_exception_utility_code = UtilityCode(
5711 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5714 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5715 PyObject *local_type, *local_value, *local_tb;
5716 PyObject *tmp_type, *tmp_value, *tmp_tb;
5717 PyThreadState *tstate = PyThreadState_GET();
5718 local_type = tstate->curexc_type;
5719 local_value = tstate->curexc_value;
5720 local_tb = tstate->curexc_traceback;
5721 tstate->curexc_type = 0;
5722 tstate->curexc_value = 0;
5723 tstate->curexc_traceback = 0;
5724 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5725 if (unlikely(tstate->curexc_type))
5727 #if PY_MAJOR_VERSION >= 3
5728 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5732 *value = local_value;
5734 Py_INCREF(local_type);
5735 Py_INCREF(local_value);
5736 Py_INCREF(local_tb);
5737 tmp_type = tstate->exc_type;
5738 tmp_value = tstate->exc_value;
5739 tmp_tb = tstate->exc_traceback;
5740 tstate->exc_type = local_type;
5741 tstate->exc_value = local_value;
5742 tstate->exc_traceback = local_tb;
5743 /* Make sure tstate is in a consistent state when we XDECREF
5744 these objects (XDECREF may run arbitrary code). */
5745 Py_XDECREF(tmp_type);
5746 Py_XDECREF(tmp_value);
5753 Py_XDECREF(local_type);
5754 Py_XDECREF(local_value);
5755 Py_XDECREF(local_tb);
5761 #------------------------------------------------------------------------------------
5763 get_exception_tuple_utility_code = UtilityCode(proto="""
5764 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5766 # I doubt that calling __Pyx_GetException() here is correct as it moves
5767 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5768 # exception handlers later on from receiving it.
5770 static PyObject *__Pyx_GetExceptionTuple(void) {
5771 PyObject *type = NULL, *value = NULL, *tb = NULL;
5772 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5773 PyObject* exc_info = PyTuple_New(3);
5778 PyTuple_SET_ITEM(exc_info, 0, type);
5779 PyTuple_SET_ITEM(exc_info, 1, value);
5780 PyTuple_SET_ITEM(exc_info, 2, tb);
5787 requires=[get_exception_utility_code])
5789 #------------------------------------------------------------------------------------
5791 reset_exception_utility_code = UtilityCode(
5793 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5794 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5797 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5798 PyThreadState *tstate = PyThreadState_GET();
5799 *type = tstate->exc_type;
5800 *value = tstate->exc_value;
5801 *tb = tstate->exc_traceback;
5807 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5808 PyObject *tmp_type, *tmp_value, *tmp_tb;
5809 PyThreadState *tstate = PyThreadState_GET();
5810 tmp_type = tstate->exc_type;
5811 tmp_value = tstate->exc_value;
5812 tmp_tb = tstate->exc_traceback;
5813 tstate->exc_type = type;
5814 tstate->exc_value = value;
5815 tstate->exc_traceback = tb;
5816 Py_XDECREF(tmp_type);
5817 Py_XDECREF(tmp_value);
5822 #------------------------------------------------------------------------------------
5824 arg_type_test_utility_code = UtilityCode(
5826 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5827 const char *name, int exact); /*proto*/
5830 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5831 const char *name, int exact)
5834 PyErr_Format(PyExc_SystemError, "Missing type object");
5837 if (none_allowed && obj == Py_None) return 1;
5839 if (Py_TYPE(obj) == type) return 1;
5842 if (PyObject_TypeCheck(obj, type)) return 1;
5844 PyErr_Format(PyExc_TypeError,
5845 "Argument '%s' has incorrect type (expected %s, got %s)",
5846 name, type->tp_name, Py_TYPE(obj)->tp_name);
5851 #------------------------------------------------------------------------------------
5853 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5854 # many or too few positional arguments were found. This handles
5855 # Py_ssize_t formatting correctly.
5857 raise_argtuple_invalid_utility_code = UtilityCode(
5859 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5860 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5863 static void __Pyx_RaiseArgtupleInvalid(
5864 const char* func_name,
5868 Py_ssize_t num_found)
5870 Py_ssize_t num_expected;
5871 const char *number, *more_or_less;
5873 if (num_found < num_min) {
5874 num_expected = num_min;
5875 more_or_less = "at least";
5877 num_expected = num_max;
5878 more_or_less = "at most";
5881 more_or_less = "exactly";
5883 number = (num_expected == 1) ? "" : "s";
5884 PyErr_Format(PyExc_TypeError,
5885 #if PY_VERSION_HEX < 0x02050000
5886 "%s() takes %s %d positional argument%s (%d given)",
5888 "%s() takes %s %zd positional argument%s (%zd given)",
5890 func_name, more_or_less, num_expected, number, num_found);
5894 raise_keyword_required_utility_code = UtilityCode(
5896 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5899 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5900 const char* func_name,
5903 PyErr_Format(PyExc_TypeError,
5904 #if PY_MAJOR_VERSION >= 3
5905 "%s() needs keyword-only argument %U", func_name, kw_name);
5907 "%s() needs keyword-only argument %s", func_name,
5908 PyString_AS_STRING(kw_name));
5913 raise_double_keywords_utility_code = UtilityCode(
5915 static void __Pyx_RaiseDoubleKeywordsError(
5916 const char* func_name, PyObject* kw_name); /*proto*/
5919 static void __Pyx_RaiseDoubleKeywordsError(
5920 const char* func_name,
5923 PyErr_Format(PyExc_TypeError,
5924 #if PY_MAJOR_VERSION >= 3
5925 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5927 "%s() got multiple values for keyword argument '%s'", func_name,
5928 PyString_AS_STRING(kw_name));
5933 #------------------------------------------------------------------------------------
5935 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5936 # were passed to a function, or if any keywords were passed to a
5937 # function that does not accept them.
5939 keyword_string_check_utility_code = UtilityCode(
5941 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5942 const char* function_name, int kw_allowed); /*proto*/
5945 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5947 const char* function_name,
5952 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5953 #if PY_MAJOR_VERSION < 3
5954 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5956 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5958 goto invalid_keyword_type;
5960 if ((!kw_allowed) && unlikely(key))
5961 goto invalid_keyword;
5963 invalid_keyword_type:
5964 PyErr_Format(PyExc_TypeError,
5965 "%s() keywords must be strings", function_name);
5968 PyErr_Format(PyExc_TypeError,
5969 #if PY_MAJOR_VERSION < 3
5970 "%s() got an unexpected keyword argument '%s'",
5971 function_name, PyString_AsString(key));
5973 "%s() got an unexpected keyword argument '%U'",
5974 function_name, key);
5980 #------------------------------------------------------------------------------------
5982 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5983 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5984 # keywords will raise an invalid keyword error.
5986 # Three kinds of errors are checked: 1) non-string keywords, 2)
5987 # unexpected keywords and 3) overlap with positional arguments.
5989 # If num_posargs is greater 0, it denotes the number of positional
5990 # arguments that were passed and that must therefore not appear
5991 # amongst the keywords as well.
5993 # This method does not check for required keyword arguments.
5996 parse_keywords_utility_code = UtilityCode(
5998 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
5999 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6000 const char* function_name); /*proto*/
6003 static int __Pyx_ParseOptionalKeywords(
6005 PyObject **argnames[],
6008 Py_ssize_t num_pos_args,
6009 const char* function_name)
6011 PyObject *key = 0, *value = 0;
6014 PyObject*** first_kw_arg = argnames + num_pos_args;
6016 while (PyDict_Next(kwds, &pos, &key, &value)) {
6017 name = first_kw_arg;
6018 while (*name && (**name != key)) name++;
6020 values[name-argnames] = value;
6022 #if PY_MAJOR_VERSION < 3
6023 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6025 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6027 goto invalid_keyword_type;
6029 for (name = first_kw_arg; *name; name++) {
6030 #if PY_MAJOR_VERSION >= 3
6031 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6032 PyUnicode_Compare(**name, key) == 0) break;
6034 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6035 _PyString_Eq(**name, key)) break;
6039 values[name-argnames] = value;
6041 /* unexpected keyword found */
6042 for (name=argnames; name != first_kw_arg; name++) {
6043 if (**name == key) goto arg_passed_twice;
6044 #if PY_MAJOR_VERSION >= 3
6045 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6046 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6048 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6049 _PyString_Eq(**name, key)) goto arg_passed_twice;
6053 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6055 goto invalid_keyword;
6063 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6065 invalid_keyword_type:
6066 PyErr_Format(PyExc_TypeError,
6067 "%s() keywords must be strings", function_name);
6070 PyErr_Format(PyExc_TypeError,
6071 #if PY_MAJOR_VERSION < 3
6072 "%s() got an unexpected keyword argument '%s'",
6073 function_name, PyString_AsString(key));
6075 "%s() got an unexpected keyword argument '%U'",
6076 function_name, key);
6083 #------------------------------------------------------------------------------------
6085 traceback_utility_code = UtilityCode(
6087 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6090 #include "compile.h"
6091 #include "frameobject.h"
6092 #include "traceback.h"
6094 static void __Pyx_AddTraceback(const char *funcname) {
6095 PyObject *py_srcfile = 0;
6096 PyObject *py_funcname = 0;
6097 PyObject *py_globals = 0;
6098 PyCodeObject *py_code = 0;
6099 PyFrameObject *py_frame = 0;
6101 #if PY_MAJOR_VERSION < 3
6102 py_srcfile = PyString_FromString(%(FILENAME)s);
6104 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6106 if (!py_srcfile) goto bad;
6108 #if PY_MAJOR_VERSION < 3
6109 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6111 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6115 #if PY_MAJOR_VERSION < 3
6116 py_funcname = PyString_FromString(funcname);
6118 py_funcname = PyUnicode_FromString(funcname);
6121 if (!py_funcname) goto bad;
6122 py_globals = PyModule_GetDict(%(GLOBALS)s);
6123 if (!py_globals) goto bad;
6124 py_code = PyCode_New(
6125 0, /*int argcount,*/
6126 #if PY_MAJOR_VERSION >= 3
6127 0, /*int kwonlyargcount,*/
6130 0, /*int stacksize,*/
6132 %(EMPTY_BYTES)s, /*PyObject *code,*/
6133 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6134 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6135 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6136 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6137 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6138 py_srcfile, /*PyObject *filename,*/
6139 py_funcname, /*PyObject *name,*/
6140 %(LINENO)s, /*int firstlineno,*/
6141 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6143 if (!py_code) goto bad;
6144 py_frame = PyFrame_New(
6145 PyThreadState_GET(), /*PyThreadState *tstate,*/
6146 py_code, /*PyCodeObject *code,*/
6147 py_globals, /*PyObject *globals,*/
6148 0 /*PyObject *locals*/
6150 if (!py_frame) goto bad;
6151 py_frame->f_lineno = %(LINENO)s;
6152 PyTraceBack_Here(py_frame);
6154 Py_XDECREF(py_srcfile);
6155 Py_XDECREF(py_funcname);
6156 Py_XDECREF(py_code);
6157 Py_XDECREF(py_frame);
6160 'FILENAME': Naming.filename_cname,
6161 'LINENO': Naming.lineno_cname,
6162 'CFILENAME': Naming.cfilenm_cname,
6163 'CLINENO': Naming.clineno_cname,
6164 'GLOBALS': Naming.module_cname,
6165 'EMPTY_TUPLE' : Naming.empty_tuple,
6166 'EMPTY_BYTES' : Naming.empty_bytes,
6169 #------------------------------------------------------------------------------------
6171 unraisable_exception_utility_code = UtilityCode(
6173 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6176 static void __Pyx_WriteUnraisable(const char *name) {
6177 PyObject *old_exc, *old_val, *old_tb;
6179 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6180 #if PY_MAJOR_VERSION < 3
6181 ctx = PyString_FromString(name);
6183 ctx = PyUnicode_FromString(name);
6185 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6187 PyErr_WriteUnraisable(Py_None);
6189 PyErr_WriteUnraisable(ctx);
6194 requires=[restore_exception_utility_code])
6196 #------------------------------------------------------------------------------------
6198 set_vtable_utility_code = UtilityCode(
6200 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6203 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6204 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6205 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6207 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6211 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6221 #------------------------------------------------------------------------------------
6223 get_vtable_utility_code = UtilityCode(
6225 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6228 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6229 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6232 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6233 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6235 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6237 if (!*(void **)vtabptr)
6247 #------------------------------------------------------------------------------------
6249 init_string_tab_utility_code = UtilityCode(
6251 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6254 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6256 #if PY_MAJOR_VERSION < 3
6257 if (t->is_unicode) {
6258 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6259 } else if (t->intern) {
6260 *t->p = PyString_InternFromString(t->s);
6262 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6264 #else /* Python 3+ has unicode identifiers */
6265 if (t->is_unicode | t->is_str) {
6267 *t->p = PyUnicode_InternFromString(t->s);
6268 } else if (t->encoding) {
6269 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6271 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6274 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6285 #------------------------------------------------------------------------------------
6287 force_init_threads_utility_code = UtilityCode(
6289 #ifndef __PYX_FORCE_INIT_THREADS
6290 #if PY_VERSION_HEX < 0x02040200
6291 #define __PYX_FORCE_INIT_THREADS 1
6293 #define __PYX_FORCE_INIT_THREADS 0
6298 #------------------------------------------------------------------------------------
6300 # Note that cPython ignores PyTrace_EXCEPTION,
6301 # but maybe some other profilers don't.
6303 profile_utility_code = UtilityCode(proto="""
6304 #ifndef CYTHON_PROFILE
6305 #define CYTHON_PROFILE 1
6308 #ifndef CYTHON_PROFILE_REUSE_FRAME
6309 #define CYTHON_PROFILE_REUSE_FRAME 0
6314 #include "compile.h"
6315 #include "frameobject.h"
6316 #include "traceback.h"
6318 #if CYTHON_PROFILE_REUSE_FRAME
6319 #define CYTHON_FRAME_MODIFIER static
6320 #define CYTHON_FRAME_DEL
6322 #define CYTHON_FRAME_MODIFIER
6323 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6326 #define __Pyx_TraceDeclarations \\
6327 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6328 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6329 int __Pyx_use_tracing = 0;
6331 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6332 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6333 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6336 #define __Pyx_TraceException() \\
6337 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6338 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6340 PyThreadState_GET()->c_profilefunc( \\
6341 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6342 Py_DECREF(exc_info); \\
6346 #define __Pyx_TraceReturn(result) \\
6347 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6348 PyThreadState_GET()->c_profilefunc( \\
6349 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6350 CYTHON_FRAME_DEL; \\
6353 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6354 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6358 #define __Pyx_TraceDeclarations
6359 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6360 #define __Pyx_TraceException()
6361 #define __Pyx_TraceReturn(result)
6363 #endif /* CYTHON_PROFILE */
6366 "FRAME": Naming.frame_cname,
6367 "FRAME_CODE": Naming.frame_code_cname,
6373 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6374 PyFrameObject** frame,
6375 const char *funcname,
6376 const char *srcfile,
6378 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6379 if (*code == NULL) {
6380 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6381 if (*code == NULL) return 0;
6383 *frame = PyFrame_New(
6384 PyThreadState_GET(), /*PyThreadState *tstate*/
6385 *code, /*PyCodeObject *code*/
6386 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6387 0 /*PyObject *locals*/
6389 if (*frame == NULL) return 0;
6392 (*frame)->f_tstate = PyThreadState_GET();
6394 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6397 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6398 PyObject *py_srcfile = 0;
6399 PyObject *py_funcname = 0;
6400 PyCodeObject *py_code = 0;
6402 #if PY_MAJOR_VERSION < 3
6403 py_funcname = PyString_FromString(funcname);
6404 py_srcfile = PyString_FromString(srcfile);
6406 py_funcname = PyUnicode_FromString(funcname);
6407 py_srcfile = PyUnicode_FromString(srcfile);
6409 if (!py_funcname | !py_srcfile) goto bad;
6411 py_code = PyCode_New(
6412 0, /*int argcount,*/
6413 #if PY_MAJOR_VERSION >= 3
6414 0, /*int kwonlyargcount,*/
6417 0, /*int stacksize,*/
6419 %(EMPTY_BYTES)s, /*PyObject *code,*/
6420 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6421 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6422 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6423 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6424 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6425 py_srcfile, /*PyObject *filename,*/
6426 py_funcname, /*PyObject *name,*/
6427 firstlineno, /*int firstlineno,*/
6428 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6432 Py_XDECREF(py_srcfile);
6433 Py_XDECREF(py_funcname);
6438 #endif /* CYTHON_PROFILE */
6440 'EMPTY_TUPLE' : Naming.empty_tuple,
6441 'EMPTY_BYTES' : Naming.empty_bytes,
6442 "MODULE": Naming.module_cname,