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]
903 # decorators [cython.locals(...)] or None
904 # directive_locals { string : NameNode } locals defined by cython.locals(...)
906 child_attrs = ["base_type", "declarators"]
909 directive_locals = {}
911 def analyse_declarations(self, env, dest_scope = None):
914 self.dest_scope = dest_scope
915 base_type = self.base_type.analyse(env)
917 # If the field is an external typedef, we cannot be sure about the type,
918 # so do conversion ourself rather than rely on the CPython mechanism (through
919 # a property; made in AnalyseDeclarationsTransform).
920 if (dest_scope.is_c_class_scope
921 and self.visibility in ('public', 'readonly')):
924 need_property = False
925 visibility = self.visibility
927 for declarator in self.declarators:
928 name_declarator, type = declarator.analyse(base_type, env)
929 if not type.is_complete():
930 if not (self.visibility == 'extern' and type.is_array):
931 error(declarator.pos,
932 "Variable type '%s' is incomplete" % type)
933 if self.visibility == 'extern' and type.is_pyobject:
934 error(declarator.pos,
935 "Python object cannot be declared extern")
936 name = name_declarator.name
937 cname = name_declarator.cname
939 error(declarator.pos, "Missing name in declaration.")
941 if type.is_cfunction:
942 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
943 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
945 if entry is not None:
946 entry.directive_locals = self.directive_locals
948 if self.directive_locals:
949 s.error("Decorators can only be followed by functions")
950 if self.in_pxd and self.visibility != 'extern':
952 "Only 'extern' C variable declaration allowed in .pxd file")
953 entry = dest_scope.declare_var(name, type, declarator.pos,
954 cname = cname, visibility = visibility, is_cdef = 1)
955 entry.needs_property = need_property
958 class CStructOrUnionDefNode(StatNode):
960 # cname string or None
961 # kind "struct" or "union"
962 # typedef_flag boolean
963 # visibility "public" or "private"
965 # attributes [CVarDefNode] or None
969 child_attrs = ["attributes"]
971 def analyse_declarations(self, env):
973 if self.visibility == 'extern' and self.packed:
974 error(self.pos, "Cannot declare extern struct as 'packed'")
975 if self.attributes is not None:
976 scope = StructOrUnionScope(self.name)
977 self.entry = env.declare_struct_or_union(
978 self.name, self.kind, scope, self.typedef_flag, self.pos,
979 self.cname, visibility = self.visibility, packed = self.packed)
980 if self.attributes is not None:
981 if self.in_pxd and not env.in_cinclude:
982 self.entry.defined_in_pxd = 1
983 for attr in self.attributes:
984 attr.analyse_declarations(env, scope)
985 if self.visibility != 'extern':
986 need_typedef_indirection = False
987 for attr in scope.var_entries:
990 type = type.base_type
991 if type == self.entry.type:
992 error(attr.pos, "Struct cannot contain itself as a member.")
993 if self.typedef_flag:
995 type = type.base_type
996 if type == self.entry.type:
997 need_typedef_indirection = True
998 if need_typedef_indirection:
999 # C can't handle typedef structs that refer to themselves.
1000 struct_entry = self.entry
1001 self.entry = env.declare_typedef(
1002 self.name, struct_entry.type, self.pos,
1003 cname = self.cname, visibility='ignore')
1004 struct_entry.type.typedef_flag = False
1005 # FIXME: this might be considered a hack ;-)
1006 struct_entry.cname = struct_entry.type.cname = \
1007 '_' + self.entry.type.typedef_cname
1009 def analyse_expressions(self, env):
1012 def generate_execution_code(self, code):
1016 class CppClassNode(CStructOrUnionDefNode):
1019 # cname string or None
1020 # visibility "extern"
1022 # attributes [CVarDefNode] or None
1024 # base_classes [string]
1025 # templates [string] or None
1027 def analyse_declarations(self, env):
1029 if self.attributes is not None:
1030 scope = CppClassScope(self.name, env)
1031 base_class_types = []
1032 for base_class_name in self.base_classes:
1033 base_class_entry = env.lookup(base_class_name)
1034 if base_class_entry is None:
1035 error(self.pos, "'%s' not found" % base_class_name)
1036 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1037 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1039 base_class_types.append(base_class_entry.type)
1040 if self.templates is None:
1041 template_types = None
1043 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1044 self.entry = env.declare_cpp_class(
1045 self.name, scope, self.pos,
1046 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1047 self.entry.is_cpp_class = 1
1048 if self.attributes is not None:
1049 if self.in_pxd and not env.in_cinclude:
1050 self.entry.defined_in_pxd = 1
1051 for attr in self.attributes:
1052 attr.analyse_declarations(scope)
1054 class CEnumDefNode(StatNode):
1055 # name string or None
1056 # cname string or None
1057 # items [CEnumDefItemNode]
1058 # typedef_flag boolean
1059 # visibility "public" or "private"
1063 child_attrs = ["items"]
1065 def analyse_declarations(self, env):
1066 self.entry = env.declare_enum(self.name, self.pos,
1067 cname = self.cname, typedef_flag = self.typedef_flag,
1068 visibility = self.visibility)
1069 if self.items is not None:
1070 if self.in_pxd and not env.in_cinclude:
1071 self.entry.defined_in_pxd = 1
1072 for item in self.items:
1073 item.analyse_declarations(env, self.entry)
1075 def analyse_expressions(self, env):
1078 def generate_execution_code(self, code):
1079 if self.visibility == 'public':
1080 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1081 for item in self.entry.enum_values:
1082 code.putln("%s = PyInt_FromLong(%s); %s" % (
1085 code.error_goto_if_null(temp, item.pos)))
1086 code.put_gotref(temp)
1087 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1088 Naming.module_cname,
1091 code.error_goto(item.pos)))
1092 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1093 code.funcstate.release_temp(temp)
1096 class CEnumDefItemNode(StatNode):
1098 # cname string or None
1099 # value ExprNode or None
1101 child_attrs = ["value"]
1103 def analyse_declarations(self, env, enum_entry):
1105 self.value.analyse_const_expression(env)
1106 if not self.value.type.is_int:
1107 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1108 self.value.analyse_const_expression(env)
1109 entry = env.declare_const(self.name, enum_entry.type,
1110 self.value, self.pos, cname = self.cname,
1111 visibility = enum_entry.visibility)
1112 enum_entry.enum_values.append(entry)
1115 class CTypeDefNode(StatNode):
1116 # base_type CBaseTypeNode
1117 # declarator CDeclaratorNode
1118 # visibility "public" or "private"
1121 child_attrs = ["base_type", "declarator"]
1123 def analyse_declarations(self, env):
1124 base = self.base_type.analyse(env)
1125 name_declarator, type = self.declarator.analyse(base, env)
1126 name = name_declarator.name
1127 cname = name_declarator.cname
1128 entry = env.declare_typedef(name, type, self.pos,
1129 cname = cname, visibility = self.visibility)
1130 if self.in_pxd and not env.in_cinclude:
1131 entry.defined_in_pxd = 1
1133 def analyse_expressions(self, env):
1135 def generate_execution_code(self, code):
1139 class FuncDefNode(StatNode, BlockNode):
1140 # Base class for function definition nodes.
1142 # return_type PyrexType
1143 # #filename string C name of filename string const
1144 # entry Symtab.Entry
1145 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1146 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1150 needs_closure = False
1153 def analyse_default_values(self, env):
1154 genv = env.global_scope()
1156 for arg in self.args:
1160 arg.default.analyse_types(env)
1161 arg.default = arg.default.coerce_to(arg.type, genv)
1164 "This argument cannot have a default value")
1169 error(arg.pos, "Non-default argument following default argument")
1171 def need_gil_acquisition(self, lenv):
1174 def create_local_scope(self, env):
1176 while genv.is_py_class_scope or genv.is_c_class_scope:
1177 genv = env.outer_scope
1178 if self.needs_closure:
1179 lenv = ClosureScope(name=self.entry.name,
1181 scope_name=self.entry.cname)
1183 lenv = LocalScope(name=self.entry.name,
1186 lenv.return_type = self.return_type
1187 type = self.entry.type
1188 if type.is_cfunction:
1189 lenv.nogil = type.nogil and not type.with_gil
1190 self.local_scope = lenv
1191 lenv.directives = env.directives
1194 def generate_function_definitions(self, env, code):
1197 lenv = self.local_scope
1198 if lenv.is_closure_scope:
1199 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1200 Naming.outer_scope_cname)
1202 outer_scope_cname = Naming.outer_scope_cname
1203 lenv.mangle_closure_cnames(outer_scope_cname)
1204 # Generate closure function definitions
1205 self.body.generate_function_definitions(lenv, code)
1206 # generate lambda function definitions
1207 for node in lenv.lambda_defs:
1208 node.generate_function_definitions(lenv, code)
1210 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1211 self.entry.scope.is_c_class_scope)
1212 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1213 self.entry.scope.is_c_class_scope)
1214 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1216 if 'cython_unused' not in self.modifiers:
1217 self.modifiers = self.modifiers + ['cython_unused']
1219 preprocessor_guard = None
1220 if self.entry.is_special and not is_buffer_slot:
1221 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1223 preprocessor_guard = slot.preprocessor_guard_code()
1224 if (self.entry.name == '__long__' and
1225 not self.entry.scope.lookup_here('__int__')):
1226 preprocessor_guard = None
1228 profile = code.globalstate.directives['profile']
1231 error(self.pos, "Cannot profile nogil function.")
1232 code.globalstate.use_utility_code(profile_utility_code)
1234 # Generate C code for header and body of function
1235 code.enter_cfunc_scope()
1236 code.return_from_error_cleanup_label = code.new_label()
1238 # ----- Top-level constants used by this function
1239 code.mark_pos(self.pos)
1240 self.generate_cached_builtins_decls(lenv, code)
1241 # ----- Function header
1244 if preprocessor_guard:
1245 code.putln(preprocessor_guard)
1247 with_pymethdef = self.needs_assignment_synthesis(env, code)
1249 self.py_func.generate_function_header(code,
1250 with_pymethdef = with_pymethdef,
1252 self.generate_function_header(code,
1253 with_pymethdef = with_pymethdef)
1254 # ----- Local variable declarations
1255 if lenv.is_closure_scope:
1256 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1258 elif env.is_closure_scope:
1259 code.put(env.scope_class.type.declaration_code(Naming.outer_scope_cname))
1261 self.generate_argument_declarations(lenv, code)
1262 for entry in lenv.var_entries:
1263 if not entry.in_closure:
1264 code.put_var_declaration(entry)
1266 if not self.return_type.is_void:
1267 if self.return_type.is_pyobject:
1271 (self.return_type.declaration_code(Naming.retval_cname),
1273 tempvardecl_code = code.insertion_point()
1274 self.generate_keyword_list(code)
1276 code.put_trace_declarations()
1277 # ----- Extern library function declarations
1278 lenv.generate_library_function_declarations(code)
1279 # ----- GIL acquisition
1280 acquire_gil = self.acquire_gil
1282 env.use_utility_code(force_init_threads_utility_code)
1283 code.putln("#ifdef WITH_THREAD")
1284 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1285 code.putln("#endif")
1286 # ----- set up refnanny
1288 code.put_setup_refcount_context(self.entry.name)
1289 # ----- Automatic lead-ins for certain special functions
1290 if is_getbuffer_slot:
1291 self.getbuffer_init(code)
1292 # ----- Create closure scope object
1293 if self.needs_closure:
1294 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1295 Naming.cur_scope_cname,
1296 lenv.scope_class.type.declaration_code(''),
1297 lenv.scope_class.type.typeptr_cname,
1298 lenv.scope_class.type.typeptr_cname,
1299 Naming.empty_tuple))
1300 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1301 if is_getbuffer_slot:
1302 self.getbuffer_error_cleanup(code)
1304 code.put_finish_refcount_context()
1305 # FIXME: what if the error return value is a Python value?
1306 code.putln("return %s;" % self.error_value())
1308 code.put_gotref(Naming.cur_scope_cname)
1309 # Note that it is unsafe to decref the scope at this point.
1310 if env.is_closure_scope:
1311 code.putln("%s = (%s)%s;" % (
1313 env.scope_class.type.declaration_code(''),
1315 if self.needs_closure:
1316 # inner closures own a reference to their outer parent
1317 code.put_incref(outer_scope_cname, env.scope_class.type)
1318 code.put_giveref(outer_scope_cname)
1319 # ----- Trace function call
1321 # this looks a bit late, but if we don't get here due to a
1322 # fatal error before hand, it's not really worth tracing
1323 code.put_trace_call(self.entry.name, self.pos)
1324 # ----- Fetch arguments
1325 self.generate_argument_parsing_code(env, code)
1326 # If an argument is assigned to in the body, we must
1327 # incref it to properly keep track of refcounts.
1328 for entry in lenv.arg_entries:
1329 if entry.type.is_pyobject:
1330 if entry.assignments and not entry.in_closure:
1331 code.put_var_incref(entry)
1332 # ----- Initialise local variables
1333 for entry in lenv.var_entries:
1334 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1335 code.put_init_var_to_py_none(entry)
1336 # ----- Initialise local buffer auxiliary variables
1337 for entry in lenv.var_entries + lenv.arg_entries:
1338 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1339 code.putln("%s.buf = NULL;" %
1340 entry.buffer_aux.buffer_info_var.cname)
1341 # ----- Check and convert arguments
1342 self.generate_argument_type_tests(code)
1343 # ----- Acquire buffer arguments
1344 for entry in lenv.arg_entries:
1345 if entry.type.is_buffer:
1346 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1348 # -------------------------
1349 # ----- Function body -----
1350 # -------------------------
1351 self.body.generate_execution_code(code)
1353 # ----- Default return value
1355 if self.return_type.is_pyobject:
1356 #if self.return_type.is_extension_type:
1357 # lhs = "(PyObject *)%s" % Naming.retval_cname
1359 lhs = Naming.retval_cname
1360 code.put_init_to_py_none(lhs, self.return_type)
1362 val = self.return_type.default_value
1364 code.putln("%s = %s;" % (Naming.retval_cname, val))
1365 # ----- Error cleanup
1366 if code.error_label in code.labels_used:
1367 code.put_goto(code.return_label)
1368 code.put_label(code.error_label)
1369 for cname, type in code.funcstate.all_managed_temps():
1370 code.put_xdecref(cname, type)
1372 # Clean up buffers -- this calls a Python function
1373 # so need to save and restore error state
1374 buffers_present = len(lenv.buffer_entries) > 0
1376 code.globalstate.use_utility_code(restore_exception_utility_code)
1377 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1378 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1379 for entry in lenv.buffer_entries:
1380 Buffer.put_release_buffer_code(code, entry)
1381 #code.putln("%s = 0;" % entry.cname)
1382 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1384 err_val = self.error_value()
1385 exc_check = self.caller_will_check_exceptions()
1386 if err_val is not None or exc_check:
1387 # TODO: Fix exception tracing (though currently unused by cProfile).
1388 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1389 # code.put_trace_exception()
1390 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1392 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1393 % self.entry.qualified_name, 0)
1395 '__Pyx_WriteUnraisable("%s");' %
1396 self.entry.qualified_name)
1397 env.use_utility_code(unraisable_exception_utility_code)
1398 env.use_utility_code(restore_exception_utility_code)
1399 default_retval = self.return_type.default_value
1400 if err_val is None and default_retval:
1401 err_val = default_retval
1402 if err_val is not None:
1403 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1405 if is_getbuffer_slot:
1406 self.getbuffer_error_cleanup(code)
1408 # If we are using the non-error cleanup section we should
1409 # jump past it if we have an error. The if-test below determine
1410 # whether this section is used.
1411 if buffers_present or is_getbuffer_slot:
1412 code.put_goto(code.return_from_error_cleanup_label)
1415 # ----- Non-error return cleanup
1416 code.put_label(code.return_label)
1417 for entry in lenv.buffer_entries:
1419 Buffer.put_release_buffer_code(code, entry)
1420 if is_getbuffer_slot:
1421 self.getbuffer_normal_cleanup(code)
1422 # ----- Return cleanup for both error and no-error return
1423 code.put_label(code.return_from_error_cleanup_label)
1424 if not Options.init_local_none:
1425 for entry in lenv.var_entries:
1426 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1427 entry.xdecref_cleanup = 1
1429 for entry in lenv.var_entries:
1430 if entry.type.is_pyobject:
1431 if entry.used and not entry.in_closure:
1432 code.put_var_decref(entry)
1433 elif entry.in_closure and self.needs_closure:
1434 code.put_giveref(entry.cname)
1435 # Decref any increfed args
1436 for entry in lenv.arg_entries:
1437 if entry.type.is_pyobject:
1438 if entry.in_closure:
1439 code.put_var_giveref(entry)
1440 elif entry.assignments:
1441 code.put_var_decref(entry)
1442 if self.needs_closure:
1443 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1446 # This code is duplicated in ModuleNode.generate_module_init_func
1448 default_retval = self.return_type.default_value
1449 err_val = self.error_value()
1450 if err_val is None and default_retval:
1451 err_val = default_retval
1452 if self.return_type.is_pyobject:
1453 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1455 if self.entry.is_special and self.entry.name == "__hash__":
1456 # Returning -1 for __hash__ is supposed to signal an error
1457 # We do as Python instances and coerce -1 into -2.
1458 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1459 Naming.retval_cname, Naming.retval_cname))
1462 if self.return_type.is_pyobject:
1463 code.put_trace_return(Naming.retval_cname)
1465 code.put_trace_return("Py_None")
1467 code.put_finish_refcount_context()
1470 code.putln("#ifdef WITH_THREAD")
1471 code.putln("PyGILState_Release(_save);")
1472 code.putln("#endif")
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 if self.name == '__new__':
1963 self.is_staticmethod = 1
1965 self.analyse_argument_types(env)
1966 if self.name == '<lambda>':
1967 self.declare_lambda_function(env)
1969 self.declare_pyfunction(env)
1970 self.analyse_signature(env)
1971 self.return_type = self.entry.signature.return_type()
1972 self.create_local_scope(env)
1974 def analyse_argument_types(self, env):
1975 directive_locals = self.directive_locals = env.directives['locals']
1976 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
1977 for arg in self.args:
1978 if hasattr(arg, 'name'):
1980 name_declarator = None
1982 base_type = arg.base_type.analyse(env)
1983 name_declarator, type = \
1984 arg.declarator.analyse(base_type, env)
1985 arg.name = name_declarator.name
1986 if arg.name in directive_locals:
1987 type_node = directive_locals[arg.name]
1988 other_type = type_node.analyse_as_type(env)
1989 if other_type is None:
1990 error(type_node.pos, "Not a type")
1991 elif (type is not PyrexTypes.py_object_type
1992 and not type.same_as(other_type)):
1993 error(arg.base_type.pos, "Signature does not agree with previous declaration")
1994 error(type_node.pos, "Previous declaration here")
1997 if name_declarator and name_declarator.cname:
1999 "Python function argument cannot have C name specification")
2000 arg.type = type.as_argument_type()
2002 arg.needs_conversion = 0
2003 arg.needs_type_test = 0
2005 if arg.type.is_pyobject:
2007 arg.accept_none = True
2009 arg.accept_none = False
2010 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2011 if arg.default and arg.default.constant_result is None:
2012 # special case: def func(MyType obj = None)
2013 arg.accept_none = True
2015 # default depends on compiler directive
2016 arg.accept_none = allow_none_for_extension_args
2018 # probably just a plain 'object'
2019 arg.accept_none = True
2021 arg.accept_none = True # won't be used, but must be there
2023 error(arg.pos, "Only Python type arguments can have 'not None'")
2025 error(arg.pos, "Only Python type arguments can have 'or None'")
2027 def analyse_signature(self, env):
2028 if self.entry.is_special:
2029 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2030 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2031 # Use the simpler calling signature for zero- and one-argument functions.
2032 if self.entry.signature is TypeSlots.pyfunction_signature:
2033 if len(self.args) == 0:
2034 self.entry.signature = TypeSlots.pyfunction_noargs
2035 elif len(self.args) == 1:
2036 if self.args[0].default is None and not self.args[0].kw_only:
2037 self.entry.signature = TypeSlots.pyfunction_onearg
2038 elif self.entry.signature is TypeSlots.pymethod_signature:
2039 if len(self.args) == 1:
2040 self.entry.signature = TypeSlots.unaryfunc
2041 elif len(self.args) == 2:
2042 if self.args[1].default is None and not self.args[1].kw_only:
2043 self.entry.signature = TypeSlots.ibinaryfunc
2045 sig = self.entry.signature
2046 nfixed = sig.num_fixed_args()
2047 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2048 and len(self.args) == 0 and self.star_arg:
2049 # this is the only case where a diverging number of
2050 # arguments is not an error - when we have no explicit
2051 # 'self' parameter as in method(*args)
2052 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2053 self.self_in_stararg = 1
2056 for i in range(min(nfixed, len(self.args))):
2059 if sig.is_self_arg(i) and not self.is_staticmethod:
2060 if self.is_classmethod:
2062 arg.hdr_type = arg.type = Builtin.type_type
2065 arg.hdr_type = arg.type = env.parent_type
2066 arg.needs_conversion = 0
2068 arg.hdr_type = sig.fixed_arg_type(i)
2069 if not arg.type.same_as(arg.hdr_type):
2070 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2071 arg.needs_type_test = 1
2073 arg.needs_conversion = 1
2074 if arg.needs_conversion:
2075 arg.hdr_cname = Naming.arg_prefix + arg.name
2077 arg.hdr_cname = Naming.var_prefix + arg.name
2079 if nfixed > len(self.args):
2080 self.bad_signature()
2082 elif nfixed < len(self.args):
2083 if not sig.has_generic_args:
2084 self.bad_signature()
2085 for arg in self.args:
2086 if arg.is_generic and \
2087 (arg.type.is_extension_type or arg.type.is_builtin_type):
2088 arg.needs_type_test = 1
2090 def bad_signature(self):
2091 sig = self.entry.signature
2092 expected_str = "%d" % sig.num_fixed_args()
2093 if sig.has_generic_args:
2094 expected_str = expected_str + " or more"
2096 if name.startswith("__") and name.endswith("__"):
2097 desc = "Special method"
2101 "%s %s has wrong number of arguments "
2102 "(%d declared, %s expected)" % (
2103 desc, self.name, len(self.args), expected_str))
2105 def signature_has_nongeneric_args(self):
2106 argcount = len(self.args)
2107 if argcount == 0 or (
2108 argcount == 1 and (self.args[0].is_self_arg or
2109 self.args[0].is_type_arg)):
2113 def signature_has_generic_args(self):
2114 return self.entry.signature.has_generic_args
2116 def declare_pyfunction(self, env):
2117 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2119 entry = env.lookup_here(name)
2120 if entry and entry.type.is_cfunction and not self.is_wrapper:
2121 warning(self.pos, "Overriding cdef method with def method.", 5)
2122 entry = env.declare_pyfunction(name, self.pos)
2124 prefix = env.scope_prefix
2125 entry.func_cname = \
2126 Naming.pyfunc_prefix + prefix + name
2127 entry.pymethdef_cname = \
2128 Naming.pymethdef_prefix + prefix + name
2129 if Options.docstrings:
2130 entry.doc = embed_position(self.pos, self.doc)
2132 Naming.funcdoc_prefix + prefix + name
2133 if entry.is_special:
2134 if entry.name in TypeSlots.invisible or not entry.doc:
2135 entry.wrapperbase_cname = None
2137 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2141 def declare_lambda_function(self, env):
2143 prefix = env.scope_prefix
2145 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2146 entry = env.declare_lambda_function(func_cname, self.pos)
2147 entry.pymethdef_cname = \
2148 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2149 entry.qualified_name = env.qualify_name(self.lambda_name)
2153 def declare_arguments(self, env):
2154 for arg in self.args:
2156 error(arg.pos, "Missing argument name")
2158 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2159 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2160 if arg.needs_conversion:
2161 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2162 if arg.type.is_pyobject:
2163 arg.entry.init = "0"
2164 arg.entry.init_to_none = 0
2166 arg.entry = self.declare_argument(env, arg)
2168 arg.entry.is_self_arg = arg.is_self_arg
2170 if arg.is_self_arg or arg.is_type_arg or \
2171 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2172 arg.entry.is_declared_generic = 1
2173 self.declare_python_arg(env, self.star_arg)
2174 self.declare_python_arg(env, self.starstar_arg)
2176 def declare_python_arg(self, env, arg):
2178 if env.directives['infer_types'] != False:
2179 type = PyrexTypes.unspecified_type
2181 type = py_object_type
2182 entry = env.declare_var(arg.name, type, arg.pos)
2185 entry.init_to_none = 0
2186 entry.xdecref_cleanup = 1
2188 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2190 def analyse_expressions(self, env):
2191 self.local_scope.directives = env.directives
2192 self.analyse_default_values(env)
2193 if self.needs_assignment_synthesis(env):
2194 # Shouldn't we be doing this at the module level too?
2195 self.synthesize_assignment_node(env)
2197 def needs_assignment_synthesis(self, env, code=None):
2198 # Should enable for module level as well, that will require more testing...
2199 if env.is_module_scope:
2201 return env.directives['binding']
2203 return code.globalstate.directives['binding']
2204 return env.is_py_class_scope or env.is_closure_scope
2206 def synthesize_assignment_node(self, env):
2208 if env.is_py_class_scope:
2209 rhs = ExprNodes.PyCFunctionNode(self.pos,
2210 pymethdef_cname = self.entry.pymethdef_cname)
2211 if not self.is_staticmethod and not self.is_classmethod:
2214 elif env.is_closure_scope:
2215 rhs = ExprNodes.InnerFunctionNode(
2216 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2218 rhs = ExprNodes.PyCFunctionNode(
2219 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2220 self.assmt = SingleAssignmentNode(self.pos,
2221 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2223 self.assmt.analyse_declarations(env)
2224 self.assmt.analyse_expressions(env)
2226 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2228 sig = self.entry.signature
2229 if sig.has_dummy_arg or self.self_in_stararg:
2230 arg_code_list.append(
2231 "PyObject *%s" % Naming.self_cname)
2232 for arg in self.args:
2233 if not arg.is_generic:
2234 if arg.is_self_arg or arg.is_type_arg:
2235 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2237 arg_code_list.append(
2238 arg.hdr_type.declaration_code(arg.hdr_cname))
2239 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2240 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2241 if sig.has_generic_args:
2242 arg_code_list.append(
2243 "PyObject *%s, PyObject *%s"
2244 % (Naming.args_cname, Naming.kwds_cname))
2245 arg_code = ", ".join(arg_code_list)
2246 dc = self.return_type.declaration_code(self.entry.func_cname)
2247 mf = " ".join(self.modifiers).upper()
2249 header = "static %s%s(%s)" % (mf, dc, arg_code)
2250 code.putln("%s; /*proto*/" % header)
2253 if (Options.docstrings and self.entry.doc and
2254 not self.entry.scope.is_property_scope and
2255 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2256 docstr = self.entry.doc
2257 if docstr.is_unicode:
2258 docstr = docstr.utf8encode()
2260 'static char %s[] = "%s";' % (
2261 self.entry.doc_cname,
2262 split_string_literal(escape_byte_string(docstr))))
2263 if self.entry.is_special:
2265 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2268 "static PyMethodDef %s = " %
2269 self.entry.pymethdef_cname)
2270 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2271 code.putln("%s {" % header)
2273 def generate_argument_declarations(self, env, code):
2274 for arg in self.args:
2275 if arg.is_generic: # or arg.needs_conversion:
2276 if arg.needs_conversion:
2277 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2278 elif not arg.entry.in_closure:
2279 code.put_var_declaration(arg.entry)
2281 def generate_keyword_list(self, code):
2282 if self.signature_has_generic_args() and \
2283 self.signature_has_nongeneric_args():
2285 "static PyObject **%s[] = {" %
2286 Naming.pykwdlist_cname)
2287 for arg in self.args:
2289 pystring_cname = code.intern_identifier(arg.name)
2290 code.put('&%s,' % pystring_cname)
2293 def generate_argument_parsing_code(self, env, code):
2294 # Generate PyArg_ParseTuple call for generic
2295 # arguments, if any.
2296 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2297 # get rid of unused argument warning
2298 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2300 old_error_label = code.new_error_label()
2301 our_error_label = code.error_label
2302 end_label = code.new_label("argument_unpacking_done")
2304 has_kwonly_args = self.num_kwonly_args > 0
2305 has_star_or_kw_args = self.star_arg is not None \
2306 or self.starstar_arg is not None or has_kwonly_args
2308 for arg in self.args:
2309 if not arg.type.is_pyobject:
2310 done = arg.type.create_from_py_utility_code(env)
2311 if not done: pass # will fail later
2313 if not self.signature_has_generic_args():
2314 if has_star_or_kw_args:
2315 error(self.pos, "This method cannot have * or keyword arguments")
2316 self.generate_argument_conversion_code(code)
2318 elif not self.signature_has_nongeneric_args():
2319 # func(*args) or func(**kw) or func(*args, **kw)
2320 self.generate_stararg_copy_code(code)
2323 positional_args = []
2325 for arg in self.args:
2326 arg_entry = arg.entry
2329 if not arg.is_self_arg and not arg.is_type_arg:
2331 kw_only_args.append(arg)
2333 positional_args.append(arg)
2335 kw_only_args.append(arg)
2336 elif not arg.is_self_arg and not arg.is_type_arg:
2337 positional_args.append(arg)
2339 self.generate_tuple_and_keyword_parsing_code(
2340 positional_args, kw_only_args, end_label, code)
2342 code.error_label = old_error_label
2343 if code.label_used(our_error_label):
2344 if not code.label_used(end_label):
2345 code.put_goto(end_label)
2346 code.put_label(our_error_label)
2347 if has_star_or_kw_args:
2348 self.generate_arg_decref(self.star_arg, code)
2349 if self.starstar_arg:
2350 if self.starstar_arg.entry.xdecref_cleanup:
2351 code.put_var_xdecref(self.starstar_arg.entry)
2353 code.put_var_decref(self.starstar_arg.entry)
2354 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2355 # The arguments are put into the closure one after the
2356 # other, so when type errors are found, all references in
2357 # the closure instance must be properly ref-counted to
2358 # facilitate generic closure instance deallocation. In
2359 # the case of an argument type error, it's best to just
2360 # DECREF+clear the already handled references, as this
2361 # frees their references as early as possible.
2362 for arg in self.args:
2363 if arg.type.is_pyobject and arg.entry.in_closure:
2364 code.put_var_xdecref_clear(arg.entry)
2365 if self.needs_closure:
2366 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2367 code.put_finish_refcount_context()
2368 code.putln("return %s;" % self.error_value())
2369 if code.label_used(end_label):
2370 code.put_label(end_label)
2372 def generate_arg_assignment(self, arg, item, code):
2373 if arg.type.is_pyobject:
2375 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2377 code.putln("%s = %s;" % (entry.cname, item))
2378 if entry.in_closure:
2379 code.put_var_incref(entry)
2381 func = arg.type.from_py_function
2383 code.putln("%s = %s(%s); %s" % (
2387 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2389 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2391 def generate_arg_xdecref(self, arg, code):
2393 code.put_var_xdecref(arg.entry)
2395 def generate_arg_decref(self, arg, code):
2397 code.put_var_decref(arg.entry)
2399 def generate_stararg_copy_code(self, code):
2400 if not self.star_arg:
2401 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2402 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2404 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2405 self.name, Naming.args_cname, self.error_value()))
2408 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2410 if self.starstar_arg:
2412 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2414 kwarg_check = "%s" % Naming.kwds_cname
2416 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2417 Naming.kwds_cname, Naming.kwds_cname)
2419 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2420 kwarg_check, Naming.kwds_cname, self.name,
2421 bool(self.starstar_arg), self.error_value()))
2423 if self.starstar_arg:
2424 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2425 self.starstar_arg.entry.cname,
2428 code.putln("if (unlikely(!%s)) return %s;" % (
2429 self.starstar_arg.entry.cname, self.error_value()))
2430 self.starstar_arg.entry.xdecref_cleanup = 0
2431 code.put_gotref(self.starstar_arg.entry.cname)
2433 if self.self_in_stararg:
2434 # need to create a new tuple with 'self' inserted as first item
2435 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2436 self.star_arg.entry.cname,
2438 self.star_arg.entry.cname))
2439 if self.starstar_arg:
2441 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2442 code.putln("return %s;" % self.error_value())
2445 code.putln("return %s;" % self.error_value())
2446 code.put_gotref(self.star_arg.entry.cname)
2447 code.put_incref(Naming.self_cname, py_object_type)
2448 code.put_giveref(Naming.self_cname)
2449 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2450 self.star_arg.entry.cname, Naming.self_cname))
2451 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2452 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2453 temp, temp, Naming.args_cname, temp))
2454 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2455 Naming.args_cname, temp))
2456 code.put_incref("item", py_object_type)
2457 code.put_giveref("item")
2458 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2459 self.star_arg.entry.cname, temp))
2461 code.funcstate.release_temp(temp)
2462 self.star_arg.entry.xdecref_cleanup = 0
2464 code.put_incref(Naming.args_cname, py_object_type)
2465 code.putln("%s = %s;" % (
2466 self.star_arg.entry.cname,
2468 self.star_arg.entry.xdecref_cleanup = 0
2470 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2471 kw_only_args, success_label, code):
2472 argtuple_error_label = code.new_label("argtuple_error")
2474 min_positional_args = self.num_required_args - self.num_required_kw_args
2475 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2476 min_positional_args -= 1
2477 max_positional_args = len(positional_args)
2478 has_fixed_positional_count = not self.star_arg and \
2479 min_positional_args == max_positional_args
2481 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2482 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2483 if self.num_required_kw_args:
2484 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2486 if self.starstar_arg or self.star_arg:
2487 self.generate_stararg_init_code(max_positional_args, code)
2489 # --- optimised code when we receive keyword arguments
2490 if self.num_required_kw_args:
2491 likely_hint = "likely"
2493 likely_hint = "unlikely"
2494 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2495 self.generate_keyword_unpacking_code(
2496 min_positional_args, max_positional_args,
2497 has_fixed_positional_count,
2498 positional_args, kw_only_args, argtuple_error_label, code)
2500 # --- optimised code when we do not receive any keyword arguments
2501 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2502 # Python raises arg tuple related errors first, so we must
2503 # check the length here
2504 if min_positional_args == max_positional_args and not self.star_arg:
2508 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2509 Naming.args_cname, compare, min_positional_args))
2510 code.put_goto(argtuple_error_label)
2512 if self.num_required_kw_args:
2513 # pure error case: keywords required but not passed
2514 if max_positional_args > min_positional_args and not self.star_arg:
2515 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2516 Naming.args_cname, max_positional_args))
2517 code.put_goto(argtuple_error_label)
2518 code.putln('} else {')
2519 for i, arg in enumerate(kw_only_args):
2521 pystring_cname = code.intern_identifier(arg.name)
2522 # required keyword-only argument missing
2523 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2526 code.putln(code.error_goto(self.pos))
2529 elif min_positional_args == max_positional_args:
2530 # parse the exact number of positional arguments from the
2532 code.putln('} else {')
2533 for i, arg in enumerate(positional_args):
2534 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2535 self.generate_arg_assignment(arg, item, code)
2536 self.generate_arg_default_assignments(code)
2539 # parse the positional arguments from the variable length
2541 code.putln('} else {')
2542 self.generate_arg_default_assignments(code)
2543 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2545 code.putln('default:')
2546 reversed_args = list(enumerate(positional_args))[::-1]
2547 for i, arg in reversed_args:
2548 if i >= min_positional_args-1:
2549 if min_positional_args > 1:
2550 code.putln('case %2d:' % (i+1)) # pure code beautification
2552 code.put('case %2d: ' % (i+1))
2553 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2554 self.generate_arg_assignment(arg, item, code)
2555 if min_positional_args == 0:
2556 code.put('case 0: ')
2557 code.putln('break;')
2559 if min_positional_args:
2560 for i in range(min_positional_args-1, -1, -1):
2561 code.putln('case %2d:' % i)
2562 code.put_goto(argtuple_error_label)
2564 code.put('default: ')
2565 code.put_goto(argtuple_error_label)
2570 if code.label_used(argtuple_error_label):
2571 code.put_goto(success_label)
2572 code.put_label(argtuple_error_label)
2573 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2574 self.name, has_fixed_positional_count,
2575 min_positional_args, max_positional_args,
2577 code.putln(code.error_goto(self.pos))
2579 def generate_arg_default_assignments(self, code):
2580 for arg in self.args:
2581 if arg.is_generic and arg.default:
2585 arg.calculate_default_value_code(code)))
2587 def generate_stararg_init_code(self, max_positional_args, code):
2588 if self.starstar_arg:
2589 self.starstar_arg.entry.xdecref_cleanup = 0
2590 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2591 self.starstar_arg.entry.cname,
2592 self.starstar_arg.entry.cname,
2593 self.error_value()))
2594 code.put_gotref(self.starstar_arg.entry.cname)
2596 self.star_arg.entry.xdecref_cleanup = 0
2597 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2599 max_positional_args))
2600 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2601 self.star_arg.entry.cname, Naming.args_cname,
2602 max_positional_args, Naming.args_cname))
2603 code.put_gotref(self.star_arg.entry.cname)
2604 if self.starstar_arg:
2606 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2607 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2608 code.putln('return %s;' % self.error_value())
2611 code.putln("if (unlikely(!%s)) return %s;" % (
2612 self.star_arg.entry.cname, self.error_value()))
2613 code.putln('} else {')
2614 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2615 code.put_incref(Naming.empty_tuple, py_object_type)
2618 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2619 has_fixed_positional_count, positional_args,
2620 kw_only_args, argtuple_error_label, code):
2621 all_args = tuple(positional_args) + tuple(kw_only_args)
2622 max_args = len(all_args)
2624 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2626 # the 'values' array collects borrowed references to arguments
2627 # before doing any type coercion etc.
2628 code.putln("PyObject* values[%d] = {%s};" % (
2629 max_args, ','.join('0'*max_args)))
2631 # assign borrowed Python default values to the values array,
2632 # so that they can be overwritten by received arguments below
2633 for i, arg in enumerate(all_args):
2634 if arg.default and arg.type.is_pyobject:
2635 default_value = arg.calculate_default_value_code(code)
2636 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2638 # parse the args tuple and check that it's not too long
2639 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2641 code.putln('default:')
2642 for i in range(max_positional_args-1, -1, -1):
2643 code.put('case %2d: ' % (i+1))
2644 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2645 i, Naming.args_cname, i))
2646 code.putln('case 0: break;')
2647 if not self.star_arg:
2648 code.put('default: ') # more arguments than allowed
2649 code.put_goto(argtuple_error_label)
2652 # now fill up the positional/required arguments with values
2654 if self.num_required_args or max_positional_args > 0:
2655 last_required_arg = -1
2656 for i, arg in enumerate(all_args):
2658 last_required_arg = i
2659 if last_required_arg < max_positional_args:
2660 last_required_arg = max_positional_args-1
2661 num_required_args = self.num_required_args
2662 if max_positional_args > 0:
2663 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2664 for i, arg in enumerate(all_args[:last_required_arg+1]):
2665 if max_positional_args > 0 and i <= max_positional_args:
2666 if self.star_arg and i == max_positional_args:
2667 code.putln('default:')
2669 code.putln('case %2d:' % i)
2670 pystring_cname = code.intern_identifier(arg.name)
2673 # handled separately below
2675 code.putln('if (kw_args > 0) {')
2676 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2677 Naming.kwds_cname, pystring_cname))
2678 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2681 num_required_args -= 1
2682 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2683 i, Naming.kwds_cname, pystring_cname))
2684 code.putln('if (likely(values[%d])) kw_args--;' % i);
2685 if i < min_positional_args:
2687 # special case: we know arg 0 is missing
2689 code.put_goto(argtuple_error_label)
2691 # print the correct number of values (args or
2692 # kwargs) that were passed into positional
2693 # arguments up to this point
2694 code.putln('else {')
2695 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2696 self.name, has_fixed_positional_count,
2697 min_positional_args, max_positional_args, i))
2698 code.putln(code.error_goto(self.pos))
2701 code.putln('else {')
2702 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2703 self.name, pystring_cname))
2704 code.putln(code.error_goto(self.pos))
2706 if max_positional_args > 0:
2709 if kw_only_args and not self.starstar_arg:
2710 # unpack optional keyword-only arguments
2711 # checking for interned strings in a dict is faster than iterating
2712 # but it's too likely that we must iterate if we expect **kwargs
2714 for i, arg in enumerate(all_args[max_positional_args:]):
2715 if not arg.kw_only or not arg.default:
2717 optional_args.append((i+max_positional_args, arg))
2719 # this mimics an unrolled loop so that we can "break" out of it
2720 code.putln('while (kw_args > 0) {')
2721 code.putln('PyObject* value;')
2722 for i, arg in optional_args:
2723 pystring_cname = code.intern_identifier(arg.name)
2725 'value = PyDict_GetItem(%s, %s);' % (
2726 Naming.kwds_cname, pystring_cname))
2728 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2729 code.putln('break;')
2732 code.putln('if (unlikely(kw_args > 0)) {')
2733 # non-positional/-required kw args left in dict: default args,
2734 # kw-only args, **kwargs or error
2736 # This is sort of a catch-all: except for checking required
2737 # arguments, this will always do the right thing for unpacking
2738 # keyword arguments, so that we can concentrate on optimising
2739 # common cases above.
2740 if max_positional_args == 0:
2743 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2744 Naming.args_cname, max_positional_args,
2745 Naming.args_cname, max_positional_args))
2746 pos_arg_count = "used_pos_args"
2748 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2749 code.globalstate.use_utility_code(parse_keywords_utility_code)
2751 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2753 Naming.pykwdlist_cname,
2754 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2757 code.putln(code.error_goto(self.pos))
2760 # convert arg values to their final type and assign them
2761 for i, arg in enumerate(all_args):
2762 if arg.default and not arg.type.is_pyobject:
2763 code.putln("if (values[%d]) {" % i)
2764 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2765 if arg.default and not arg.type.is_pyobject:
2766 code.putln('} else {')
2770 arg.calculate_default_value_code(code)))
2773 def generate_argument_conversion_code(self, code):
2774 # Generate code to convert arguments from signature type to
2775 # declared type, if needed. Also copies signature arguments
2776 # into closure fields.
2777 for arg in self.args:
2778 if arg.needs_conversion:
2779 self.generate_arg_conversion(arg, code)
2780 elif arg.entry.in_closure:
2781 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2782 if arg.type.is_pyobject:
2783 code.put_var_incref(arg.entry)
2785 def generate_arg_conversion(self, arg, code):
2786 # Generate conversion code for one argument.
2787 old_type = arg.hdr_type
2789 if old_type.is_pyobject:
2791 code.putln("if (%s) {" % arg.hdr_cname)
2793 code.putln("assert(%s); {" % arg.hdr_cname)
2794 self.generate_arg_conversion_from_pyobject(arg, code)
2796 elif new_type.is_pyobject:
2797 self.generate_arg_conversion_to_pyobject(arg, code)
2799 if new_type.assignable_from(old_type):
2801 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2804 "Cannot convert 1 argument from '%s' to '%s'" %
2805 (old_type, new_type))
2807 def generate_arg_conversion_from_pyobject(self, arg, code):
2809 func = new_type.from_py_function
2810 # copied from CoerceFromPyTypeNode
2812 lhs = arg.entry.cname
2813 rhs = "%s(%s)" % (func, arg.hdr_cname)
2814 if new_type.is_enum:
2815 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2816 code.putln("%s = %s; %s" % (
2819 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2822 "Cannot convert Python object argument to type '%s'"
2825 def generate_arg_conversion_to_pyobject(self, arg, code):
2826 old_type = arg.hdr_type
2827 func = old_type.to_py_function
2829 code.putln("%s = %s(%s); %s" % (
2833 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2834 code.put_var_gotref(arg.entry)
2837 "Cannot convert argument of type '%s' to Python object"
2840 def generate_argument_type_tests(self, code):
2841 # Generate type tests for args whose signature
2842 # type is PyObject * and whose declared type is
2843 # a subtype thereof.
2844 for arg in self.args:
2845 if arg.needs_type_test:
2846 self.generate_arg_type_test(arg, code)
2847 elif not arg.accept_none and arg.type.is_pyobject:
2848 self.generate_arg_none_check(arg, code)
2850 def error_value(self):
2851 return self.entry.signature.error_value
2853 def caller_will_check_exceptions(self):
2856 class OverrideCheckNode(StatNode):
2857 # A Node for dispatching to the def method if it
2866 child_attrs = ['body']
2870 def analyse_expressions(self, env):
2871 self.args = env.arg_entries
2872 if self.py_func.is_module_scope:
2877 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2878 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2879 call_node = ExprNodes.SimpleCallNode(self.pos,
2880 function=self.func_node,
2881 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2882 self.body = ReturnStatNode(self.pos, value=call_node)
2883 self.body.analyse_expressions(env)
2885 def generate_execution_code(self, code):
2886 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2887 # Check to see if we are an extension type
2888 if self.py_func.is_module_scope:
2889 self_arg = "((PyObject *)%s)" % Naming.module_cname
2891 self_arg = "((PyObject *)%s)" % self.args[0].cname
2892 code.putln("/* Check if called by wrapper */")
2893 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2894 code.putln("/* Check if overriden in Python */")
2895 if self.py_func.is_module_scope:
2896 code.putln("else {")
2898 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2899 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2900 self.func_node.set_cname(func_node_temp)
2901 # need to get attribute manually--scope would return cdef method
2902 err = code.error_goto_if_null(func_node_temp, self.pos)
2903 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2904 func_node_temp, self_arg, interned_attr_cname, err))
2905 code.put_gotref(func_node_temp)
2906 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2907 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2908 func_node_temp, self.py_func.entry.func_cname)
2909 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2910 self.body.generate_execution_code(code)
2912 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2913 code.funcstate.release_temp(func_node_temp)
2916 class ClassDefNode(StatNode, BlockNode):
2919 class PyClassDefNode(ClassDefNode):
2920 # A Python class definition.
2922 # name EncodedString Name of the class
2923 # doc string or None
2924 # body StatNode Attribute definition code
2925 # entry Symtab.Entry
2926 # scope PyClassScope
2927 # decorators [DecoratorNode] list of decorators or None
2929 # The following subnodes are constructed internally:
2931 # dict DictNode Class dictionary
2932 # classobj ClassNode Class object
2933 # target NameNode Variable to assign class object to
2935 child_attrs = ["body", "dict", "classobj", "target"]
2938 def __init__(self, pos, name, bases, doc, body, decorators = None):
2939 StatNode.__init__(self, pos)
2943 self.decorators = decorators
2945 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
2946 if self.doc and Options.docstrings:
2947 doc = embed_position(self.pos, self.doc)
2948 # FIXME: correct string node?
2949 doc_node = ExprNodes.StringNode(pos, value = doc)
2952 self.classobj = ExprNodes.ClassNode(pos, name = name,
2953 bases = bases, dict = self.dict, doc = doc_node)
2954 self.target = ExprNodes.NameNode(pos, name = name)
2956 def as_cclass(self):
2958 Return this node as if it were declared as an extension class
2960 bases = self.classobj.bases.args
2962 base_class_name = None
2963 base_class_module = None
2964 elif len(bases) == 1:
2967 from ExprNodes import AttributeNode, NameNode
2968 while isinstance(base, AttributeNode):
2969 path.insert(0, base.attribute)
2971 if isinstance(base, NameNode):
2972 path.insert(0, base.name)
2973 base_class_name = path[-1]
2975 base_class_module = u'.'.join(path[:-1])
2977 base_class_module = None
2979 error(self.classobj.bases.args.pos, "Invalid base class")
2981 error(self.classobj.bases.args.pos, "C class may only have one base class")
2984 return CClassDefNode(self.pos,
2985 visibility = 'private',
2987 class_name = self.name,
2988 base_class_module = base_class_module,
2989 base_class_name = base_class_name,
2990 decorators = self.decorators,
2995 def create_scope(self, env):
2997 while env.is_py_class_scope or env.is_c_class_scope:
2998 env = env.outer_scope
2999 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3002 def analyse_declarations(self, env):
3003 self.target.analyse_target_declaration(env)
3004 cenv = self.create_scope(env)
3005 cenv.directives = env.directives
3006 cenv.class_obj_cname = self.target.entry.cname
3007 self.body.analyse_declarations(cenv)
3009 def analyse_expressions(self, env):
3010 self.dict.analyse_expressions(env)
3011 self.classobj.analyse_expressions(env)
3012 genv = env.global_scope()
3014 self.body.analyse_expressions(cenv)
3015 self.target.analyse_target_expression(env, self.classobj)
3017 def generate_function_definitions(self, env, code):
3018 self.body.generate_function_definitions(self.scope, code)
3020 def generate_execution_code(self, code):
3021 code.pyclass_stack.append(self)
3023 self.dict.generate_evaluation_code(code)
3024 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3025 self.body.generate_execution_code(code)
3026 self.classobj.generate_evaluation_code(code)
3027 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3028 self.target.generate_assignment_code(self.classobj, code)
3029 self.dict.generate_disposal_code(code)
3030 self.dict.free_temps(code)
3031 code.pyclass_stack.pop()
3034 class CClassDefNode(ClassDefNode):
3035 # An extension type definition.
3037 # visibility 'private' or 'public' or 'extern'
3038 # typedef_flag boolean
3040 # module_name string or None For import of extern type objects
3041 # class_name string Unqualified name of class
3042 # as_name string or None Name to declare as in this scope
3043 # base_class_module string or None Module containing the base class
3044 # base_class_name string or None Name of the base class
3045 # objstruct_name string or None Specified C name of object struct
3046 # typeobj_name string or None Specified C name of type object
3047 # in_pxd boolean Is in a .pxd file
3048 # decorators [DecoratorNode] list of decorators or None
3049 # doc string or None
3050 # body StatNode or None
3051 # entry Symtab.Entry
3052 # base_type PyExtensionType or None
3053 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3054 # buffer_defaults_pos
3056 child_attrs = ["body"]
3057 buffer_defaults_node = None
3058 buffer_defaults_pos = None
3059 typedef_flag = False
3061 objstruct_name = None
3065 def analyse_declarations(self, env):
3066 #print "CClassDefNode.analyse_declarations:", self.class_name
3067 #print "...visibility =", self.visibility
3068 #print "...module_name =", self.module_name
3071 if self.buffer_defaults_node:
3072 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3073 env, [], self.buffer_defaults_node,
3074 need_complete=False)
3076 buffer_defaults = None
3078 if env.in_cinclude and not self.objstruct_name:
3079 error(self.pos, "Object struct name specification required for "
3080 "C class defined in 'extern from' block")
3081 self.base_type = None
3082 # Now that module imports are cached, we need to
3083 # import the modules for extern classes.
3084 if self.module_name:
3086 for module in env.cimported_modules:
3087 if module.name == self.module_name:
3088 self.module = module
3089 if self.module is None:
3090 self.module = ModuleScope(self.module_name, None, env.context)
3091 self.module.has_extern_class = 1
3092 env.add_imported_module(self.module)
3094 if self.base_class_name:
3095 if self.base_class_module:
3096 base_class_scope = env.find_module(self.base_class_module, self.pos)
3098 base_class_scope = env
3099 if self.base_class_name == 'object':
3100 # extension classes are special and don't need to inherit from object
3101 if base_class_scope is None or base_class_scope.lookup('object') is None:
3102 self.base_class_name = None
3103 self.base_class_module = None
3104 base_class_scope = None
3105 if base_class_scope:
3106 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3107 if base_class_entry:
3108 if not base_class_entry.is_type:
3109 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3110 elif not base_class_entry.type.is_extension_type:
3111 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3112 elif not base_class_entry.type.is_complete():
3113 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3114 self.base_class_name, self.class_name))
3115 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3116 base_class_entry.type.scope.directives['final']:
3117 error(self.pos, "Base class '%s' of type '%s' is final" % (
3118 self.base_class_name, self.class_name))
3120 self.base_type = base_class_entry.type
3121 has_body = self.body is not None
3122 if self.module_name and self.visibility != 'extern':
3123 module_path = self.module_name.split(".")
3124 home_scope = env.find_imported_module(module_path, self.pos)
3130 if self.visibility == 'extern':
3131 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3132 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3134 self.entry = home_scope.declare_c_class(
3135 name = self.class_name,
3137 defining = has_body and self.in_pxd,
3138 implementing = has_body and not self.in_pxd,
3139 module_name = self.module_name,
3140 base_type = self.base_type,
3141 objstruct_cname = self.objstruct_name,
3142 typeobj_cname = self.typeobj_name,
3143 visibility = self.visibility,
3144 typedef_flag = self.typedef_flag,
3146 buffer_defaults = buffer_defaults)
3147 if home_scope is not env and self.visibility == 'extern':
3148 env.add_imported_entry(self.class_name, self.entry, pos)
3149 self.scope = scope = self.entry.type.scope
3150 if scope is not None:
3151 scope.directives = env.directives
3153 if self.doc and Options.docstrings:
3154 scope.doc = embed_position(self.pos, self.doc)
3157 self.body.analyse_declarations(scope)
3161 scope.implemented = 1
3162 env.allocate_vtable_names(self.entry)
3164 def analyse_expressions(self, env):
3166 scope = self.entry.type.scope
3167 self.body.analyse_expressions(scope)
3169 def generate_function_definitions(self, env, code):
3171 self.body.generate_function_definitions(
3172 self.entry.type.scope, code)
3174 def generate_execution_code(self, code):
3175 # This is needed to generate evaluation code for
3176 # default values of method arguments.
3178 self.body.generate_execution_code(code)
3180 def annotate(self, code):
3182 self.body.annotate(code)
3185 class PropertyNode(StatNode):
3186 # Definition of a property in an extension type.
3189 # doc EncodedString or None Doc string
3192 child_attrs = ["body"]
3194 def analyse_declarations(self, env):
3195 entry = env.declare_property(self.name, self.doc, self.pos)
3197 entry.scope.directives = env.directives
3198 self.body.analyse_declarations(entry.scope)
3200 def analyse_expressions(self, env):
3201 self.body.analyse_expressions(env)
3203 def generate_function_definitions(self, env, code):
3204 self.body.generate_function_definitions(env, code)
3206 def generate_execution_code(self, code):
3209 def annotate(self, code):
3210 self.body.annotate(code)
3213 class GlobalNode(StatNode):
3214 # Global variable declaration.
3220 def analyse_declarations(self, env):
3221 for name in self.names:
3222 env.declare_global(name, self.pos)
3224 def analyse_expressions(self, env):
3227 def generate_execution_code(self, code):
3231 class ExprStatNode(StatNode):
3232 # Expression used as a statement.
3236 child_attrs = ["expr"]
3238 def analyse_declarations(self, env):
3240 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3241 func = self.expr.function.as_cython_attribute()
3242 if func == u'declare':
3243 args, kwds = self.expr.explicit_args_kwds()
3245 error(self.expr.pos, "Variable names must be specified.")
3246 for var, type_node in kwds.key_value_pairs:
3247 type = type_node.analyse_as_type(env)
3249 error(type_node.pos, "Unknown type")
3251 env.declare_var(var.value, type, var.pos, is_cdef = True)
3252 self.__class__ = PassStatNode
3254 def analyse_expressions(self, env):
3255 self.expr.analyse_expressions(env)
3257 def generate_execution_code(self, code):
3258 self.expr.generate_evaluation_code(code)
3259 if not self.expr.is_temp and self.expr.result():
3260 code.putln("%s;" % self.expr.result())
3261 self.expr.generate_disposal_code(code)
3262 self.expr.free_temps(code)
3264 def generate_function_definitions(self, env, code):
3265 self.expr.generate_function_definitions(env, code)
3267 def annotate(self, code):
3268 self.expr.annotate(code)
3271 class AssignmentNode(StatNode):
3272 # Abstract base class for assignment nodes.
3274 # The analyse_expressions and generate_execution_code
3275 # phases of assignments are split into two sub-phases
3276 # each, to enable all the right hand sides of a
3277 # parallel assignment to be evaluated before assigning
3278 # to any of the left hand sides.
3280 def analyse_expressions(self, env):
3281 self.analyse_types(env)
3283 # def analyse_expressions(self, env):
3284 # self.analyse_expressions_1(env)
3285 # self.analyse_expressions_2(env)
3287 def generate_execution_code(self, code):
3288 self.generate_rhs_evaluation_code(code)
3289 self.generate_assignment_code(code)
3292 class SingleAssignmentNode(AssignmentNode):
3293 # The simplest case:
3297 # lhs ExprNode Left hand side
3298 # rhs ExprNode Right hand side
3299 # first bool Is this guaranteed the first assignment to lhs?
3301 child_attrs = ["lhs", "rhs"]
3303 declaration_only = False
3305 def analyse_declarations(self, env):
3308 # handle declarations of the form x = cython.foo()
3309 if isinstance(self.rhs, ExprNodes.CallNode):
3310 func_name = self.rhs.function.as_cython_attribute()
3312 args, kwds = self.rhs.explicit_args_kwds()
3314 if func_name in ['declare', 'typedef']:
3315 if len(args) > 2 or kwds is not None:
3316 error(rhs.pos, "Can only declare one type at a time.")
3318 type = args[0].analyse_as_type(env)
3320 error(args[0].pos, "Unknown type")
3323 if func_name == 'declare':
3324 if isinstance(lhs, ExprNodes.NameNode):
3325 vars = [(lhs.name, lhs.pos)]
3326 elif isinstance(lhs, ExprNodes.TupleNode):
3327 vars = [(var.name, var.pos) for var in lhs.args]
3329 error(lhs.pos, "Invalid declaration")
3331 for var, pos in vars:
3332 env.declare_var(var, type, pos, is_cdef = True)
3337 self.declaration_only = True
3339 self.declaration_only = True
3340 if not isinstance(lhs, ExprNodes.NameNode):
3341 error(lhs.pos, "Invalid declaration.")
3342 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3344 elif func_name in ['struct', 'union']:
3345 self.declaration_only = True
3346 if len(args) > 0 or kwds is None:
3347 error(rhs.pos, "Struct or union members must be given by name.")
3350 for member, type_node in kwds.key_value_pairs:
3351 type = type_node.analyse_as_type(env)
3353 error(type_node.pos, "Unknown type")
3355 members.append((member.value, type, member.pos))
3356 if len(members) < len(kwds.key_value_pairs):
3358 if not isinstance(self.lhs, ExprNodes.NameNode):
3359 error(self.lhs.pos, "Invalid declaration.")
3360 name = self.lhs.name
3361 scope = StructOrUnionScope(name)
3362 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3363 for member, type, pos in members:
3364 scope.declare_var(member, type, pos)
3366 if self.declaration_only:
3369 self.lhs.analyse_target_declaration(env)
3371 def analyse_types(self, env, use_temp = 0):
3372 self.rhs.analyse_types(env)
3373 self.lhs.analyse_target_types(env)
3374 self.lhs.gil_assignment_check(env)
3375 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3377 self.rhs = self.rhs.coerce_to_temp(env)
3379 def generate_rhs_evaluation_code(self, code):
3380 self.rhs.generate_evaluation_code(code)
3382 def generate_assignment_code(self, code):
3383 self.lhs.generate_assignment_code(self.rhs, code)
3385 def generate_function_definitions(self, env, code):
3386 self.rhs.generate_function_definitions(env, code)
3388 def annotate(self, code):
3389 self.lhs.annotate(code)
3390 self.rhs.annotate(code)
3393 class CascadedAssignmentNode(AssignmentNode):
3394 # An assignment with multiple left hand sides:
3398 # lhs_list [ExprNode] Left hand sides
3399 # rhs ExprNode Right hand sides
3403 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3405 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3406 coerced_rhs_list = None
3408 def analyse_declarations(self, env):
3409 for lhs in self.lhs_list:
3410 lhs.analyse_target_declaration(env)
3412 def analyse_types(self, env, use_temp = 0):
3413 self.rhs.analyse_types(env)
3414 if not self.rhs.is_simple():
3416 self.rhs = self.rhs.coerce_to_temp(env)
3418 self.rhs = self.rhs.coerce_to_simple(env)
3419 from ExprNodes import CloneNode
3420 self.coerced_rhs_list = []
3421 for lhs in self.lhs_list:
3422 lhs.analyse_target_types(env)
3423 lhs.gil_assignment_check(env)
3424 rhs = CloneNode(self.rhs)
3425 rhs = rhs.coerce_to(lhs.type, env)
3426 self.coerced_rhs_list.append(rhs)
3428 def generate_rhs_evaluation_code(self, code):
3429 self.rhs.generate_evaluation_code(code)
3431 def generate_assignment_code(self, code):
3432 for i in range(len(self.lhs_list)):
3433 lhs = self.lhs_list[i]
3434 rhs = self.coerced_rhs_list[i]
3435 rhs.generate_evaluation_code(code)
3436 lhs.generate_assignment_code(rhs, code)
3437 # Assignment has disposed of the cloned RHS
3438 self.rhs.generate_disposal_code(code)
3439 self.rhs.free_temps(code)
3441 def generate_function_definitions(self, env, code):
3442 self.rhs.generate_function_definitions(env, code)
3444 def annotate(self, code):
3445 for i in range(len(self.lhs_list)):
3446 lhs = self.lhs_list[i].annotate(code)
3447 rhs = self.coerced_rhs_list[i].annotate(code)
3448 self.rhs.annotate(code)
3451 class ParallelAssignmentNode(AssignmentNode):
3452 # A combined packing/unpacking assignment:
3456 # This has been rearranged by the parser into
3458 # a = d ; b = e ; c = f
3460 # but we must evaluate all the right hand sides
3461 # before assigning to any of the left hand sides.
3463 # stats [AssignmentNode] The constituent assignments
3465 child_attrs = ["stats"]
3467 def analyse_declarations(self, env):
3468 for stat in self.stats:
3469 stat.analyse_declarations(env)
3471 def analyse_expressions(self, env):
3472 for stat in self.stats:
3473 stat.analyse_types(env, use_temp = 1)
3475 # def analyse_expressions(self, env):
3476 # for stat in self.stats:
3477 # stat.analyse_expressions_1(env, use_temp = 1)
3478 # for stat in self.stats:
3479 # stat.analyse_expressions_2(env)
3481 def generate_execution_code(self, code):
3482 for stat in self.stats:
3483 stat.generate_rhs_evaluation_code(code)
3484 for stat in self.stats:
3485 stat.generate_assignment_code(code)
3487 def generate_function_definitions(self, env, code):
3488 for stat in self.stats:
3489 stat.generate_function_definitions(env, code)
3491 def annotate(self, code):
3492 for stat in self.stats:
3496 class InPlaceAssignmentNode(AssignmentNode):
3497 # An in place arithmetic operand:
3503 # lhs ExprNode Left hand side
3504 # rhs ExprNode Right hand side
3505 # op char one of "+-*/%^&|"
3506 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3508 # This code is a bit tricky because in order to obey Python
3509 # semantics the sub-expressions (e.g. indices) of the lhs must
3510 # not be evaluated twice. So we must re-use the values calculated
3511 # in evaluation phase for the assignment phase as well.
3512 # Fortunately, the type of the lhs node is fairly constrained
3513 # (it must be a NameNode, AttributeNode, or IndexNode).
3515 child_attrs = ["lhs", "rhs"]
3518 def analyse_declarations(self, env):
3519 self.lhs.analyse_target_declaration(env)
3521 def analyse_types(self, env):
3522 self.dup = self.create_dup_node(env) # re-assigns lhs to a shallow copy
3523 self.rhs.analyse_types(env)
3524 self.lhs.analyse_target_types(env)
3526 if self.lhs.type.is_pyobject:
3527 self.rhs = self.rhs.coerce_to_pyobject(env)
3528 elif self.rhs.type.is_pyobject or (self.lhs.type.is_numeric and self.rhs.type.is_numeric):
3529 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3530 if self.lhs.type.is_pyobject:
3531 self.result_value_temp = ExprNodes.PyTempNode(self.pos, env)
3532 self.result_value = self.result_value_temp.coerce_to(self.lhs.type, env)
3534 def generate_execution_code(self, code):
3536 self.rhs.generate_evaluation_code(code)
3537 self.dup.generate_subexpr_evaluation_code(code)
3538 if self.dup.is_temp:
3539 self.dup.allocate_temp_result(code)
3540 # self.dup.generate_result_code is run only if it is not buffer access
3541 if self.operator == "**":
3545 if self.lhs.type.is_pyobject:
3546 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3547 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3548 self.dup.generate_result_code(code)
3549 self.result_value_temp.allocate(code)
3551 "%s = %s(%s, %s%s); %s" % (
3552 self.result_value.result(),
3553 self.py_operation_function(),
3554 self.dup.py_result(),
3555 self.rhs.py_result(),
3557 code.error_goto_if_null(self.result_value.py_result(), self.pos)))
3558 code.put_gotref(self.result_value.py_result())
3559 self.result_value.generate_evaluation_code(code) # May be a type check...
3560 self.rhs.generate_disposal_code(code)
3561 self.rhs.free_temps(code)
3562 self.dup.generate_disposal_code(code)
3563 self.dup.free_temps(code)
3564 self.lhs.generate_assignment_code(self.result_value, code)
3565 self.result_value_temp.release(code)
3567 c_op = self.operator
3571 error(self.pos, "No C inplace power operator")
3572 elif self.lhs.type.is_complex:
3573 error(self.pos, "Inplace operators not implemented for complex types.")
3575 # have to do assignment directly to avoid side-effects
3576 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3577 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3579 self.dup.generate_result_code(code)
3580 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()) )
3581 self.rhs.generate_disposal_code(code)
3582 self.rhs.free_temps(code)
3583 if self.dup.is_temp:
3584 self.dup.generate_subexpr_disposal_code(code)
3585 self.dup.free_subexpr_temps(code)
3587 def create_dup_node(self, env):
3590 self.dup.analyse_types(env)
3591 if isinstance(self.lhs, ExprNodes.NameNode):
3592 target_lhs = ExprNodes.NameNode(self.dup.pos,
3593 name = self.dup.name,
3594 is_temp = self.dup.is_temp,
3595 entry = self.dup.entry)
3596 elif isinstance(self.lhs, ExprNodes.AttributeNode):
3597 target_lhs = ExprNodes.AttributeNode(self.dup.pos,
3598 obj = ExprNodes.CloneNode(self.lhs.obj),
3599 attribute = self.dup.attribute,
3600 is_temp = self.dup.is_temp)
3601 elif isinstance(self.lhs, ExprNodes.IndexNode):
3603 index = ExprNodes.CloneNode(self.lhs.index)
3606 if self.lhs.indices:
3607 indices = [ExprNodes.CloneNode(x) for x in self.lhs.indices]
3610 target_lhs = ExprNodes.IndexNode(self.dup.pos,
3611 base = ExprNodes.CloneNode(self.dup.base),
3614 is_temp = self.dup.is_temp)
3616 assert False, "Unsupported node: %s" % type(self.lhs)
3617 self.lhs = target_lhs
3620 def py_operation_function(self):
3621 return self.py_functions[self.operator]
3624 "|": "PyNumber_InPlaceOr",
3625 "^": "PyNumber_InPlaceXor",
3626 "&": "PyNumber_InPlaceAnd",
3627 "+": "PyNumber_InPlaceAdd",
3628 "-": "PyNumber_InPlaceSubtract",
3629 "*": "PyNumber_InPlaceMultiply",
3630 "/": "__Pyx_PyNumber_InPlaceDivide",
3631 "%": "PyNumber_InPlaceRemainder",
3632 "<<": "PyNumber_InPlaceLshift",
3633 ">>": "PyNumber_InPlaceRshift",
3634 "**": "PyNumber_InPlacePower",
3635 "//": "PyNumber_InPlaceFloorDivide",
3638 def annotate(self, code):
3639 self.lhs.annotate(code)
3640 self.rhs.annotate(code)
3641 self.dup.annotate(code)
3643 def create_binop_node(self):
3645 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3648 class PrintStatNode(StatNode):
3651 # arg_tuple TupleNode
3652 # stream ExprNode or None (stdout)
3653 # append_newline boolean
3655 child_attrs = ["arg_tuple", "stream"]
3657 def analyse_expressions(self, env):
3659 self.stream.analyse_expressions(env)
3660 self.stream = self.stream.coerce_to_pyobject(env)
3661 self.arg_tuple.analyse_expressions(env)
3662 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3663 env.use_utility_code(printing_utility_code)
3664 if len(self.arg_tuple.args) == 1 and self.append_newline:
3665 env.use_utility_code(printing_one_utility_code)
3667 nogil_check = Node.gil_error
3668 gil_message = "Python print statement"
3670 def generate_execution_code(self, code):
3672 self.stream.generate_evaluation_code(code)
3673 stream_result = self.stream.py_result()
3676 if len(self.arg_tuple.args) == 1 and self.append_newline:
3677 arg = self.arg_tuple.args[0]
3678 arg.generate_evaluation_code(code)
3681 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3684 code.error_goto(self.pos)))
3685 arg.generate_disposal_code(code)
3686 arg.free_temps(code)
3688 self.arg_tuple.generate_evaluation_code(code)
3690 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3692 self.arg_tuple.py_result(),
3693 self.append_newline,
3694 code.error_goto(self.pos)))
3695 self.arg_tuple.generate_disposal_code(code)
3696 self.arg_tuple.free_temps(code)
3699 self.stream.generate_disposal_code(code)
3700 self.stream.free_temps(code)
3702 def generate_function_definitions(self, env, code):
3704 self.stream.generate_function_definitions(env, code)
3705 self.arg_tuple.generate_function_definitions(env, code)
3707 def annotate(self, code):
3709 self.stream.annotate(code)
3710 self.arg_tuple.annotate(code)
3713 class ExecStatNode(StatNode):
3718 child_attrs = ["args"]
3720 def analyse_expressions(self, env):
3721 for i, arg in enumerate(self.args):
3722 arg.analyse_expressions(env)
3723 arg = arg.coerce_to_pyobject(env)
3725 env.use_utility_code(Builtin.pyexec_utility_code)
3727 nogil_check = Node.gil_error
3728 gil_message = "Python exec statement"
3730 def generate_execution_code(self, code):
3732 for arg in self.args:
3733 arg.generate_evaluation_code(code)
3734 args.append( arg.py_result() )
3735 args = tuple(args + ['0', '0'][:3-len(args)])
3736 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3737 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3738 (temp_result,) + args))
3739 for arg in self.args:
3740 arg.generate_disposal_code(code)
3741 arg.free_temps(code)
3743 code.error_goto_if_null(temp_result, self.pos))
3744 code.put_gotref(temp_result)
3745 code.put_decref_clear(temp_result, py_object_type)
3746 code.funcstate.release_temp(temp_result)
3748 def annotate(self, code):
3749 for arg in self.args:
3753 class DelStatNode(StatNode):
3758 child_attrs = ["args"]
3760 def analyse_declarations(self, env):
3761 for arg in self.args:
3762 arg.analyse_target_declaration(env)
3764 def analyse_expressions(self, env):
3765 for arg in self.args:
3766 arg.analyse_target_expression(env, None)
3767 if arg.type.is_pyobject:
3769 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3771 elif arg.type.is_cpp_class:
3772 error(arg.pos, "Deletion of non-heap C++ object")
3774 error(arg.pos, "Deletion of non-Python, non-C++ object")
3775 #arg.release_target_temp(env)
3777 def nogil_check(self, env):
3778 for arg in self.args:
3779 if arg.type.is_pyobject:
3782 gil_message = "Deleting Python object"
3784 def generate_execution_code(self, code):
3785 for arg in self.args:
3786 if arg.type.is_pyobject:
3787 arg.generate_deletion_code(code)
3788 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3789 arg.generate_result_code(code)
3790 code.putln("delete %s;" % arg.result())
3791 # else error reported earlier
3793 def annotate(self, code):
3794 for arg in self.args:
3798 class PassStatNode(StatNode):
3803 def analyse_expressions(self, env):
3806 def generate_execution_code(self, code):
3810 class BreakStatNode(StatNode):
3814 def analyse_expressions(self, env):
3817 def generate_execution_code(self, code):
3818 if not code.break_label:
3819 error(self.pos, "break statement not inside loop")
3821 code.put_goto(code.break_label)
3824 class ContinueStatNode(StatNode):
3828 def analyse_expressions(self, env):
3831 def generate_execution_code(self, code):
3832 if code.funcstate.in_try_finally:
3833 error(self.pos, "continue statement inside try of try...finally")
3834 elif not code.continue_label:
3835 error(self.pos, "continue statement not inside loop")
3837 code.put_goto(code.continue_label)
3840 class ReturnStatNode(StatNode):
3843 # value ExprNode or None
3844 # return_type PyrexType
3846 child_attrs = ["value"]
3848 def analyse_expressions(self, env):
3849 return_type = env.return_type
3850 self.return_type = return_type
3852 error(self.pos, "Return not inside a function body")
3855 self.value.analyse_types(env)
3856 if return_type.is_void or return_type.is_returncode:
3857 error(self.value.pos,
3858 "Return with value in void function")
3860 self.value = self.value.coerce_to(env.return_type, env)
3862 if (not return_type.is_void
3863 and not return_type.is_pyobject
3864 and not return_type.is_returncode):
3865 error(self.pos, "Return value required")
3867 def nogil_check(self, env):
3868 if self.return_type.is_pyobject:
3871 gil_message = "Returning Python object"
3873 def generate_execution_code(self, code):
3874 code.mark_pos(self.pos)
3875 if not self.return_type:
3876 # error reported earlier
3878 if self.return_type.is_pyobject:
3879 code.put_xdecref(Naming.retval_cname,
3882 self.value.generate_evaluation_code(code)
3883 self.value.make_owned_reference(code)
3886 Naming.retval_cname,
3887 self.value.result_as(self.return_type)))
3888 self.value.generate_post_assignment_code(code)
3889 self.value.free_temps(code)
3891 if self.return_type.is_pyobject:
3892 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3893 elif self.return_type.is_returncode:
3896 Naming.retval_cname,
3897 self.return_type.default_value))
3898 for cname, type in code.funcstate.temps_holding_reference():
3899 code.put_decref_clear(cname, type)
3900 code.put_goto(code.return_label)
3902 def generate_function_definitions(self, env, code):
3903 if self.value is not None:
3904 self.value.generate_function_definitions(env, code)
3906 def annotate(self, code):
3908 self.value.annotate(code)
3911 class RaiseStatNode(StatNode):
3914 # exc_type ExprNode or None
3915 # exc_value ExprNode or None
3916 # exc_tb ExprNode or None
3918 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3920 def analyse_expressions(self, env):
3922 self.exc_type.analyse_types(env)
3923 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3925 self.exc_value.analyse_types(env)
3926 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3928 self.exc_tb.analyse_types(env)
3929 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3930 env.use_utility_code(raise_utility_code)
3932 nogil_check = Node.gil_error
3933 gil_message = "Raising exception"
3935 def generate_execution_code(self, code):
3937 self.exc_type.generate_evaluation_code(code)
3938 type_code = self.exc_type.py_result()
3942 self.exc_value.generate_evaluation_code(code)
3943 value_code = self.exc_value.py_result()
3947 self.exc_tb.generate_evaluation_code(code)
3948 tb_code = self.exc_tb.py_result()
3952 "__Pyx_Raise(%s, %s, %s);" % (
3956 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3958 obj.generate_disposal_code(code)
3959 obj.free_temps(code)
3961 code.error_goto(self.pos))
3963 def generate_function_definitions(self, env, code):
3964 if self.exc_type is not None:
3965 self.exc_type.generate_function_definitions(env, code)
3966 if self.exc_value is not None:
3967 self.exc_value.generate_function_definitions(env, code)
3968 if self.exc_tb is not None:
3969 self.exc_tb.generate_function_definitions(env, code)
3971 def annotate(self, code):
3973 self.exc_type.annotate(code)
3975 self.exc_value.annotate(code)
3977 self.exc_tb.annotate(code)
3980 class ReraiseStatNode(StatNode):
3984 def analyse_expressions(self, env):
3985 env.use_utility_code(restore_exception_utility_code)
3987 nogil_check = Node.gil_error
3988 gil_message = "Raising exception"
3990 def generate_execution_code(self, code):
3991 vars = code.funcstate.exc_vars
3993 for varname in vars:
3994 code.put_giveref(varname)
3995 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
3996 for varname in vars:
3997 code.put("%s = 0; " % varname)
3999 code.putln(code.error_goto(self.pos))
4001 error(self.pos, "Reraise not inside except clause")
4004 class AssertStatNode(StatNode):
4008 # value ExprNode or None
4010 child_attrs = ["cond", "value"]
4012 def analyse_expressions(self, env):
4013 self.cond = self.cond.analyse_boolean_expression(env)
4015 self.value.analyse_types(env)
4016 self.value = self.value.coerce_to_pyobject(env)
4018 nogil_check = Node.gil_error
4019 gil_message = "Raising exception"
4021 def generate_execution_code(self, code):
4022 code.putln("#ifndef PYREX_WITHOUT_ASSERTIONS")
4023 self.cond.generate_evaluation_code(code)
4025 "if (unlikely(!%s)) {" %
4028 self.value.generate_evaluation_code(code)
4030 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4031 self.value.py_result())
4032 self.value.generate_disposal_code(code)
4033 self.value.free_temps(code)
4036 "PyErr_SetNone(PyExc_AssertionError);")
4038 code.error_goto(self.pos))
4041 self.cond.generate_disposal_code(code)
4042 self.cond.free_temps(code)
4043 code.putln("#endif")
4045 def generate_function_definitions(self, env, code):
4046 self.cond.generate_function_definitions(env, code)
4047 if self.value is not None:
4048 self.value.generate_function_definitions(env, code)
4050 def annotate(self, code):
4051 self.cond.annotate(code)
4053 self.value.annotate(code)
4056 class IfStatNode(StatNode):
4059 # if_clauses [IfClauseNode]
4060 # else_clause StatNode or None
4062 child_attrs = ["if_clauses", "else_clause"]
4064 def analyse_control_flow(self, env):
4065 env.start_branching(self.pos)
4066 for if_clause in self.if_clauses:
4067 if_clause.analyse_control_flow(env)
4068 env.next_branch(if_clause.end_pos())
4069 if self.else_clause:
4070 self.else_clause.analyse_control_flow(env)
4071 env.finish_branching(self.end_pos())
4073 def analyse_declarations(self, env):
4074 for if_clause in self.if_clauses:
4075 if_clause.analyse_declarations(env)
4076 if self.else_clause:
4077 self.else_clause.analyse_declarations(env)
4079 def analyse_expressions(self, env):
4080 for if_clause in self.if_clauses:
4081 if_clause.analyse_expressions(env)
4082 if self.else_clause:
4083 self.else_clause.analyse_expressions(env)
4085 def generate_execution_code(self, code):
4086 code.mark_pos(self.pos)
4087 end_label = code.new_label()
4088 for if_clause in self.if_clauses:
4089 if_clause.generate_execution_code(code, end_label)
4090 if self.else_clause:
4091 code.putln("/*else*/ {")
4092 self.else_clause.generate_execution_code(code)
4094 code.put_label(end_label)
4096 def generate_function_definitions(self, env, code):
4097 for clause in self.if_clauses:
4098 clause.generate_function_definitions(env, code)
4099 if self.else_clause is not None:
4100 self.else_clause.generate_function_definitions(env, code)
4102 def annotate(self, code):
4103 for if_clause in self.if_clauses:
4104 if_clause.annotate(code)
4105 if self.else_clause:
4106 self.else_clause.annotate(code)
4109 class IfClauseNode(Node):
4110 # if or elif clause in an if statement
4112 # condition ExprNode
4115 child_attrs = ["condition", "body"]
4117 def analyse_control_flow(self, env):
4118 self.body.analyse_control_flow(env)
4120 def analyse_declarations(self, env):
4121 self.condition.analyse_declarations(env)
4122 self.body.analyse_declarations(env)
4124 def analyse_expressions(self, env):
4126 self.condition.analyse_temp_boolean_expression(env)
4127 self.body.analyse_expressions(env)
4129 def get_constant_condition_result(self):
4130 if self.condition.has_constant_result():
4131 return bool(self.condition.constant_result)
4135 def generate_execution_code(self, code, end_label):
4136 self.condition.generate_evaluation_code(code)
4139 self.condition.result())
4140 self.condition.generate_disposal_code(code)
4141 self.condition.free_temps(code)
4142 self.body.generate_execution_code(code)
4143 code.put_goto(end_label)
4146 def generate_function_definitions(self, env, code):
4147 self.condition.generate_function_definitions(env, code)
4148 self.body.generate_function_definitions(env, code)
4150 def annotate(self, code):
4151 self.condition.annotate(code)
4152 self.body.annotate(code)
4155 class SwitchCaseNode(StatNode):
4156 # Generated in the optimization of an if-elif-else node
4158 # conditions [ExprNode]
4161 child_attrs = ['conditions', 'body']
4163 def generate_execution_code(self, code):
4164 for cond in self.conditions:
4165 code.mark_pos(cond.pos)
4166 cond.generate_evaluation_code(code)
4167 code.putln("case %s:" % cond.result())
4168 self.body.generate_execution_code(code)
4169 code.putln("break;")
4171 def generate_function_definitions(self, env, code):
4172 for cond in self.conditions:
4173 cond.generate_function_definitions(env, code)
4174 self.body.generate_function_definitions(env, code)
4176 def annotate(self, code):
4177 for cond in self.conditions:
4179 self.body.annotate(code)
4181 class SwitchStatNode(StatNode):
4182 # Generated in the optimization of an if-elif-else node
4185 # cases [SwitchCaseNode]
4186 # else_clause StatNode or None
4188 child_attrs = ['test', 'cases', 'else_clause']
4190 def generate_execution_code(self, code):
4191 code.putln("switch (%s) {" % self.test.result())
4192 for case in self.cases:
4193 case.generate_execution_code(code)
4194 if self.else_clause is not None:
4195 code.putln("default:")
4196 self.else_clause.generate_execution_code(code)
4197 code.putln("break;")
4200 def generate_function_definitions(self, env, code):
4201 self.test.generate_function_definitions(env, code)
4202 for case in self.cases:
4203 case.generate_function_definitions(env, code)
4204 if self.else_clause is not None:
4205 self.else_clause.generate_function_definitions(env, code)
4207 def annotate(self, code):
4208 self.test.annotate(code)
4209 for case in self.cases:
4211 if self.else_clause is not None:
4212 self.else_clause.annotate(code)
4214 class LoopNode(object):
4216 def analyse_control_flow(self, env):
4217 env.start_branching(self.pos)
4218 self.body.analyse_control_flow(env)
4219 env.next_branch(self.body.end_pos())
4220 if self.else_clause:
4221 self.else_clause.analyse_control_flow(env)
4222 env.finish_branching(self.end_pos())
4225 class WhileStatNode(LoopNode, StatNode):
4228 # condition ExprNode
4230 # else_clause StatNode
4232 child_attrs = ["condition", "body", "else_clause"]
4234 def analyse_declarations(self, env):
4235 self.body.analyse_declarations(env)
4236 if self.else_clause:
4237 self.else_clause.analyse_declarations(env)
4239 def analyse_expressions(self, env):
4241 self.condition.analyse_temp_boolean_expression(env)
4242 self.body.analyse_expressions(env)
4243 if self.else_clause:
4244 self.else_clause.analyse_expressions(env)
4246 def generate_execution_code(self, code):
4247 old_loop_labels = code.new_loop_labels()
4250 self.condition.generate_evaluation_code(code)
4251 self.condition.generate_disposal_code(code)
4254 self.condition.result())
4255 self.condition.free_temps(code)
4256 self.body.generate_execution_code(code)
4257 code.put_label(code.continue_label)
4259 break_label = code.break_label
4260 code.set_loop_labels(old_loop_labels)
4261 if self.else_clause:
4262 code.putln("/*else*/ {")
4263 self.else_clause.generate_execution_code(code)
4265 code.put_label(break_label)
4267 def generate_function_definitions(self, env, code):
4268 self.condition.generate_function_definitions(env, code)
4269 self.body.generate_function_definitions(env, code)
4270 if self.else_clause is not None:
4271 self.else_clause.generate_function_definitions(env, code)
4273 def annotate(self, code):
4274 self.condition.annotate(code)
4275 self.body.annotate(code)
4276 if self.else_clause:
4277 self.else_clause.annotate(code)
4280 def ForStatNode(pos, **kw):
4281 if 'iterator' in kw:
4282 return ForInStatNode(pos, **kw)
4284 return ForFromStatNode(pos, **kw)
4286 class ForInStatNode(LoopNode, StatNode):
4290 # iterator IteratorNode
4292 # else_clause StatNode
4293 # item NextNode used internally
4295 child_attrs = ["target", "iterator", "body", "else_clause"]
4298 def analyse_declarations(self, env):
4299 self.target.analyse_target_declaration(env)
4300 self.body.analyse_declarations(env)
4301 if self.else_clause:
4302 self.else_clause.analyse_declarations(env)
4304 def analyse_expressions(self, env):
4306 self.target.analyse_target_types(env)
4307 self.iterator.analyse_expressions(env)
4308 self.item = ExprNodes.NextNode(self.iterator, env)
4309 self.item = self.item.coerce_to(self.target.type, env)
4310 self.body.analyse_expressions(env)
4311 if self.else_clause:
4312 self.else_clause.analyse_expressions(env)
4314 def generate_execution_code(self, code):
4315 old_loop_labels = code.new_loop_labels()
4316 self.iterator.allocate_counter_temp(code)
4317 self.iterator.generate_evaluation_code(code)
4320 self.item.generate_evaluation_code(code)
4321 self.target.generate_assignment_code(self.item, code)
4322 self.body.generate_execution_code(code)
4323 code.put_label(code.continue_label)
4326 break_label = code.break_label
4327 code.set_loop_labels(old_loop_labels)
4329 if self.else_clause:
4330 # in nested loops, the 'else' block can contain a
4331 # 'continue' statement for the outer loop, but we may need
4332 # to generate cleanup code before taking that path, so we
4334 orig_continue_label = code.continue_label
4335 code.continue_label = code.new_label('outer_continue')
4337 code.putln("/*else*/ {")
4338 self.else_clause.generate_execution_code(code)
4341 if code.label_used(code.continue_label):
4342 code.put_goto(break_label)
4343 code.put_label(code.continue_label)
4344 self.iterator.generate_disposal_code(code)
4345 code.put_goto(orig_continue_label)
4346 code.set_loop_labels(old_loop_labels)
4348 if code.label_used(break_label):
4349 code.put_label(break_label)
4350 self.iterator.release_counter_temp(code)
4351 self.iterator.generate_disposal_code(code)
4352 self.iterator.free_temps(code)
4354 def generate_function_definitions(self, env, code):
4355 self.target.generate_function_definitions(env, code)
4356 self.iterator.generate_function_definitions(env, code)
4357 self.body.generate_function_definitions(env, code)
4358 if self.else_clause is not None:
4359 self.else_clause.generate_function_definitions(env, code)
4361 def annotate(self, code):
4362 self.target.annotate(code)
4363 self.iterator.annotate(code)
4364 self.body.annotate(code)
4365 if self.else_clause:
4366 self.else_clause.annotate(code)
4367 self.item.annotate(code)
4370 class ForFromStatNode(LoopNode, StatNode):
4371 # for name from expr rel name rel expr
4378 # step ExprNode or None
4380 # else_clause StatNode or None
4386 # loopvar_node ExprNode (usually a NameNode or temp node)
4387 # py_loopvar_node PyTempNode or None
4388 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4390 is_py_target = False
4392 py_loopvar_node = None
4395 gil_message = "For-loop using object bounds or target"
4397 def nogil_check(self, env):
4398 for x in (self.target, self.bound1, self.bound2):
4399 if x.type.is_pyobject:
4402 def analyse_declarations(self, env):
4403 self.target.analyse_target_declaration(env)
4404 self.body.analyse_declarations(env)
4405 if self.else_clause:
4406 self.else_clause.analyse_declarations(env)
4408 def analyse_expressions(self, env):
4410 self.target.analyse_target_types(env)
4411 self.bound1.analyse_types(env)
4412 self.bound2.analyse_types(env)
4413 if self.step is not None:
4414 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4415 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4416 self.step.analyse_types(env)
4418 target_type = self.target.type
4419 if self.target.type.is_numeric:
4420 loop_type = self.target.type
4422 loop_type = PyrexTypes.c_int_type
4423 if not self.bound1.type.is_pyobject:
4424 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4425 if not self.bound2.type.is_pyobject:
4426 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4427 if self.step is not None and not self.step.type.is_pyobject:
4428 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4429 self.bound1 = self.bound1.coerce_to(loop_type, env)
4430 self.bound2 = self.bound2.coerce_to(loop_type, env)
4431 if not self.bound2.is_literal:
4432 self.bound2 = self.bound2.coerce_to_temp(env)
4433 if self.step is not None:
4434 self.step = self.step.coerce_to(loop_type, env)
4435 if not self.step.is_literal:
4436 self.step = self.step.coerce_to_temp(env)
4438 target_type = self.target.type
4439 if not (target_type.is_pyobject or target_type.is_numeric):
4440 error(self.target.pos,
4441 "for-from loop variable must be c numeric type or Python object")
4442 if target_type.is_numeric:
4443 self.is_py_target = False
4444 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4445 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4446 self.loopvar_node = self.target
4447 self.py_loopvar_node = None
4449 self.is_py_target = True
4450 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4451 self.loopvar_node = c_loopvar_node
4452 self.py_loopvar_node = \
4453 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4454 self.body.analyse_expressions(env)
4455 if self.else_clause:
4456 self.else_clause.analyse_expressions(env)
4458 def generate_execution_code(self, code):
4459 old_loop_labels = code.new_loop_labels()
4460 from_range = self.from_range
4461 self.bound1.generate_evaluation_code(code)
4462 self.bound2.generate_evaluation_code(code)
4463 offset, incop = self.relation_table[self.relation1]
4464 if self.step is not None:
4465 self.step.generate_evaluation_code(code)
4466 step = self.step.result()
4467 incop = "%s=%s" % (incop[0], step)
4469 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4470 self.loopvar_node.allocate(code)
4471 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4472 self.py_loopvar_node.allocate(code)
4474 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4476 loopvar_name = self.loopvar_node.result()
4478 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4480 self.bound1.result(), offset,
4481 loopvar_name, self.relation2, self.bound2.result(),
4482 loopvar_name, incop))
4483 if self.py_loopvar_node:
4484 self.py_loopvar_node.generate_evaluation_code(code)
4485 self.target.generate_assignment_code(self.py_loopvar_node, code)
4487 code.putln("%s = %s;" % (
4488 self.target.result(), loopvar_name))
4489 self.body.generate_execution_code(code)
4490 code.put_label(code.continue_label)
4491 if self.py_loopvar_node:
4492 # This mess is to make for..from loops with python targets behave
4493 # exactly like those with C targets with regards to re-assignment
4494 # of the loop variable.
4496 if self.target.entry.is_pyglobal:
4497 # We know target is a NameNode, this is the only ugly case.
4498 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4499 target_node.allocate(code)
4500 interned_cname = code.intern_identifier(self.target.entry.name)
4501 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4502 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4503 target_node.result(),
4504 Naming.module_cname,
4506 code.error_goto_if_null(target_node.result(), self.target.pos)))
4507 code.put_gotref(target_node.result())
4509 target_node = self.target
4510 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4511 from_py_node.temp_code = loopvar_name
4512 from_py_node.generate_result_code(code)
4513 if self.target.entry.is_pyglobal:
4514 code.put_decref(target_node.result(), target_node.type)
4515 target_node.release(code)
4517 if self.py_loopvar_node:
4518 # This is potentially wasteful, but we don't want the semantics to
4519 # depend on whether or not the loop is a python type.
4520 self.py_loopvar_node.generate_evaluation_code(code)
4521 self.target.generate_assignment_code(self.py_loopvar_node, code)
4523 code.funcstate.release_temp(loopvar_name)
4524 break_label = code.break_label
4525 code.set_loop_labels(old_loop_labels)
4526 if self.else_clause:
4527 code.putln("/*else*/ {")
4528 self.else_clause.generate_execution_code(code)
4530 code.put_label(break_label)
4531 self.bound1.generate_disposal_code(code)
4532 self.bound1.free_temps(code)
4533 self.bound2.generate_disposal_code(code)
4534 self.bound2.free_temps(code)
4535 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4536 self.loopvar_node.release(code)
4537 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4538 self.py_loopvar_node.release(code)
4539 if self.step is not None:
4540 self.step.generate_disposal_code(code)
4541 self.step.free_temps(code)
4544 # {relop : (initial offset, increment op)}
4551 def generate_function_definitions(self, env, code):
4552 self.target.generate_function_definitions(env, code)
4553 self.bound1.generate_function_definitions(env, code)
4554 self.bound2.generate_function_definitions(env, code)
4555 if self.step is not None:
4556 self.step.generate_function_definitions(env, code)
4557 self.body.generate_function_definitions(env, code)
4558 if self.else_clause is not None:
4559 self.else_clause.generate_function_definitions(env, code)
4561 def annotate(self, code):
4562 self.target.annotate(code)
4563 self.bound1.annotate(code)
4564 self.bound2.annotate(code)
4566 self.step.annotate(code)
4567 self.body.annotate(code)
4568 if self.else_clause:
4569 self.else_clause.annotate(code)
4572 class WithStatNode(StatNode):
4574 Represents a Python with statement.
4576 This is only used at parse tree level; and is not present in
4577 analysis or generation phases.
4579 # manager The with statement manager object
4580 # target Node (lhs expression)
4582 child_attrs = ["manager", "target", "body"]
4584 class TryExceptStatNode(StatNode):
4585 # try .. except statement
4588 # except_clauses [ExceptClauseNode]
4589 # else_clause StatNode or None
4591 child_attrs = ["body", "except_clauses", "else_clause"]
4593 def analyse_control_flow(self, env):
4594 env.start_branching(self.pos)
4595 self.body.analyse_control_flow(env)
4596 successful_try = env.control_flow # grab this for later
4597 env.next_branch(self.body.end_pos())
4598 env.finish_branching(self.body.end_pos())
4600 env.start_branching(self.except_clauses[0].pos)
4601 for except_clause in self.except_clauses:
4602 except_clause.analyse_control_flow(env)
4603 env.next_branch(except_clause.end_pos())
4605 # the else cause it executed only when the try clause finishes
4606 env.control_flow.incoming = successful_try
4607 if self.else_clause:
4608 self.else_clause.analyse_control_flow(env)
4609 env.finish_branching(self.end_pos())
4611 def analyse_declarations(self, env):
4612 self.body.analyse_declarations(env)
4613 for except_clause in self.except_clauses:
4614 except_clause.analyse_declarations(env)
4615 if self.else_clause:
4616 self.else_clause.analyse_declarations(env)
4617 env.use_utility_code(reset_exception_utility_code)
4619 def analyse_expressions(self, env):
4620 self.body.analyse_expressions(env)
4621 default_clause_seen = 0
4622 for except_clause in self.except_clauses:
4623 except_clause.analyse_expressions(env)
4624 if default_clause_seen:
4625 error(except_clause.pos, "default 'except:' must be last")
4626 if not except_clause.pattern:
4627 default_clause_seen = 1
4628 self.has_default_clause = default_clause_seen
4629 if self.else_clause:
4630 self.else_clause.analyse_expressions(env)
4632 nogil_check = Node.gil_error
4633 gil_message = "Try-except statement"
4635 def generate_execution_code(self, code):
4636 old_return_label = code.return_label
4637 old_break_label = code.break_label
4638 old_continue_label = code.continue_label
4639 old_error_label = code.new_error_label()
4640 our_error_label = code.error_label
4641 except_end_label = code.new_label('exception_handled')
4642 except_error_label = code.new_label('except_error')
4643 except_return_label = code.new_label('except_return')
4644 try_return_label = code.new_label('try_return')
4645 try_break_label = code.new_label('try_break')
4646 try_continue_label = code.new_label('try_continue')
4647 try_end_label = code.new_label('try_end')
4650 code.putln("PyObject %s;" %
4651 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4652 code.putln("__Pyx_ExceptionSave(%s);" %
4653 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4654 for var in Naming.exc_save_vars:
4655 code.put_xgotref(var)
4658 code.return_label = try_return_label
4659 code.break_label = try_break_label
4660 code.continue_label = try_continue_label
4661 self.body.generate_execution_code(code)
4664 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4665 code.error_label = except_error_label
4666 code.return_label = except_return_label
4667 if self.else_clause:
4670 self.else_clause.generate_execution_code(code)
4673 for var in Naming.exc_save_vars:
4674 code.put_xdecref_clear(var, py_object_type)
4675 code.put_goto(try_end_label)
4676 if code.label_used(try_return_label):
4677 code.put_label(try_return_label)
4678 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4679 code.putln("__Pyx_ExceptionReset(%s);" %
4680 ', '.join(Naming.exc_save_vars))
4681 code.put_goto(old_return_label)
4682 code.put_label(our_error_label)
4683 for temp_name, type in temps_to_clean_up:
4684 code.put_xdecref_clear(temp_name, type)
4685 for except_clause in self.except_clauses:
4686 except_clause.generate_handling_code(code, except_end_label)
4688 error_label_used = code.label_used(except_error_label)
4689 if error_label_used or not self.has_default_clause:
4690 if error_label_used:
4691 code.put_label(except_error_label)
4692 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4693 code.putln("__Pyx_ExceptionReset(%s);" %
4694 ', '.join(Naming.exc_save_vars))
4695 code.put_goto(old_error_label)
4697 for exit_label, old_label in zip(
4698 [try_break_label, try_continue_label, except_return_label],
4699 [old_break_label, old_continue_label, old_return_label]):
4701 if code.label_used(exit_label):
4702 code.put_label(exit_label)
4703 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4704 code.putln("__Pyx_ExceptionReset(%s);" %
4705 ', '.join(Naming.exc_save_vars))
4706 code.put_goto(old_label)
4708 if code.label_used(except_end_label):
4709 code.put_label(except_end_label)
4710 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4711 code.putln("__Pyx_ExceptionReset(%s);" %
4712 ', '.join(Naming.exc_save_vars))
4713 code.put_label(try_end_label)
4716 code.return_label = old_return_label
4717 code.break_label = old_break_label
4718 code.continue_label = old_continue_label
4719 code.error_label = old_error_label
4721 def generate_function_definitions(self, env, code):
4722 self.body.generate_function_definitions(env, code)
4723 for except_clause in self.except_clauses:
4724 except_clause.generate_function_definitions(env, code)
4725 if self.else_clause is not None:
4726 self.else_clause.generate_function_definitions(env, code)
4728 def annotate(self, code):
4729 self.body.annotate(code)
4730 for except_node in self.except_clauses:
4731 except_node.annotate(code)
4732 if self.else_clause:
4733 self.else_clause.annotate(code)
4736 class ExceptClauseNode(Node):
4737 # Part of try ... except statement.
4739 # pattern [ExprNode]
4740 # target ExprNode or None
4742 # excinfo_target NameNode or None optional target for exception info
4743 # match_flag string result of exception match
4744 # exc_value ExcValueNode used internally
4745 # function_name string qualified name of enclosing function
4746 # exc_vars (string * 3) local exception variables
4748 # excinfo_target is never set by the parser, but can be set by a transform
4749 # in order to extract more extensive information about the exception as a
4750 # sys.exc_info()-style tuple into a target variable
4752 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4755 excinfo_target = None
4757 def analyse_declarations(self, env):
4759 self.target.analyse_target_declaration(env)
4760 if self.excinfo_target is not None:
4761 self.excinfo_target.analyse_target_declaration(env)
4762 self.body.analyse_declarations(env)
4764 def analyse_expressions(self, env):
4766 genv = env.global_scope()
4767 self.function_name = env.qualified_name
4769 # normalise/unpack self.pattern into a list
4770 for i, pattern in enumerate(self.pattern):
4771 pattern.analyse_expressions(env)
4772 self.pattern[i] = pattern.coerce_to_pyobject(env)
4775 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4776 self.target.analyse_target_expression(env, self.exc_value)
4777 if self.excinfo_target is not None:
4779 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4780 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4781 self.excinfo_tuple.analyse_expressions(env)
4782 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4784 self.body.analyse_expressions(env)
4786 def generate_handling_code(self, code, end_label):
4787 code.mark_pos(self.pos)
4790 for pattern in self.pattern:
4791 pattern.generate_evaluation_code(code)
4792 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4794 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4796 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4797 for pattern in self.pattern:
4798 pattern.generate_disposal_code(code)
4799 pattern.free_temps(code)
4803 code.funcstate.release_temp(match_flag)
4805 code.putln("/*except:*/ {")
4807 if not getattr(self.body, 'stats', True) and \
4808 self.excinfo_target is None and self.target is None:
4809 # most simple case: no exception variable, empty body (pass)
4810 # => reset the exception state, done
4811 code.putln("PyErr_Restore(0,0,0);")
4812 code.put_goto(end_label)
4816 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4819 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4820 # We always have to fetch the exception value even if
4821 # there is no target, because this also normalises the
4822 # exception and stores it in the thread state.
4823 code.globalstate.use_utility_code(get_exception_utility_code)
4824 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4825 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4826 code.error_goto(self.pos)))
4830 self.exc_value.set_var(exc_vars[1])
4831 self.exc_value.generate_evaluation_code(code)
4832 self.target.generate_assignment_code(self.exc_value, code)
4833 if self.excinfo_target is not None:
4834 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4835 node.set_var(tempvar)
4836 self.excinfo_tuple.generate_evaluation_code(code)
4837 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4839 old_break_label, old_continue_label = code.break_label, code.continue_label
4840 code.break_label = code.new_label('except_break')
4841 code.continue_label = code.new_label('except_continue')
4843 old_exc_vars = code.funcstate.exc_vars
4844 code.funcstate.exc_vars = exc_vars
4845 self.body.generate_execution_code(code)
4846 code.funcstate.exc_vars = old_exc_vars
4847 for var in exc_vars:
4848 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4849 code.put_goto(end_label)
4851 if code.label_used(code.break_label):
4852 code.put_label(code.break_label)
4853 for var in exc_vars:
4854 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4855 code.put_goto(old_break_label)
4856 code.break_label = old_break_label
4858 if code.label_used(code.continue_label):
4859 code.put_label(code.continue_label)
4860 for var in exc_vars:
4861 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4862 code.put_goto(old_continue_label)
4863 code.continue_label = old_continue_label
4865 for temp in exc_vars:
4866 code.funcstate.release_temp(temp)
4871 def generate_function_definitions(self, env, code):
4872 if self.target is not None:
4873 self.target.generate_function_definitions(env, code)
4874 self.body.generate_function_definitions(env, code)
4876 def annotate(self, code):
4878 for pattern in self.pattern:
4879 pattern.annotate(code)
4881 self.target.annotate(code)
4882 self.body.annotate(code)
4885 class TryFinallyStatNode(StatNode):
4886 # try ... finally statement
4889 # finally_clause StatNode
4891 # The plan is that we funnel all continue, break
4892 # return and error gotos into the beginning of the
4893 # finally block, setting a variable to remember which
4894 # one we're doing. At the end of the finally block, we
4895 # switch on the variable to figure out where to go.
4896 # In addition, if we're doing an error, we save the
4897 # exception on entry to the finally block and restore
4900 child_attrs = ["body", "finally_clause"]
4902 preserve_exception = 1
4904 disallow_continue_in_try_finally = 0
4905 # There doesn't seem to be any point in disallowing
4906 # continue in the try block, since we have no problem
4909 def create_analysed(pos, env, body, finally_clause):
4910 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4912 create_analysed = staticmethod(create_analysed)
4914 def analyse_control_flow(self, env):
4915 env.start_branching(self.pos)
4916 self.body.analyse_control_flow(env)
4917 env.next_branch(self.body.end_pos())
4918 env.finish_branching(self.body.end_pos())
4919 self.finally_clause.analyse_control_flow(env)
4921 def analyse_declarations(self, env):
4922 self.body.analyse_declarations(env)
4923 self.finally_clause.analyse_declarations(env)
4925 def analyse_expressions(self, env):
4926 self.body.analyse_expressions(env)
4927 self.finally_clause.analyse_expressions(env)
4929 nogil_check = Node.gil_error
4930 gil_message = "Try-finally statement"
4932 def generate_execution_code(self, code):
4933 old_error_label = code.error_label
4934 old_labels = code.all_new_labels()
4935 new_labels = code.get_all_labels()
4936 new_error_label = code.error_label
4937 catch_label = code.new_label()
4940 if self.disallow_continue_in_try_finally:
4941 was_in_try_finally = code.funcstate.in_try_finally
4942 code.funcstate.in_try_finally = 1
4943 self.body.generate_execution_code(code)
4944 if self.disallow_continue_in_try_finally:
4945 code.funcstate.in_try_finally = was_in_try_finally
4948 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4949 code.mark_pos(self.finally_clause.pos)
4953 error_label_used = 0
4954 for i, new_label in enumerate(new_labels):
4955 if new_label in code.labels_used:
4956 cases_used.append(i)
4957 if new_label == new_error_label:
4958 error_label_used = 1
4959 error_label_case = i
4963 if error_label_used and self.preserve_exception:
4965 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4967 "int %s;" % Naming.exc_lineno_name)
4968 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4969 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4970 code.putln(exc_var_init_zero)
4972 exc_var_init_zero = None
4973 code.use_label(catch_label)
4975 "__pyx_why = 0; goto %s;" % catch_label)
4976 for i in cases_used:
4977 new_label = new_labels[i]
4978 #if new_label and new_label != "<try>":
4979 if new_label == new_error_label and self.preserve_exception:
4980 self.put_error_catcher(code,
4981 new_error_label, i+1, catch_label, temps_to_clean_up)
4983 code.put('%s: ' % new_label)
4984 if exc_var_init_zero:
4985 code.putln(exc_var_init_zero)
4986 code.putln("__pyx_why = %s; goto %s;" % (
4989 code.put_label(catch_label)
4990 code.set_all_labels(old_labels)
4991 if error_label_used:
4992 code.new_error_label()
4993 finally_error_label = code.error_label
4994 self.finally_clause.generate_execution_code(code)
4995 if error_label_used:
4996 if finally_error_label in code.labels_used and self.preserve_exception:
4997 over_label = code.new_label()
4998 code.put_goto(over_label);
4999 code.put_label(finally_error_label)
5000 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5001 for var in Naming.exc_vars:
5002 code.putln("Py_XDECREF(%s);" % var)
5004 code.put_goto(old_error_label)
5005 code.put_label(over_label)
5006 code.error_label = old_error_label
5009 "switch (__pyx_why) {")
5010 for i in cases_used:
5011 old_label = old_labels[i]
5012 if old_label == old_error_label and self.preserve_exception:
5013 self.put_error_uncatcher(code, i+1, old_error_label)
5015 code.use_label(old_label)
5017 "case %s: goto %s;" % (
5025 def generate_function_definitions(self, env, code):
5026 self.body.generate_function_definitions(env, code)
5027 self.finally_clause.generate_function_definitions(env, code)
5029 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5030 code.globalstate.use_utility_code(restore_exception_utility_code)
5037 for temp_name, type in temps_to_clean_up:
5038 code.put_xdecref_clear(temp_name, type)
5040 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5044 Naming.exc_lineno_name, Naming.lineno_cname))
5045 code.put_goto(catch_label)
5048 def put_error_uncatcher(self, code, i, error_label):
5049 code.globalstate.use_utility_code(restore_exception_utility_code)
5054 "__Pyx_ErrRestore(%s, %s, %s);" %
5058 Naming.lineno_cname, Naming.exc_lineno_name))
5059 for var in Naming.exc_vars:
5063 code.put_goto(error_label)
5067 def annotate(self, code):
5068 self.body.annotate(code)
5069 self.finally_clause.annotate(code)
5072 class GILStatNode(TryFinallyStatNode):
5073 # 'with gil' or 'with nogil' statement
5075 # state string 'gil' or 'nogil'
5079 preserve_exception = 0
5081 def __init__(self, pos, state, body):
5083 TryFinallyStatNode.__init__(self, pos,
5085 finally_clause = GILExitNode(pos, state = state))
5087 def analyse_expressions(self, env):
5088 env.use_utility_code(force_init_threads_utility_code)
5089 was_nogil = env.nogil
5091 TryFinallyStatNode.analyse_expressions(self, env)
5092 env.nogil = was_nogil
5096 def generate_execution_code(self, code):
5097 code.mark_pos(self.pos)
5099 if self.state == 'gil':
5100 code.putln("#ifdef WITH_THREAD")
5101 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5102 code.putln("#endif")
5104 code.putln("#ifdef WITH_THREAD")
5105 code.putln("PyThreadState *_save;")
5106 code.putln("#endif")
5107 code.putln("Py_UNBLOCK_THREADS")
5108 TryFinallyStatNode.generate_execution_code(self, code)
5112 class GILExitNode(StatNode):
5113 # Used as the 'finally' block in a GILStatNode
5115 # state string 'gil' or 'nogil'
5119 def analyse_expressions(self, env):
5122 def generate_execution_code(self, code):
5123 if self.state == 'gil':
5124 code.putln("#ifdef WITH_THREAD")
5125 code.putln("PyGILState_Release(_save);")
5126 code.putln("#endif")
5128 code.putln("Py_BLOCK_THREADS")
5131 class CImportStatNode(StatNode):
5134 # module_name string Qualified name of module being imported
5135 # as_name string or None Name specified in "as" clause, if any
5139 def analyse_declarations(self, env):
5140 if not env.is_module_scope:
5141 error(self.pos, "cimport only allowed at module level")
5143 module_scope = env.find_module(self.module_name, self.pos)
5144 if "." in self.module_name:
5145 names = [EncodedString(name) for name in self.module_name.split(".")]
5147 top_module_scope = env.context.find_submodule(top_name)
5148 module_scope = top_module_scope
5149 for name in names[1:]:
5150 submodule_scope = module_scope.find_submodule(name)
5151 module_scope.declare_module(name, submodule_scope, self.pos)
5152 module_scope = submodule_scope
5154 env.declare_module(self.as_name, module_scope, self.pos)
5156 env.declare_module(top_name, top_module_scope, self.pos)
5158 name = self.as_name or self.module_name
5159 env.declare_module(name, module_scope, self.pos)
5161 def analyse_expressions(self, env):
5164 def generate_execution_code(self, code):
5168 class FromCImportStatNode(StatNode):
5169 # from ... cimport statement
5171 # module_name string Qualified name of module
5172 # imported_names [(pos, name, as_name, kind)] Names to be imported
5176 def analyse_declarations(self, env):
5177 if not env.is_module_scope:
5178 error(self.pos, "cimport only allowed at module level")
5180 module_scope = env.find_module(self.module_name, self.pos)
5181 env.add_imported_module(module_scope)
5182 for pos, name, as_name, kind in self.imported_names:
5184 for local_name, entry in module_scope.entries.items():
5185 env.add_imported_entry(local_name, entry, pos)
5187 entry = module_scope.lookup(name)
5189 if kind and not self.declaration_matches(entry, kind):
5190 entry.redeclared(pos)
5192 if kind == 'struct' or kind == 'union':
5193 entry = module_scope.declare_struct_or_union(name,
5194 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5195 elif kind == 'class':
5196 entry = module_scope.declare_c_class(name, pos = pos,
5197 module_name = self.module_name)
5199 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5200 if submodule_scope.parent_module is module_scope:
5201 env.declare_module(as_name or name, submodule_scope, self.pos)
5203 error(pos, "Name '%s' not declared in module '%s'"
5204 % (name, self.module_name))
5207 local_name = as_name or name
5208 env.add_imported_entry(local_name, entry, pos)
5210 def declaration_matches(self, entry, kind):
5211 if not entry.is_type:
5215 if not type.is_extension_type:
5218 if not type.is_struct_or_union:
5220 if kind != type.kind:
5224 def analyse_expressions(self, env):
5227 def generate_execution_code(self, code):
5231 class FromImportStatNode(StatNode):
5232 # from ... import statement
5235 # items [(string, NameNode)]
5236 # interned_items [(string, NameNode, ExprNode)]
5237 # item PyTempNode used internally
5238 # import_star boolean used internally
5240 child_attrs = ["module"]
5243 def analyse_declarations(self, env):
5244 for name, target in self.items:
5246 if not env.is_module_scope:
5247 error(self.pos, "import * only allowed at module level")
5249 env.has_import_star = 1
5250 self.import_star = 1
5252 target.analyse_target_declaration(env)
5254 def analyse_expressions(self, env):
5256 self.module.analyse_expressions(env)
5257 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5258 self.interned_items = []
5259 for name, target in self.items:
5261 for _, entry in env.entries.items():
5262 if not entry.is_type and entry.type.is_extension_type:
5263 env.use_utility_code(ExprNodes.type_test_utility_code)
5266 entry = env.lookup(target.name)
5267 # check whether or not entry is already cimported
5268 if (entry.is_type and entry.type.name == name
5269 and hasattr(entry.type, 'module_name')):
5270 if entry.type.module_name == self.module.module_name.value:
5271 # cimported with absolute name
5274 # cimported with relative name
5275 module = env.find_module(self.module.module_name.value,
5277 if entry.type.module_name == module.qualified_name:
5279 except AttributeError:
5281 target.analyse_target_expression(env, None)
5282 if target.type is py_object_type:
5285 coerced_item = self.item.coerce_to(target.type, env)
5286 self.interned_items.append((name, target, coerced_item))
5288 def generate_execution_code(self, code):
5289 self.module.generate_evaluation_code(code)
5290 if self.import_star:
5292 'if (%s(%s) < 0) %s;' % (
5294 self.module.py_result(),
5295 code.error_goto(self.pos)))
5296 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5297 self.item.set_cname(item_temp)
5298 for name, target, coerced_item in self.interned_items:
5299 cname = code.intern_identifier(name)
5301 '%s = PyObject_GetAttr(%s, %s); %s' % (
5303 self.module.py_result(),
5305 code.error_goto_if_null(item_temp, self.pos)))
5306 code.put_gotref(item_temp)
5307 if coerced_item is None:
5308 target.generate_assignment_code(self.item, code)
5310 coerced_item.allocate_temp_result(code)
5311 coerced_item.generate_result_code(code)
5312 target.generate_assignment_code(coerced_item, code)
5313 code.put_decref_clear(item_temp, py_object_type)
5314 code.funcstate.release_temp(item_temp)
5315 self.module.generate_disposal_code(code)
5316 self.module.free_temps(code)
5320 #------------------------------------------------------------------------------------
5322 # Runtime support code
5324 #------------------------------------------------------------------------------------
5326 utility_function_predeclarations = \
5328 /* inline attribute */
5329 #ifndef CYTHON_INLINE
5330 #if defined(__GNUC__)
5331 #define CYTHON_INLINE __inline__
5332 #elif defined(_MSC_VER)
5333 #define CYTHON_INLINE __inline
5334 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5335 #define CYTHON_INLINE inline
5337 #define CYTHON_INLINE
5341 /* unused attribute */
5342 #ifndef CYTHON_UNUSED
5343 # if defined(__GNUC__)
5344 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5345 # define CYTHON_UNUSED __attribute__ ((__unused__))
5347 # define CYTHON_UNUSED
5349 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5350 # define CYTHON_UNUSED __attribute__ ((__unused__))
5352 # define CYTHON_UNUSED
5356 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*/
5360 if Options.gcc_branch_hints:
5361 branch_prediction_macros = \
5364 /* Test for GCC > 2.95 */
5365 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5366 #define likely(x) __builtin_expect(!!(x), 1)
5367 #define unlikely(x) __builtin_expect(!!(x), 0)
5368 #else /* __GNUC__ > 2 ... */
5369 #define likely(x) (x)
5370 #define unlikely(x) (x)
5371 #endif /* __GNUC__ > 2 ... */
5372 #else /* __GNUC__ */
5373 #define likely(x) (x)
5374 #define unlikely(x) (x)
5375 #endif /* __GNUC__ */
5378 branch_prediction_macros = \
5380 #define likely(x) (x)
5381 #define unlikely(x) (x)
5384 #get_name_predeclaration = \
5385 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5387 #get_name_interned_predeclaration = \
5388 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5390 #------------------------------------------------------------------------------------
5392 printing_utility_code = UtilityCode(
5394 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5395 #if PY_MAJOR_VERSION >= 3
5396 static PyObject* %s = 0;
5397 static PyObject* %s = 0;
5399 """ % (Naming.print_function, Naming.print_function_kwargs),
5401 #if PY_MAJOR_VERSION >= 3
5405 """ % (Naming.print_function, Naming.print_function_kwargs),
5407 #if PY_MAJOR_VERSION < 3
5408 static PyObject *__Pyx_GetStdout(void) {
5409 PyObject *f = PySys_GetObject((char *)"stdout");
5411 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5416 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5421 if (!(f = __Pyx_GetStdout()))
5424 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5425 if (PyFile_SoftSpace(f, 1)) {
5426 if (PyFile_WriteString(" ", f) < 0)
5429 v = PyTuple_GET_ITEM(arg_tuple, i);
5430 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5432 if (PyString_Check(v)) {
5433 char *s = PyString_AsString(v);
5434 Py_ssize_t len = PyString_Size(v);
5436 isspace(Py_CHARMASK(s[len-1])) &&
5438 PyFile_SoftSpace(f, 0);
5442 if (PyFile_WriteString("\n", f) < 0)
5444 PyFile_SoftSpace(f, 0);
5449 #else /* Python 3 has a print function */
5451 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5452 PyObject* kwargs = 0;
5453 PyObject* result = 0;
5454 PyObject* end_string;
5455 if (unlikely(!%(PRINT_FUNCTION)s)) {
5456 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5457 if (!%(PRINT_FUNCTION)s)
5461 kwargs = PyDict_New();
5462 if (unlikely(!kwargs))
5464 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5467 end_string = PyUnicode_FromStringAndSize(" ", 1);
5468 if (unlikely(!end_string))
5470 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5471 Py_DECREF(end_string);
5474 Py_DECREF(end_string);
5476 } else if (!newline) {
5477 if (unlikely(!%(PRINT_KWARGS)s)) {
5478 %(PRINT_KWARGS)s = PyDict_New();
5479 if (unlikely(!%(PRINT_KWARGS)s))
5481 end_string = PyUnicode_FromStringAndSize(" ", 1);
5482 if (unlikely(!end_string))
5484 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5485 Py_DECREF(end_string);
5488 Py_DECREF(end_string);
5490 kwargs = %(PRINT_KWARGS)s;
5492 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5493 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5500 if (kwargs != %(PRINT_KWARGS)s)
5506 """ % {'BUILTINS' : Naming.builtins_cname,
5507 'PRINT_FUNCTION' : Naming.print_function,
5508 'PRINT_KWARGS' : Naming.print_function_kwargs}
5512 printing_one_utility_code = UtilityCode(
5514 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5517 #if PY_MAJOR_VERSION < 3
5519 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5521 if (!(f = __Pyx_GetStdout()))
5524 if (PyFile_SoftSpace(f, 0)) {
5525 if (PyFile_WriteString(" ", f) < 0)
5528 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5530 if (PyFile_WriteString("\n", f) < 0)
5533 /* the line below is just to avoid compiler
5534 * compiler warnings about unused functions */
5535 return __Pyx_Print(f, NULL, 0);
5538 #else /* Python 3 has a print function */
5540 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5542 PyObject* arg_tuple = PyTuple_New(1);
5543 if (unlikely(!arg_tuple))
5546 PyTuple_SET_ITEM(arg_tuple, 0, o);
5547 res = __Pyx_Print(stream, arg_tuple, 1);
5548 Py_DECREF(arg_tuple);
5554 requires=[printing_utility_code])
5558 #------------------------------------------------------------------------------------
5560 # Exception raising code
5562 # Exceptions are raised by __Pyx_Raise() and stored as plain
5563 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5564 # 'except' statement, curexc_* is moved over to exc_* by
5565 # __Pyx_GetException()
5567 restore_exception_utility_code = UtilityCode(
5569 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5570 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5573 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5574 PyObject *tmp_type, *tmp_value, *tmp_tb;
5575 PyThreadState *tstate = PyThreadState_GET();
5577 tmp_type = tstate->curexc_type;
5578 tmp_value = tstate->curexc_value;
5579 tmp_tb = tstate->curexc_traceback;
5580 tstate->curexc_type = type;
5581 tstate->curexc_value = value;
5582 tstate->curexc_traceback = tb;
5583 Py_XDECREF(tmp_type);
5584 Py_XDECREF(tmp_value);
5588 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5589 PyThreadState *tstate = PyThreadState_GET();
5590 *type = tstate->curexc_type;
5591 *value = tstate->curexc_value;
5592 *tb = tstate->curexc_traceback;
5594 tstate->curexc_type = 0;
5595 tstate->curexc_value = 0;
5596 tstate->curexc_traceback = 0;
5601 # The following function is based on do_raise() from ceval.c. There
5602 # are separate versions for Python2 and Python3 as exception handling
5603 # has changed quite a lot between the two versions.
5605 raise_utility_code = UtilityCode(
5607 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5610 #if PY_MAJOR_VERSION < 3
5611 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5615 /* First, check the traceback argument, replacing None with NULL. */
5616 if (tb == Py_None) {
5620 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5621 PyErr_SetString(PyExc_TypeError,
5622 "raise: arg 3 must be a traceback or None");
5625 /* Next, replace a missing value with None */
5626 if (value == NULL) {
5630 #if PY_VERSION_HEX < 0x02050000
5631 if (!PyClass_Check(type))
5633 if (!PyType_Check(type))
5636 /* Raising an instance. The value should be a dummy. */
5637 if (value != Py_None) {
5638 PyErr_SetString(PyExc_TypeError,
5639 "instance exception may not have a separate value");
5642 /* Normalize to raise <class>, <instance> */
5645 #if PY_VERSION_HEX < 0x02050000
5646 if (PyInstance_Check(type)) {
5647 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5652 PyErr_SetString(PyExc_TypeError,
5653 "raise: exception must be an old-style class or instance");
5657 type = (PyObject*) Py_TYPE(type);
5659 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5660 PyErr_SetString(PyExc_TypeError,
5661 "raise: exception class must be a subclass of BaseException");
5667 __Pyx_ErrRestore(type, value, tb);
5676 #else /* Python 3+ */
5678 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5679 if (tb == Py_None) {
5681 } else if (tb && !PyTraceBack_Check(tb)) {
5682 PyErr_SetString(PyExc_TypeError,
5683 "raise: arg 3 must be a traceback or None");
5686 if (value == Py_None)
5689 if (PyExceptionInstance_Check(type)) {
5691 PyErr_SetString(PyExc_TypeError,
5692 "instance exception may not have a separate value");
5696 type = (PyObject*) Py_TYPE(value);
5697 } else if (!PyExceptionClass_Check(type)) {
5698 PyErr_SetString(PyExc_TypeError,
5699 "raise: exception class must be a subclass of BaseException");
5703 PyErr_SetObject(type, value);
5706 PyThreadState *tstate = PyThreadState_GET();
5707 PyObject* tmp_tb = tstate->curexc_traceback;
5710 tstate->curexc_traceback = tb;
5720 requires=[restore_exception_utility_code])
5722 #------------------------------------------------------------------------------------
5724 get_exception_utility_code = UtilityCode(
5726 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5729 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5730 PyObject *local_type, *local_value, *local_tb;
5731 PyObject *tmp_type, *tmp_value, *tmp_tb;
5732 PyThreadState *tstate = PyThreadState_GET();
5733 local_type = tstate->curexc_type;
5734 local_value = tstate->curexc_value;
5735 local_tb = tstate->curexc_traceback;
5736 tstate->curexc_type = 0;
5737 tstate->curexc_value = 0;
5738 tstate->curexc_traceback = 0;
5739 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5740 if (unlikely(tstate->curexc_type))
5742 #if PY_MAJOR_VERSION >= 3
5743 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5747 *value = local_value;
5749 Py_INCREF(local_type);
5750 Py_INCREF(local_value);
5751 Py_INCREF(local_tb);
5752 tmp_type = tstate->exc_type;
5753 tmp_value = tstate->exc_value;
5754 tmp_tb = tstate->exc_traceback;
5755 tstate->exc_type = local_type;
5756 tstate->exc_value = local_value;
5757 tstate->exc_traceback = local_tb;
5758 /* Make sure tstate is in a consistent state when we XDECREF
5759 these objects (XDECREF may run arbitrary code). */
5760 Py_XDECREF(tmp_type);
5761 Py_XDECREF(tmp_value);
5768 Py_XDECREF(local_type);
5769 Py_XDECREF(local_value);
5770 Py_XDECREF(local_tb);
5776 #------------------------------------------------------------------------------------
5778 get_exception_tuple_utility_code = UtilityCode(proto="""
5779 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5781 # I doubt that calling __Pyx_GetException() here is correct as it moves
5782 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5783 # exception handlers later on from receiving it.
5785 static PyObject *__Pyx_GetExceptionTuple(void) {
5786 PyObject *type = NULL, *value = NULL, *tb = NULL;
5787 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5788 PyObject* exc_info = PyTuple_New(3);
5793 PyTuple_SET_ITEM(exc_info, 0, type);
5794 PyTuple_SET_ITEM(exc_info, 1, value);
5795 PyTuple_SET_ITEM(exc_info, 2, tb);
5802 requires=[get_exception_utility_code])
5804 #------------------------------------------------------------------------------------
5806 reset_exception_utility_code = UtilityCode(
5808 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5809 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5812 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5813 PyThreadState *tstate = PyThreadState_GET();
5814 *type = tstate->exc_type;
5815 *value = tstate->exc_value;
5816 *tb = tstate->exc_traceback;
5822 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5823 PyObject *tmp_type, *tmp_value, *tmp_tb;
5824 PyThreadState *tstate = PyThreadState_GET();
5825 tmp_type = tstate->exc_type;
5826 tmp_value = tstate->exc_value;
5827 tmp_tb = tstate->exc_traceback;
5828 tstate->exc_type = type;
5829 tstate->exc_value = value;
5830 tstate->exc_traceback = tb;
5831 Py_XDECREF(tmp_type);
5832 Py_XDECREF(tmp_value);
5837 #------------------------------------------------------------------------------------
5839 arg_type_test_utility_code = UtilityCode(
5841 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5842 const char *name, int exact); /*proto*/
5845 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5846 const char *name, int exact)
5849 PyErr_Format(PyExc_SystemError, "Missing type object");
5852 if (none_allowed && obj == Py_None) return 1;
5854 if (Py_TYPE(obj) == type) return 1;
5857 if (PyObject_TypeCheck(obj, type)) return 1;
5859 PyErr_Format(PyExc_TypeError,
5860 "Argument '%s' has incorrect type (expected %s, got %s)",
5861 name, type->tp_name, Py_TYPE(obj)->tp_name);
5866 #------------------------------------------------------------------------------------
5868 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5869 # many or too few positional arguments were found. This handles
5870 # Py_ssize_t formatting correctly.
5872 raise_argtuple_invalid_utility_code = UtilityCode(
5874 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5875 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5878 static void __Pyx_RaiseArgtupleInvalid(
5879 const char* func_name,
5883 Py_ssize_t num_found)
5885 Py_ssize_t num_expected;
5886 const char *number, *more_or_less;
5888 if (num_found < num_min) {
5889 num_expected = num_min;
5890 more_or_less = "at least";
5892 num_expected = num_max;
5893 more_or_less = "at most";
5896 more_or_less = "exactly";
5898 number = (num_expected == 1) ? "" : "s";
5899 PyErr_Format(PyExc_TypeError,
5900 #if PY_VERSION_HEX < 0x02050000
5901 "%s() takes %s %d positional argument%s (%d given)",
5903 "%s() takes %s %zd positional argument%s (%zd given)",
5905 func_name, more_or_less, num_expected, number, num_found);
5909 raise_keyword_required_utility_code = UtilityCode(
5911 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5914 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5915 const char* func_name,
5918 PyErr_Format(PyExc_TypeError,
5919 #if PY_MAJOR_VERSION >= 3
5920 "%s() needs keyword-only argument %U", func_name, kw_name);
5922 "%s() needs keyword-only argument %s", func_name,
5923 PyString_AS_STRING(kw_name));
5928 raise_double_keywords_utility_code = UtilityCode(
5930 static void __Pyx_RaiseDoubleKeywordsError(
5931 const char* func_name, PyObject* kw_name); /*proto*/
5934 static void __Pyx_RaiseDoubleKeywordsError(
5935 const char* func_name,
5938 PyErr_Format(PyExc_TypeError,
5939 #if PY_MAJOR_VERSION >= 3
5940 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5942 "%s() got multiple values for keyword argument '%s'", func_name,
5943 PyString_AS_STRING(kw_name));
5948 #------------------------------------------------------------------------------------
5950 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5951 # were passed to a function, or if any keywords were passed to a
5952 # function that does not accept them.
5954 keyword_string_check_utility_code = UtilityCode(
5956 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5957 const char* function_name, int kw_allowed); /*proto*/
5960 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5962 const char* function_name,
5967 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5968 #if PY_MAJOR_VERSION < 3
5969 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5971 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
5973 goto invalid_keyword_type;
5975 if ((!kw_allowed) && unlikely(key))
5976 goto invalid_keyword;
5978 invalid_keyword_type:
5979 PyErr_Format(PyExc_TypeError,
5980 "%s() keywords must be strings", function_name);
5983 PyErr_Format(PyExc_TypeError,
5984 #if PY_MAJOR_VERSION < 3
5985 "%s() got an unexpected keyword argument '%s'",
5986 function_name, PyString_AsString(key));
5988 "%s() got an unexpected keyword argument '%U'",
5989 function_name, key);
5995 #------------------------------------------------------------------------------------
5997 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
5998 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
5999 # keywords will raise an invalid keyword error.
6001 # Three kinds of errors are checked: 1) non-string keywords, 2)
6002 # unexpected keywords and 3) overlap with positional arguments.
6004 # If num_posargs is greater 0, it denotes the number of positional
6005 # arguments that were passed and that must therefore not appear
6006 # amongst the keywords as well.
6008 # This method does not check for required keyword arguments.
6011 parse_keywords_utility_code = UtilityCode(
6013 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6014 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6015 const char* function_name); /*proto*/
6018 static int __Pyx_ParseOptionalKeywords(
6020 PyObject **argnames[],
6023 Py_ssize_t num_pos_args,
6024 const char* function_name)
6026 PyObject *key = 0, *value = 0;
6029 PyObject*** first_kw_arg = argnames + num_pos_args;
6031 while (PyDict_Next(kwds, &pos, &key, &value)) {
6032 name = first_kw_arg;
6033 while (*name && (**name != key)) name++;
6035 values[name-argnames] = value;
6037 #if PY_MAJOR_VERSION < 3
6038 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6040 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6042 goto invalid_keyword_type;
6044 for (name = first_kw_arg; *name; name++) {
6045 #if PY_MAJOR_VERSION >= 3
6046 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6047 PyUnicode_Compare(**name, key) == 0) break;
6049 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6050 _PyString_Eq(**name, key)) break;
6054 values[name-argnames] = value;
6056 /* unexpected keyword found */
6057 for (name=argnames; name != first_kw_arg; name++) {
6058 if (**name == key) goto arg_passed_twice;
6059 #if PY_MAJOR_VERSION >= 3
6060 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6061 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6063 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6064 _PyString_Eq(**name, key)) goto arg_passed_twice;
6068 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6070 goto invalid_keyword;
6078 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6080 invalid_keyword_type:
6081 PyErr_Format(PyExc_TypeError,
6082 "%s() keywords must be strings", function_name);
6085 PyErr_Format(PyExc_TypeError,
6086 #if PY_MAJOR_VERSION < 3
6087 "%s() got an unexpected keyword argument '%s'",
6088 function_name, PyString_AsString(key));
6090 "%s() got an unexpected keyword argument '%U'",
6091 function_name, key);
6098 #------------------------------------------------------------------------------------
6100 traceback_utility_code = UtilityCode(
6102 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6105 #include "compile.h"
6106 #include "frameobject.h"
6107 #include "traceback.h"
6109 static void __Pyx_AddTraceback(const char *funcname) {
6110 PyObject *py_srcfile = 0;
6111 PyObject *py_funcname = 0;
6112 PyObject *py_globals = 0;
6113 PyCodeObject *py_code = 0;
6114 PyFrameObject *py_frame = 0;
6116 #if PY_MAJOR_VERSION < 3
6117 py_srcfile = PyString_FromString(%(FILENAME)s);
6119 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6121 if (!py_srcfile) goto bad;
6123 #if PY_MAJOR_VERSION < 3
6124 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6126 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6130 #if PY_MAJOR_VERSION < 3
6131 py_funcname = PyString_FromString(funcname);
6133 py_funcname = PyUnicode_FromString(funcname);
6136 if (!py_funcname) goto bad;
6137 py_globals = PyModule_GetDict(%(GLOBALS)s);
6138 if (!py_globals) goto bad;
6139 py_code = PyCode_New(
6140 0, /*int argcount,*/
6141 #if PY_MAJOR_VERSION >= 3
6142 0, /*int kwonlyargcount,*/
6145 0, /*int stacksize,*/
6147 %(EMPTY_BYTES)s, /*PyObject *code,*/
6148 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6149 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6150 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6151 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6152 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6153 py_srcfile, /*PyObject *filename,*/
6154 py_funcname, /*PyObject *name,*/
6155 %(LINENO)s, /*int firstlineno,*/
6156 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6158 if (!py_code) goto bad;
6159 py_frame = PyFrame_New(
6160 PyThreadState_GET(), /*PyThreadState *tstate,*/
6161 py_code, /*PyCodeObject *code,*/
6162 py_globals, /*PyObject *globals,*/
6163 0 /*PyObject *locals*/
6165 if (!py_frame) goto bad;
6166 py_frame->f_lineno = %(LINENO)s;
6167 PyTraceBack_Here(py_frame);
6169 Py_XDECREF(py_srcfile);
6170 Py_XDECREF(py_funcname);
6171 Py_XDECREF(py_code);
6172 Py_XDECREF(py_frame);
6175 'FILENAME': Naming.filename_cname,
6176 'LINENO': Naming.lineno_cname,
6177 'CFILENAME': Naming.cfilenm_cname,
6178 'CLINENO': Naming.clineno_cname,
6179 'GLOBALS': Naming.module_cname,
6180 'EMPTY_TUPLE' : Naming.empty_tuple,
6181 'EMPTY_BYTES' : Naming.empty_bytes,
6184 #------------------------------------------------------------------------------------
6186 unraisable_exception_utility_code = UtilityCode(
6188 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6191 static void __Pyx_WriteUnraisable(const char *name) {
6192 PyObject *old_exc, *old_val, *old_tb;
6194 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6195 #if PY_MAJOR_VERSION < 3
6196 ctx = PyString_FromString(name);
6198 ctx = PyUnicode_FromString(name);
6200 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6202 PyErr_WriteUnraisable(Py_None);
6204 PyErr_WriteUnraisable(ctx);
6209 requires=[restore_exception_utility_code])
6211 #------------------------------------------------------------------------------------
6213 set_vtable_utility_code = UtilityCode(
6215 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6218 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6219 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6220 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6222 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6226 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6236 #------------------------------------------------------------------------------------
6238 get_vtable_utility_code = UtilityCode(
6240 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6243 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6244 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6247 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6248 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6250 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6252 if (!*(void **)vtabptr)
6262 #------------------------------------------------------------------------------------
6264 init_string_tab_utility_code = UtilityCode(
6266 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6269 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6271 #if PY_MAJOR_VERSION < 3
6272 if (t->is_unicode) {
6273 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6274 } else if (t->intern) {
6275 *t->p = PyString_InternFromString(t->s);
6277 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6279 #else /* Python 3+ has unicode identifiers */
6280 if (t->is_unicode | t->is_str) {
6282 *t->p = PyUnicode_InternFromString(t->s);
6283 } else if (t->encoding) {
6284 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6286 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6289 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6300 #------------------------------------------------------------------------------------
6302 force_init_threads_utility_code = UtilityCode(
6304 #ifndef __PYX_FORCE_INIT_THREADS
6305 #if PY_VERSION_HEX < 0x02040200
6306 #define __PYX_FORCE_INIT_THREADS 1
6308 #define __PYX_FORCE_INIT_THREADS 0
6313 #------------------------------------------------------------------------------------
6315 # Note that cPython ignores PyTrace_EXCEPTION,
6316 # but maybe some other profilers don't.
6318 profile_utility_code = UtilityCode(proto="""
6319 #ifndef CYTHON_PROFILE
6320 #define CYTHON_PROFILE 1
6323 #ifndef CYTHON_PROFILE_REUSE_FRAME
6324 #define CYTHON_PROFILE_REUSE_FRAME 0
6329 #include "compile.h"
6330 #include "frameobject.h"
6331 #include "traceback.h"
6333 #if CYTHON_PROFILE_REUSE_FRAME
6334 #define CYTHON_FRAME_MODIFIER static
6335 #define CYTHON_FRAME_DEL
6337 #define CYTHON_FRAME_MODIFIER
6338 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6341 #define __Pyx_TraceDeclarations \\
6342 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6343 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6344 int __Pyx_use_tracing = 0;
6346 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6347 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6348 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6351 #define __Pyx_TraceException() \\
6352 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6353 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6355 PyThreadState_GET()->c_profilefunc( \\
6356 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6357 Py_DECREF(exc_info); \\
6361 #define __Pyx_TraceReturn(result) \\
6362 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6363 PyThreadState_GET()->c_profilefunc( \\
6364 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6365 CYTHON_FRAME_DEL; \\
6368 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6369 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6373 #define __Pyx_TraceDeclarations
6374 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6375 #define __Pyx_TraceException()
6376 #define __Pyx_TraceReturn(result)
6378 #endif /* CYTHON_PROFILE */
6381 "FRAME": Naming.frame_cname,
6382 "FRAME_CODE": Naming.frame_code_cname,
6388 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6389 PyFrameObject** frame,
6390 const char *funcname,
6391 const char *srcfile,
6393 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6394 if (*code == NULL) {
6395 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6396 if (*code == NULL) return 0;
6398 *frame = PyFrame_New(
6399 PyThreadState_GET(), /*PyThreadState *tstate*/
6400 *code, /*PyCodeObject *code*/
6401 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6402 0 /*PyObject *locals*/
6404 if (*frame == NULL) return 0;
6407 (*frame)->f_tstate = PyThreadState_GET();
6409 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6412 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6413 PyObject *py_srcfile = 0;
6414 PyObject *py_funcname = 0;
6415 PyCodeObject *py_code = 0;
6417 #if PY_MAJOR_VERSION < 3
6418 py_funcname = PyString_FromString(funcname);
6419 py_srcfile = PyString_FromString(srcfile);
6421 py_funcname = PyUnicode_FromString(funcname);
6422 py_srcfile = PyUnicode_FromString(srcfile);
6424 if (!py_funcname | !py_srcfile) goto bad;
6426 py_code = PyCode_New(
6427 0, /*int argcount,*/
6428 #if PY_MAJOR_VERSION >= 3
6429 0, /*int kwonlyargcount,*/
6432 0, /*int stacksize,*/
6434 %(EMPTY_BYTES)s, /*PyObject *code,*/
6435 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6436 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6437 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6438 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6439 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6440 py_srcfile, /*PyObject *filename,*/
6441 py_funcname, /*PyObject *name,*/
6442 firstlineno, /*int firstlineno,*/
6443 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6447 Py_XDECREF(py_srcfile);
6448 Py_XDECREF(py_funcname);
6453 #endif /* CYTHON_PROFILE */
6455 'EMPTY_TUPLE' : Naming.empty_tuple,
6456 'EMPTY_BYTES' : Naming.empty_bytes,
6457 "MODULE": Naming.module_cname,