3 # Pyrex - Parse tree nodes
8 cython.declare(sys=object, os=object, time=object, copy=object,
9 Builtin=object, error=object, warning=object, Naming=object, PyrexTypes=object,
10 py_object_type=object, ModuleScope=object, LocalScope=object, ClosureScope=object, \
11 StructOrUnionScope=object, PyClassScope=object, CClassScope=object,
12 CppClassScope=object, UtilityCode=object, EncodedString=object,
13 absolute_path_length=cython.Py_ssize_t)
15 import sys, os, time, copy
18 from Errors import error, warning, InternalError
22 from PyrexTypes import py_object_type, error_type, CFuncType
23 from Symtab import ModuleScope, LocalScope, ClosureScope, \
24 StructOrUnionScope, PyClassScope, CClassScope, CppClassScope
25 from Cython.Utils import open_new_file, replace_suffix
26 from Code import UtilityCode
27 from StringEncoding import EncodedString, escape_byte_string, split_string_literal
32 absolute_path_length = 0
34 def relative_position(pos):
36 We embed the relative filename in the generated C file, since we
37 don't want to have to regnerate and compile all the source code
38 whenever the Python install directory moves (which could happen,
39 e.g,. when distributing binaries.)
42 a position tuple -- (absolute filename, line number column position)
50 global absolute_path_length
51 if absolute_path_length==0:
52 absolute_path_length = len(os.path.abspath(os.getcwd()))
53 return (pos[0].get_filenametable_entry()[absolute_path_length+1:], pos[1])
55 def embed_position(pos, docstring):
56 if not Options.embed_pos_in_docstring:
58 pos_line = u'File: %s (starting at line %s)' % relative_position(pos)
61 return EncodedString(pos_line)
63 # make sure we can encode the filename in the docstring encoding
64 # otherwise make the docstring a unicode string
65 encoding = docstring.encoding
66 if encoding is not None:
68 encoded_bytes = pos_line.encode(encoding)
69 except UnicodeEncodeError:
73 # reuse the string encoding of the original docstring
74 doc = EncodedString(pos_line)
76 doc = EncodedString(pos_line + u'\n' + docstring)
77 doc.encoding = encoding
81 from Code import CCodeWriter
82 from types import FunctionType
84 def write_func_call(func):
86 if len(args) > 1 and isinstance(args[1], CCodeWriter):
87 # here we annotate the code with this function call
88 # but only if new code is generated
90 marker = ' /* %s -> %s.%s %s */' % (
91 ' ' * code.call_level,
92 node.__class__.__name__,
95 pristine = code.buffer.stream.tell()
97 start = code.buffer.stream.tell()
99 res = func(*args, **kwds)
101 if start == code.buffer.stream.tell():
102 code.buffer.stream.seek(pristine)
104 marker = marker.replace('->', '<-')
108 return func(*args, **kwds)
111 class VerboseCodeWriter(type):
112 # Set this as a metaclass to trace function calls in code.
113 # This slows down code generation and makes much larger files.
114 def __new__(cls, name, bases, attrs):
116 for mname, m in attrs.items():
117 if isinstance(m, FunctionType):
118 attrs[mname] = write_func_call(m)
119 return super(VerboseCodeWriter, cls).__new__(cls, name, bases, attrs)
123 # pos (string, int, int) Source file position
124 # is_name boolean Is a NameNode
125 # is_literal boolean Is a ConstNode
127 if DebugFlags.debug_trace_code_generation:
128 __metaclass__ = VerboseCodeWriter
134 # All descandants should set child_attrs to a list of the attributes
135 # containing nodes considered "children" in the tree. Each such attribute
136 # can either contain a single node or a list of nodes. See Visitor.py.
139 def __init__(self, pos, **kw):
141 self.__dict__.update(kw)
143 gil_message = "Operation"
147 def gil_error(self, env=None):
148 error(self.pos, "%s not allowed without gil" % self.gil_message)
150 cpp_message = "Operation"
152 def cpp_check(self, env):
157 error(self.pos, "%s only allowed in c++" % self.cpp_message)
159 def clone_node(self):
160 """Clone the node. This is defined as a shallow copy, except for member lists
161 amongst the child attributes (from get_child_accessors) which are also
162 copied. Lists containing child nodes are thus seen as a way for the node
163 to hold multiple children directly; the list is not treated as a seperate
164 level in the tree."""
165 result = copy.copy(self)
166 for attrname in result.child_attrs:
167 value = getattr(result, attrname)
168 if isinstance(value, list):
169 setattr(result, attrname, [x for x in value])
174 # There are 4 phases of parse tree processing, applied in order to
175 # all the statements in a given scope-block:
177 # (0) analyse_control_flow
178 # Create the control flow tree into which state can be asserted and
181 # (1) analyse_declarations
182 # Make symbol table entries for all declarations at the current
183 # level, both explicit (def, cdef, etc.) and implicit (assignment
184 # to an otherwise undeclared name).
186 # (2) analyse_expressions
187 # Determine the result types of expressions and fill in the
188 # 'type' attribute of each ExprNode. Insert coercion nodes into the
189 # tree where needed to convert to and from Python objects.
190 # Allocate temporary locals for intermediate results. Fill
191 # in the 'result_code' attribute of each ExprNode with a C code
195 # Emit C code for all declarations, statements and expressions.
196 # Recursively applies the 3 processing phases to the bodies of
200 def analyse_control_flow(self, env):
203 def analyse_declarations(self, env):
206 def analyse_expressions(self, env):
207 raise InternalError("analyse_expressions not implemented for %s" % \
208 self.__class__.__name__)
210 def generate_code(self, code):
211 raise InternalError("generate_code not implemented for %s" % \
212 self.__class__.__name__)
214 def annotate(self, code):
215 # mro does the wrong thing
216 if isinstance(self, BlockNode):
217 self.body.annotate(code)
222 except AttributeError:
224 if not self.child_attrs:
227 for attr in self.child_attrs:
228 child = getattr(self, attr)
229 # Sometimes lists, sometimes nodes
232 elif isinstance(child, list):
234 pos = max(pos, c.end_pos())
236 pos = max(pos, child.end_pos())
240 def dump(self, level=0, filter_out=("pos",), cutoff=100, encountered=None):
242 return "<...nesting level cutoff...>"
243 if encountered is None:
245 if id(self) in encountered:
246 return "<%s (0x%x) -- already output>" % (self.__class__.__name__, id(self))
247 encountered.add(id(self))
249 def dump_child(x, level):
250 if isinstance(x, Node):
251 return x.dump(level, filter_out, cutoff-1, encountered)
252 elif isinstance(x, list):
253 return "[%s]" % ", ".join([dump_child(item, level) for item in x])
258 attrs = [(key, value) for key, value in self.__dict__.items() if key not in filter_out]
260 return "<%s (0x%x)>" % (self.__class__.__name__, id(self))
263 res = "<%s (0x%x)\n" % (self.__class__.__name__, id(self))
264 for key, value in attrs:
265 res += "%s %s: %s\n" % (indent, key, dump_child(value, level + 1))
266 res += "%s>" % indent
269 class CompilerDirectivesNode(Node):
271 Sets compiler directives for the children nodes
273 # directives {string:value} A dictionary holding the right value for
274 # *all* possible directives.
276 child_attrs = ["body"]
278 def analyse_control_flow(self, env):
280 env.directives = self.directives
281 self.body.analyse_control_flow(env)
284 def analyse_declarations(self, env):
286 env.directives = self.directives
287 self.body.analyse_declarations(env)
290 def analyse_expressions(self, env):
292 env.directives = self.directives
293 self.body.analyse_expressions(env)
296 def generate_function_definitions(self, env, code):
297 env_old = env.directives
298 code_old = code.globalstate.directives
299 code.globalstate.directives = self.directives
300 self.body.generate_function_definitions(env, code)
301 env.directives = env_old
302 code.globalstate.directives = code_old
304 def generate_execution_code(self, code):
305 old = code.globalstate.directives
306 code.globalstate.directives = self.directives
307 self.body.generate_execution_code(code)
308 code.globalstate.directives = old
310 def annotate(self, code):
311 old = code.globalstate.directives
312 code.globalstate.directives = self.directives
313 self.body.annotate(code)
314 code.globalstate.directives = old
316 class BlockNode(object):
317 # Mixin class for nodes representing a declaration block.
319 def generate_cached_builtins_decls(self, env, code):
320 entries = env.global_scope().undeclared_cached_builtins
321 for entry in entries:
322 code.globalstate.add_cached_builtin_decl(entry)
325 def generate_lambda_definitions(self, env, code):
326 for node in env.lambda_defs:
327 node.generate_function_definitions(env, code)
329 class StatListNode(Node):
330 # stats a list of StatNode
332 child_attrs = ["stats"]
334 def create_analysed(pos, env, *args, **kw):
335 node = StatListNode(pos, *args, **kw)
336 return node # No node-specific analysis necesarry
337 create_analysed = staticmethod(create_analysed)
339 def analyse_control_flow(self, env):
340 for stat in self.stats:
341 stat.analyse_control_flow(env)
343 def analyse_declarations(self, env):
344 #print "StatListNode.analyse_declarations" ###
345 for stat in self.stats:
346 stat.analyse_declarations(env)
348 def analyse_expressions(self, env):
349 #print "StatListNode.analyse_expressions" ###
350 for stat in self.stats:
351 stat.analyse_expressions(env)
353 def generate_function_definitions(self, env, code):
354 #print "StatListNode.generate_function_definitions" ###
355 for stat in self.stats:
356 stat.generate_function_definitions(env, code)
358 def generate_execution_code(self, code):
359 #print "StatListNode.generate_execution_code" ###
360 for stat in self.stats:
361 code.mark_pos(stat.pos)
362 stat.generate_execution_code(code)
364 def annotate(self, code):
365 for stat in self.stats:
369 class StatNode(Node):
371 # Code generation for statements is split into the following subphases:
373 # (1) generate_function_definitions
374 # Emit C code for the definitions of any structs,
375 # unions, enums and functions defined in the current
378 # (2) generate_execution_code
379 # Emit C code for executable statements.
382 def generate_function_definitions(self, env, code):
385 def generate_execution_code(self, code):
386 raise InternalError("generate_execution_code not implemented for %s" % \
387 self.__class__.__name__)
390 class CDefExternNode(StatNode):
391 # include_file string or None
394 child_attrs = ["body"]
396 def analyse_declarations(self, env):
397 if self.include_file:
398 env.add_include_file(self.include_file)
399 old_cinclude_flag = env.in_cinclude
401 self.body.analyse_declarations(env)
402 env.in_cinclude = old_cinclude_flag
404 def analyse_expressions(self, env):
407 def generate_execution_code(self, code):
410 def annotate(self, code):
411 self.body.annotate(code)
414 class CDeclaratorNode(Node):
415 # Part of a C declaration.
417 # Processing during analyse_declarations phase:
420 # Returns (name, type) pair where name is the
421 # CNameDeclaratorNode of the name being declared
422 # and type is the type it is being declared as.
424 # calling_convention string Calling convention of CFuncDeclaratorNode
425 # for which this is a base
429 calling_convention = ""
432 class CNameDeclaratorNode(CDeclaratorNode):
433 # name string The Pyrex name being declared
434 # cname string or None C name, if specified
435 # default ExprNode or None the value assigned on declaration
437 child_attrs = ['default']
441 def analyse(self, base_type, env, nonempty = 0):
442 if nonempty and self.name == '':
443 # May have mistaken the name for the type.
444 if base_type.is_ptr or base_type.is_array or base_type.is_buffer:
445 error(self.pos, "Missing argument name")
446 elif base_type.is_void:
447 error(self.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
449 self.name = base_type.declaration_code("", for_display=1, pyrex=1)
450 base_type = py_object_type
451 self.type = base_type
452 return self, base_type
454 class CPtrDeclaratorNode(CDeclaratorNode):
455 # base CDeclaratorNode
457 child_attrs = ["base"]
459 def analyse(self, base_type, env, nonempty = 0):
460 if base_type.is_pyobject:
462 "Pointer base type cannot be a Python object")
463 ptr_type = PyrexTypes.c_ptr_type(base_type)
464 return self.base.analyse(ptr_type, env, nonempty = nonempty)
466 class CReferenceDeclaratorNode(CDeclaratorNode):
467 # base CDeclaratorNode
469 child_attrs = ["base"]
471 def analyse(self, base_type, env, nonempty = 0):
472 if base_type.is_pyobject:
474 "Reference base type cannot be a Python object")
475 ref_type = PyrexTypes.c_ref_type(base_type)
476 return self.base.analyse(ref_type, env, nonempty = nonempty)
478 class CArrayDeclaratorNode(CDeclaratorNode):
479 # base CDeclaratorNode
482 child_attrs = ["base", "dimension"]
484 def analyse(self, base_type, env, nonempty = 0):
485 if base_type.is_cpp_class:
486 from ExprNodes import TupleNode
487 if isinstance(self.dimension, TupleNode):
488 args = self.dimension.args
490 args = self.dimension,
491 values = [v.analyse_as_type(env) for v in args]
493 ix = values.index(None)
494 error(args[ix].pos, "Template parameter not a type.")
496 base_type = base_type.specialize_here(self.pos, values)
497 return self.base.analyse(base_type, env, nonempty = nonempty)
499 self.dimension.analyse_const_expression(env)
500 if not self.dimension.type.is_int:
501 error(self.dimension.pos, "Array dimension not integer")
502 size = self.dimension.get_constant_c_result_code()
511 if not base_type.is_complete():
513 "Array element type '%s' is incomplete" % base_type)
514 if base_type.is_pyobject:
516 "Array element cannot be a Python object")
517 if base_type.is_cfunction:
519 "Array element cannot be a function")
520 array_type = PyrexTypes.c_array_type(base_type, size)
521 return self.base.analyse(array_type, env, nonempty = nonempty)
524 class CFuncDeclaratorNode(CDeclaratorNode):
525 # base CDeclaratorNode
526 # args [CArgDeclNode]
527 # has_varargs boolean
528 # exception_value ConstNode
529 # exception_check boolean True if PyErr_Occurred check needed
530 # nogil boolean Can be called without gil
531 # with_gil boolean Acquire gil around function body
533 child_attrs = ["base", "args", "exception_value"]
536 optional_arg_count = 0
538 def analyse(self, return_type, env, nonempty = 0):
542 for i, arg_node in enumerate(self.args):
543 name_declarator, type = arg_node.analyse(env, nonempty = nonempty,
544 is_self_arg = (i == 0 and env.is_c_class_scope))
545 name = name_declarator.name
546 if name_declarator.cname:
548 "Function argument cannot have C name specification")
549 # Turn *[] argument into **
551 type = PyrexTypes.c_ptr_type(type.base_type)
552 # Catch attempted C-style func(void) decl
554 error(arg_node.pos, "Use spam() rather than spam(void) to declare a function with no arguments.")
555 func_type_args.append(
556 PyrexTypes.CFuncTypeArg(name, type, arg_node.pos))
558 self.optional_arg_count += 1
559 elif self.optional_arg_count:
560 error(self.pos, "Non-default argument follows default argument")
562 if self.optional_arg_count:
563 scope = StructOrUnionScope()
564 arg_count_member = '%sn' % Naming.pyrex_prefix
565 scope.declare_var(arg_count_member, PyrexTypes.c_int_type, self.pos)
566 for arg in func_type_args[len(func_type_args)-self.optional_arg_count:]:
567 scope.declare_var(arg.name, arg.type, arg.pos, allow_pyobject = 1)
568 struct_cname = env.mangle(Naming.opt_arg_prefix, self.base.name)
569 self.op_args_struct = env.global_scope().declare_struct_or_union(name = struct_cname,
574 cname = struct_cname)
575 self.op_args_struct.defined_in_pxd = 1
576 self.op_args_struct.used = 1
580 if self.exception_check == '+':
581 env.add_include_file('stdexcept')
582 if return_type.is_pyobject \
583 and (self.exception_value or self.exception_check) \
584 and self.exception_check != '+':
586 "Exception clause not allowed for function returning Python object")
588 if self.exception_value:
589 self.exception_value.analyse_const_expression(env)
590 if self.exception_check == '+':
591 self.exception_value.analyse_types(env)
592 exc_val_type = self.exception_value.type
593 if not exc_val_type.is_error and \
594 not exc_val_type.is_pyobject and \
595 not (exc_val_type.is_cfunction and not exc_val_type.return_type.is_pyobject and len(exc_val_type.args)==0):
596 error(self.exception_value.pos,
597 "Exception value must be a Python exception or cdef function with no arguments.")
598 exc_val = self.exception_value
600 self.exception_value = self.exception_value.coerce_to(return_type, env)
601 if self.exception_value.analyse_const_expression(env):
602 exc_val = self.exception_value.get_constant_c_result_code()
604 raise InternalError("get_constant_c_result_code not implemented for %s" %
605 self.exception_value.__class__.__name__)
606 if not return_type.assignable_from(self.exception_value.type):
607 error(self.exception_value.pos,
608 "Exception value incompatible with function return type")
609 exc_check = self.exception_check
610 if return_type.is_array:
612 "Function cannot return an array")
613 if return_type.is_cfunction:
615 "Function cannot return a function")
616 func_type = PyrexTypes.CFuncType(
617 return_type, func_type_args, self.has_varargs,
618 optional_arg_count = self.optional_arg_count,
619 exception_value = exc_val, exception_check = exc_check,
620 calling_convention = self.base.calling_convention,
621 nogil = self.nogil, with_gil = self.with_gil, is_overridable = self.overridable)
622 if self.optional_arg_count:
623 func_type.op_arg_struct = PyrexTypes.c_ptr_type(self.op_args_struct.type)
624 callspec = env.directives['callspec']
626 current = func_type.calling_convention
627 if current and current != callspec:
628 error(self.pos, "cannot have both '%s' and '%s' "
629 "calling conventions" % (current, callspec))
630 func_type.calling_convention = callspec
631 return self.base.analyse(func_type, env)
634 class CArgDeclNode(Node):
635 # Item in a function declaration argument list.
637 # base_type CBaseTypeNode
638 # declarator CDeclaratorNode
639 # not_none boolean Tagged with 'not None'
640 # or_none boolean Tagged with 'or None'
641 # accept_none boolean Resolved boolean for not_none/or_none
642 # default ExprNode or None
643 # default_value PyObjectConst constant for default value
644 # annotation ExprNode or None Py3 function arg annotation
645 # is_self_arg boolean Is the "self" arg of an extension type method
646 # is_type_arg boolean Is the "class" arg of an extension type classmethod
647 # is_kw_only boolean Is a keyword-only argument
649 child_attrs = ["base_type", "declarator", "default"]
655 name_declarator = None
659 def analyse(self, env, nonempty = 0, is_self_arg = False):
661 self.base_type.is_self_arg = self.is_self_arg = True
662 if self.type is None:
663 # The parser may missinterpret names as types...
665 if isinstance(self.declarator, CNameDeclaratorNode) and self.declarator.name == '':
667 self.declarator.name = self.base_type.name
668 self.base_type.name = None
669 self.base_type.is_basic_c_type = False
672 could_be_name = False
673 base_type = self.base_type.analyse(env, could_be_name = could_be_name)
674 if hasattr(self.base_type, 'arg_name') and self.base_type.arg_name:
675 self.declarator.name = self.base_type.arg_name
676 # The parser is unable to resolve the ambiguity of [] as part of the
677 # type (e.g. in buffers) or empty declarator (as with arrays).
678 # This is only arises for empty multi-dimensional arrays.
679 if (base_type.is_array
680 and isinstance(self.base_type, TemplatedTypeNode)
681 and isinstance(self.declarator, CArrayDeclaratorNode)):
682 declarator = self.declarator
683 while isinstance(declarator.base, CArrayDeclaratorNode):
684 declarator = declarator.base
685 declarator.base = self.base_type.array_declarator
686 base_type = base_type.base_type
687 return self.declarator.analyse(base_type, env, nonempty = nonempty)
689 return self.name_declarator, self.type
691 def calculate_default_value_code(self, code):
692 if self.default_value is None:
694 if self.default.is_literal:
695 # will not output any code, just assign the result_code
696 self.default.generate_evaluation_code(code)
697 return self.type.cast_code(self.default.result())
698 self.default_value = code.get_argument_default_const(self.type)
699 return self.default_value
701 def annotate(self, code):
703 self.default.annotate(code)
706 class CBaseTypeNode(Node):
707 # Abstract base class for C base type nodes.
709 # Processing during analyse_declarations phase:
716 def analyse_as_type(self, env):
717 return self.analyse(env)
719 class CAnalysedBaseTypeNode(Node):
724 def analyse(self, env, could_be_name = False):
727 class CSimpleBaseTypeNode(CBaseTypeNode):
729 # module_path [string] Qualifying name components
730 # is_basic_c_type boolean
734 # is_self_arg boolean Is self argument of C method
735 # ##is_type_arg boolean Is type argument of class method
738 arg_name = None # in case the argument name was interpreted as a type
740 def analyse(self, env, could_be_name = False):
741 # Return type descriptor.
742 #print "CSimpleBaseTypeNode.analyse: is_self_arg =", self.is_self_arg ###
744 if self.is_basic_c_type:
745 type = PyrexTypes.simple_c_type(self.signed, self.longness, self.name)
747 error(self.pos, "Unrecognised type modifier combination")
748 elif self.name == "object" and not self.module_path:
749 type = py_object_type
750 elif self.name is None:
751 if self.is_self_arg and env.is_c_class_scope:
752 #print "CSimpleBaseTypeNode.analyse: defaulting to parent type" ###
753 type = env.parent_type
754 ## elif self.is_type_arg and env.is_c_class_scope:
755 ## type = Builtin.type_type
757 type = py_object_type
760 scope = env.find_imported_module(self.module_path, self.pos)
764 if scope.is_c_class_scope:
765 scope = scope.global_scope()
766 entry = scope.lookup(self.name)
767 if entry and entry.is_type:
770 if self.is_self_arg and env.is_c_class_scope:
771 type = env.parent_type
772 ## elif self.is_type_arg and env.is_c_class_scope:
773 ## type = Builtin.type_type
775 type = py_object_type
776 self.arg_name = self.name
779 if not self.name in self.templates:
780 error(self.pos, "'%s' is not a type identifier" % self.name)
781 type = PyrexTypes.TemplatePlaceholderType(self.name)
783 error(self.pos, "'%s' is not a type identifier" % self.name)
785 if not type.is_numeric or type.is_complex:
786 error(self.pos, "can only complexify c numeric types")
787 type = PyrexTypes.CComplexType(type)
788 type.create_declaration_utility_code(env)
789 elif type is Builtin.complex_type:
790 # Special case: optimise builtin complex type into C's
791 # double complex. The parser cannot do this (as for the
792 # normal scalar types) as the user may have redeclared the
793 # 'complex' type. Testing for the exact type here works.
794 type = PyrexTypes.c_double_complex_type
795 type.create_declaration_utility_code(env)
800 return PyrexTypes.error_type
802 class CNestedBaseTypeNode(CBaseTypeNode):
803 # For C++ classes that live inside other C++ classes.
806 # base_type CBaseTypeNode
808 child_attrs = ['base_type']
810 def analyse(self, env, could_be_name = None):
811 base_type = self.base_type.analyse(env)
812 if base_type is PyrexTypes.error_type:
813 return PyrexTypes.error_type
814 if not base_type.is_cpp_class:
815 error(self.pos, "'%s' is not a valid type scope" % base_type)
816 return PyrexTypes.error_type
817 type_entry = base_type.scope.lookup_here(self.name)
818 if not type_entry or not type_entry.is_type:
819 error(self.pos, "'%s.%s' is not a type identifier" % (base_type, self.name))
820 return PyrexTypes.error_type
821 return type_entry.type
823 class TemplatedTypeNode(CBaseTypeNode):
825 # positional_args [ExprNode] List of positional arguments
826 # keyword_args DictNode Keyword arguments
827 # base_type_node CBaseTypeNode
830 # type PyrexTypes.BufferType or PyrexTypes.CppClassType ...containing the right options
833 child_attrs = ["base_type_node", "positional_args",
834 "keyword_args", "dtype_node"]
840 def analyse(self, env, could_be_name = False, base_type = None):
841 if base_type is None:
842 base_type = self.base_type_node.analyse(env)
843 if base_type.is_error: return base_type
845 if base_type.is_cpp_class:
847 if self.keyword_args and self.keyword_args.key_value_pairs:
848 error(self.pos, "c++ templates cannot take keyword arguments");
849 self.type = PyrexTypes.error_type
852 for template_node in self.positional_args:
853 type = template_node.analyse_as_type(env)
855 error(template_node.pos, "unknown type in template argument")
857 template_types.append(type)
858 self.type = base_type.specialize_here(self.pos, template_types)
860 elif base_type.is_pyobject:
864 options = Buffer.analyse_buffer_options(
867 self.positional_args,
869 base_type.buffer_defaults)
871 if sys.version_info[0] < 3:
872 # Py 2.x enforces byte strings as keyword arguments ...
873 options = dict([ (name.encode('ASCII'), value)
874 for name, value in options.items() ])
876 self.type = PyrexTypes.BufferType(base_type, **options)
880 empty_declarator = CNameDeclaratorNode(self.pos, name="", cname=None)
881 if len(self.positional_args) > 1 or self.keyword_args.key_value_pairs:
882 error(self.pos, "invalid array declaration")
883 self.type = PyrexTypes.error_type
885 # It would be nice to merge this class with CArrayDeclaratorNode,
886 # but arrays are part of the declaration, not the type...
887 if not self.positional_args:
890 dimension = self.positional_args[0]
891 self.array_declarator = CArrayDeclaratorNode(self.pos,
892 base = empty_declarator,
893 dimension = dimension)
894 self.type = self.array_declarator.analyse(base_type, env)[1]
898 class CComplexBaseTypeNode(CBaseTypeNode):
899 # base_type CBaseTypeNode
900 # declarator CDeclaratorNode
902 child_attrs = ["base_type", "declarator"]
904 def analyse(self, env, could_be_name = False):
905 base = self.base_type.analyse(env, could_be_name)
906 _, type = self.declarator.analyse(base, env)
910 class CVarDefNode(StatNode):
911 # C variable definition or forward/extern function declaration.
913 # visibility 'private' or 'public' or 'extern'
914 # base_type CBaseTypeNode
915 # declarators [CDeclaratorNode]
919 # decorators [cython.locals(...)] or None
920 # directive_locals { string : NameNode } locals defined by cython.locals(...)
922 child_attrs = ["base_type", "declarators"]
925 directive_locals = {}
927 def analyse_declarations(self, env, dest_scope = None):
930 self.dest_scope = dest_scope
931 base_type = self.base_type.analyse(env)
933 # If the field is an external typedef, we cannot be sure about the type,
934 # so do conversion ourself rather than rely on the CPython mechanism (through
935 # a property; made in AnalyseDeclarationsTransform).
936 if (dest_scope.is_c_class_scope
937 and self.visibility in ('public', 'readonly')):
940 need_property = False
941 visibility = self.visibility
943 for declarator in self.declarators:
944 name_declarator, type = declarator.analyse(base_type, env)
945 if not type.is_complete():
946 if not (self.visibility == 'extern' and type.is_array):
947 error(declarator.pos,
948 "Variable type '%s' is incomplete" % type)
949 if self.visibility == 'extern' and type.is_pyobject:
950 error(declarator.pos,
951 "Python object cannot be declared extern")
952 name = name_declarator.name
953 cname = name_declarator.cname
955 error(declarator.pos, "Missing name in declaration.")
957 if type.is_cfunction:
958 entry = dest_scope.declare_cfunction(name, type, declarator.pos,
959 cname = cname, visibility = self.visibility, in_pxd = self.in_pxd,
961 if entry is not None:
962 entry.directive_locals = self.directive_locals
964 if self.directive_locals:
965 error(self.pos, "Decorators can only be followed by functions")
966 if self.in_pxd and self.visibility != 'extern':
968 "Only 'extern' C variable declaration allowed in .pxd file")
969 entry = dest_scope.declare_var(name, type, declarator.pos,
970 cname = cname, visibility = visibility, is_cdef = 1)
971 entry.needs_property = need_property
974 class CStructOrUnionDefNode(StatNode):
976 # cname string or None
977 # kind "struct" or "union"
978 # typedef_flag boolean
979 # visibility "public" or "private"
981 # attributes [CVarDefNode] or None
985 child_attrs = ["attributes"]
987 def analyse_declarations(self, env):
989 if self.visibility == 'extern' and self.packed:
990 error(self.pos, "Cannot declare extern struct as 'packed'")
991 if self.attributes is not None:
992 scope = StructOrUnionScope(self.name)
993 self.entry = env.declare_struct_or_union(
994 self.name, self.kind, scope, self.typedef_flag, self.pos,
995 self.cname, visibility = self.visibility, packed = self.packed)
996 if self.attributes is not None:
997 if self.in_pxd and not env.in_cinclude:
998 self.entry.defined_in_pxd = 1
999 for attr in self.attributes:
1000 attr.analyse_declarations(env, scope)
1001 if self.visibility != 'extern':
1002 need_typedef_indirection = False
1003 for attr in scope.var_entries:
1005 while type.is_array:
1006 type = type.base_type
1007 if type == self.entry.type:
1008 error(attr.pos, "Struct cannot contain itself as a member.")
1009 if self.typedef_flag:
1011 type = type.base_type
1012 if type == self.entry.type:
1013 need_typedef_indirection = True
1014 if need_typedef_indirection:
1015 # C can't handle typedef structs that refer to themselves.
1016 struct_entry = self.entry
1017 self.entry = env.declare_typedef(
1018 self.name, struct_entry.type, self.pos,
1019 cname = self.cname, visibility='ignore')
1020 struct_entry.type.typedef_flag = False
1021 # FIXME: this might be considered a hack ;-)
1022 struct_entry.cname = struct_entry.type.cname = \
1023 '_' + self.entry.type.typedef_cname
1025 def analyse_expressions(self, env):
1028 def generate_execution_code(self, code):
1032 class CppClassNode(CStructOrUnionDefNode):
1035 # cname string or None
1036 # visibility "extern"
1038 # attributes [CVarDefNode] or None
1040 # base_classes [string]
1041 # templates [string] or None
1043 def analyse_declarations(self, env):
1045 if self.attributes is not None:
1046 scope = CppClassScope(self.name, env)
1047 base_class_types = []
1048 for base_class_name in self.base_classes:
1049 base_class_entry = env.lookup(base_class_name)
1050 if base_class_entry is None:
1051 error(self.pos, "'%s' not found" % base_class_name)
1052 elif not base_class_entry.is_type or not base_class_entry.type.is_cpp_class:
1053 error(self.pos, "'%s' is not a cpp class type" % base_class_name)
1055 base_class_types.append(base_class_entry.type)
1056 if self.templates is None:
1057 template_types = None
1059 template_types = [PyrexTypes.TemplatePlaceholderType(template_name) for template_name in self.templates]
1060 self.entry = env.declare_cpp_class(
1061 self.name, scope, self.pos,
1062 self.cname, base_class_types, visibility = self.visibility, templates = template_types)
1063 self.entry.is_cpp_class = 1
1064 if self.attributes is not None:
1065 if self.in_pxd and not env.in_cinclude:
1066 self.entry.defined_in_pxd = 1
1067 for attr in self.attributes:
1068 attr.analyse_declarations(scope)
1070 class CEnumDefNode(StatNode):
1071 # name string or None
1072 # cname string or None
1073 # items [CEnumDefItemNode]
1074 # typedef_flag boolean
1075 # visibility "public" or "private"
1079 child_attrs = ["items"]
1081 def analyse_declarations(self, env):
1082 self.entry = env.declare_enum(self.name, self.pos,
1083 cname = self.cname, typedef_flag = self.typedef_flag,
1084 visibility = self.visibility)
1085 if self.items is not None:
1086 if self.in_pxd and not env.in_cinclude:
1087 self.entry.defined_in_pxd = 1
1088 for item in self.items:
1089 item.analyse_declarations(env, self.entry)
1091 def analyse_expressions(self, env):
1094 def generate_execution_code(self, code):
1095 if self.visibility == 'public':
1096 temp = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
1097 for item in self.entry.enum_values:
1098 code.putln("%s = PyInt_FromLong(%s); %s" % (
1101 code.error_goto_if_null(temp, item.pos)))
1102 code.put_gotref(temp)
1103 code.putln('if (__Pyx_SetAttrString(%s, "%s", %s) < 0) %s' % (
1104 Naming.module_cname,
1107 code.error_goto(item.pos)))
1108 code.put_decref_clear(temp, PyrexTypes.py_object_type)
1109 code.funcstate.release_temp(temp)
1112 class CEnumDefItemNode(StatNode):
1114 # cname string or None
1115 # value ExprNode or None
1117 child_attrs = ["value"]
1119 def analyse_declarations(self, env, enum_entry):
1121 self.value.analyse_const_expression(env)
1122 if not self.value.type.is_int:
1123 self.value = self.value.coerce_to(PyrexTypes.c_int_type, env)
1124 self.value.analyse_const_expression(env)
1125 entry = env.declare_const(self.name, enum_entry.type,
1126 self.value, self.pos, cname = self.cname,
1127 visibility = enum_entry.visibility)
1128 enum_entry.enum_values.append(entry)
1131 class CTypeDefNode(StatNode):
1132 # base_type CBaseTypeNode
1133 # declarator CDeclaratorNode
1134 # visibility "public" or "private"
1137 child_attrs = ["base_type", "declarator"]
1139 def analyse_declarations(self, env):
1140 base = self.base_type.analyse(env)
1141 name_declarator, type = self.declarator.analyse(base, env)
1142 name = name_declarator.name
1143 cname = name_declarator.cname
1144 entry = env.declare_typedef(name, type, self.pos,
1145 cname = cname, visibility = self.visibility)
1146 if self.in_pxd and not env.in_cinclude:
1147 entry.defined_in_pxd = 1
1149 def analyse_expressions(self, env):
1151 def generate_execution_code(self, code):
1155 class FuncDefNode(StatNode, BlockNode):
1156 # Base class for function definition nodes.
1158 # return_type PyrexType
1159 # #filename string C name of filename string const
1160 # entry Symtab.Entry
1161 # needs_closure boolean Whether or not this function has inner functions/classes/yield
1162 # needs_outer_scope boolean Whether or not this function requires outer scope
1163 # directive_locals { string : NameNode } locals defined by cython.locals(...)
1167 needs_closure = False
1168 needs_outer_scope = False
1171 def analyse_default_values(self, env):
1172 genv = env.global_scope()
1174 for arg in self.args:
1178 arg.default.analyse_types(env)
1179 arg.default = arg.default.coerce_to(arg.type, genv)
1182 "This argument cannot have a default value")
1187 error(arg.pos, "Non-default argument following default argument")
1189 def need_gil_acquisition(self, lenv):
1192 def create_local_scope(self, env):
1194 while genv.is_py_class_scope or genv.is_c_class_scope:
1195 genv = genv.outer_scope
1196 if self.needs_closure:
1197 lenv = ClosureScope(name=self.entry.name,
1199 scope_name=self.entry.cname)
1201 lenv = LocalScope(name=self.entry.name,
1204 lenv.return_type = self.return_type
1205 type = self.entry.type
1206 if type.is_cfunction:
1207 lenv.nogil = type.nogil and not type.with_gil
1208 self.local_scope = lenv
1209 lenv.directives = env.directives
1212 def generate_function_definitions(self, env, code):
1215 lenv = self.local_scope
1216 if lenv.is_closure_scope and not lenv.is_passthrough:
1217 outer_scope_cname = "%s->%s" % (Naming.cur_scope_cname,
1218 Naming.outer_scope_cname)
1220 outer_scope_cname = Naming.outer_scope_cname
1221 lenv.mangle_closure_cnames(outer_scope_cname)
1222 # Generate closure function definitions
1223 self.body.generate_function_definitions(lenv, code)
1224 # generate lambda function definitions
1225 self.generate_lambda_definitions(lenv, code)
1227 is_getbuffer_slot = (self.entry.name == "__getbuffer__" and
1228 self.entry.scope.is_c_class_scope)
1229 is_releasebuffer_slot = (self.entry.name == "__releasebuffer__" and
1230 self.entry.scope.is_c_class_scope)
1231 is_buffer_slot = is_getbuffer_slot or is_releasebuffer_slot
1233 if 'cython_unused' not in self.modifiers:
1234 self.modifiers = self.modifiers + ['cython_unused']
1236 preprocessor_guard = None
1237 if self.entry.is_special and not is_buffer_slot:
1238 slot = TypeSlots.method_name_to_slot.get(self.entry.name)
1240 preprocessor_guard = slot.preprocessor_guard_code()
1241 if (self.entry.name == '__long__' and
1242 not self.entry.scope.lookup_here('__int__')):
1243 preprocessor_guard = None
1245 profile = code.globalstate.directives['profile']
1248 error(self.pos, "Cannot profile nogil function.")
1249 code.globalstate.use_utility_code(profile_utility_code)
1251 # Generate C code for header and body of function
1252 code.enter_cfunc_scope()
1253 code.return_from_error_cleanup_label = code.new_label()
1255 # ----- Top-level constants used by this function
1256 code.mark_pos(self.pos)
1257 self.generate_cached_builtins_decls(lenv, code)
1258 # ----- Function header
1261 if preprocessor_guard:
1262 code.putln(preprocessor_guard)
1264 with_pymethdef = self.needs_assignment_synthesis(env, code)
1266 self.py_func.generate_function_header(code,
1267 with_pymethdef = with_pymethdef,
1269 self.generate_function_header(code,
1270 with_pymethdef = with_pymethdef)
1271 # ----- Local variable declarations
1272 # Find function scope
1274 while cenv.is_py_class_scope or cenv.is_c_class_scope:
1275 cenv = cenv.outer_scope
1276 if self.needs_closure:
1277 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1279 elif self.needs_outer_scope:
1280 if lenv.is_passthrough:
1281 code.put(lenv.scope_class.type.declaration_code(Naming.cur_scope_cname))
1283 code.put(cenv.scope_class.type.declaration_code(Naming.outer_scope_cname))
1285 self.generate_argument_declarations(lenv, code)
1286 for entry in lenv.var_entries:
1287 if not entry.in_closure:
1288 code.put_var_declaration(entry)
1290 if not self.return_type.is_void:
1291 if self.return_type.is_pyobject:
1295 (self.return_type.declaration_code(Naming.retval_cname),
1297 tempvardecl_code = code.insertion_point()
1298 self.generate_keyword_list(code)
1300 code.put_trace_declarations()
1301 # ----- Extern library function declarations
1302 lenv.generate_library_function_declarations(code)
1303 # ----- GIL acquisition
1304 acquire_gil = self.acquire_gil
1306 env.use_utility_code(force_init_threads_utility_code)
1307 code.putln("#ifdef WITH_THREAD")
1308 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
1309 code.putln("#endif")
1310 # ----- set up refnanny
1312 code.put_setup_refcount_context(self.entry.name)
1313 # ----- Automatic lead-ins for certain special functions
1314 if is_getbuffer_slot:
1315 self.getbuffer_init(code)
1316 # ----- Create closure scope object
1317 if self.needs_closure:
1318 code.putln("%s = (%s)%s->tp_new(%s, %s, NULL);" % (
1319 Naming.cur_scope_cname,
1320 lenv.scope_class.type.declaration_code(''),
1321 lenv.scope_class.type.typeptr_cname,
1322 lenv.scope_class.type.typeptr_cname,
1323 Naming.empty_tuple))
1324 code.putln("if (unlikely(!%s)) {" % Naming.cur_scope_cname)
1325 if is_getbuffer_slot:
1326 self.getbuffer_error_cleanup(code)
1328 code.put_finish_refcount_context()
1329 # FIXME: what if the error return value is a Python value?
1330 code.putln("return %s;" % self.error_value())
1332 code.put_gotref(Naming.cur_scope_cname)
1333 # Note that it is unsafe to decref the scope at this point.
1334 if self.needs_outer_scope:
1335 code.putln("%s = (%s)%s;" % (
1337 cenv.scope_class.type.declaration_code(''),
1339 if lenv.is_passthrough:
1340 code.putln("%s = %s;" % (Naming.cur_scope_cname, outer_scope_cname));
1341 elif self.needs_closure:
1342 # inner closures own a reference to their outer parent
1343 code.put_incref(outer_scope_cname, cenv.scope_class.type)
1344 code.put_giveref(outer_scope_cname)
1345 # ----- Trace function call
1347 # this looks a bit late, but if we don't get here due to a
1348 # fatal error before hand, it's not really worth tracing
1349 code.put_trace_call(self.entry.name, self.pos)
1350 # ----- Fetch arguments
1351 self.generate_argument_parsing_code(env, code)
1352 # If an argument is assigned to in the body, we must
1353 # incref it to properly keep track of refcounts.
1354 for entry in lenv.arg_entries:
1355 if entry.type.is_pyobject:
1356 if (acquire_gil or entry.assignments) and not entry.in_closure:
1357 code.put_var_incref(entry)
1358 # ----- Initialise local variables
1359 for entry in lenv.var_entries:
1360 if entry.type.is_pyobject and entry.init_to_none and entry.used:
1361 code.put_init_var_to_py_none(entry)
1362 # ----- Initialise local buffer auxiliary variables
1363 for entry in lenv.var_entries + lenv.arg_entries:
1364 if entry.type.is_buffer and entry.buffer_aux.buffer_info_var.used:
1365 code.putln("%s.buf = NULL;" %
1366 entry.buffer_aux.buffer_info_var.cname)
1367 # ----- Check and convert arguments
1368 self.generate_argument_type_tests(code)
1369 # ----- Acquire buffer arguments
1370 for entry in lenv.arg_entries:
1371 if entry.type.is_buffer:
1372 Buffer.put_acquire_arg_buffer(entry, code, self.pos)
1374 # -------------------------
1375 # ----- Function body -----
1376 # -------------------------
1377 self.body.generate_execution_code(code)
1379 # ----- Default return value
1381 if self.return_type.is_pyobject:
1382 #if self.return_type.is_extension_type:
1383 # lhs = "(PyObject *)%s" % Naming.retval_cname
1385 lhs = Naming.retval_cname
1386 code.put_init_to_py_none(lhs, self.return_type)
1388 val = self.return_type.default_value
1390 code.putln("%s = %s;" % (Naming.retval_cname, val))
1391 # ----- Error cleanup
1392 if code.error_label in code.labels_used:
1393 code.put_goto(code.return_label)
1394 code.put_label(code.error_label)
1395 for cname, type in code.funcstate.all_managed_temps():
1396 code.put_xdecref(cname, type)
1398 # Clean up buffers -- this calls a Python function
1399 # so need to save and restore error state
1400 buffers_present = len(lenv.buffer_entries) > 0
1402 code.globalstate.use_utility_code(restore_exception_utility_code)
1403 code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
1404 code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
1405 for entry in lenv.buffer_entries:
1406 Buffer.put_release_buffer_code(code, entry)
1407 #code.putln("%s = 0;" % entry.cname)
1408 code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
1410 err_val = self.error_value()
1411 exc_check = self.caller_will_check_exceptions()
1412 if err_val is not None or exc_check:
1413 # TODO: Fix exception tracing (though currently unused by cProfile).
1414 # code.globalstate.use_utility_code(get_exception_tuple_utility_code)
1415 # code.put_trace_exception()
1416 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
1418 warning(self.entry.pos, "Unraisable exception in function '%s'." \
1419 % self.entry.qualified_name, 0)
1421 '__Pyx_WriteUnraisable("%s");' %
1422 self.entry.qualified_name)
1423 env.use_utility_code(unraisable_exception_utility_code)
1424 env.use_utility_code(restore_exception_utility_code)
1425 default_retval = self.return_type.default_value
1426 if err_val is None and default_retval:
1427 err_val = default_retval
1428 if err_val is not None:
1429 code.putln("%s = %s;" % (Naming.retval_cname, err_val))
1431 if is_getbuffer_slot:
1432 self.getbuffer_error_cleanup(code)
1434 # If we are using the non-error cleanup section we should
1435 # jump past it if we have an error. The if-test below determine
1436 # whether this section is used.
1437 if buffers_present or is_getbuffer_slot:
1438 code.put_goto(code.return_from_error_cleanup_label)
1441 # ----- Non-error return cleanup
1442 code.put_label(code.return_label)
1443 for entry in lenv.buffer_entries:
1445 Buffer.put_release_buffer_code(code, entry)
1446 if is_getbuffer_slot:
1447 self.getbuffer_normal_cleanup(code)
1448 # ----- Return cleanup for both error and no-error return
1449 code.put_label(code.return_from_error_cleanup_label)
1450 if not Options.init_local_none:
1451 for entry in lenv.var_entries:
1452 if lenv.control_flow.get_state((entry.name, 'initialized')) is not True:
1453 entry.xdecref_cleanup = 1
1455 for entry in lenv.var_entries:
1456 if entry.type.is_pyobject:
1457 if entry.used and not entry.in_closure:
1458 code.put_var_decref(entry)
1459 elif entry.in_closure and self.needs_closure:
1460 code.put_giveref(entry.cname)
1461 # Decref any increfed args
1462 for entry in lenv.arg_entries:
1463 if entry.type.is_pyobject:
1464 if entry.in_closure:
1465 code.put_var_giveref(entry)
1466 elif acquire_gil or entry.assignments:
1467 code.put_var_decref(entry)
1468 if self.needs_closure:
1469 code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
1472 # This code is duplicated in ModuleNode.generate_module_init_func
1474 default_retval = self.return_type.default_value
1475 err_val = self.error_value()
1476 if err_val is None and default_retval:
1477 err_val = default_retval
1478 if self.return_type.is_pyobject:
1479 code.put_xgiveref(self.return_type.as_pyobject(Naming.retval_cname))
1481 if self.entry.is_special and self.entry.name == "__hash__":
1482 # Returning -1 for __hash__ is supposed to signal an error
1483 # We do as Python instances and coerce -1 into -2.
1484 code.putln("if (unlikely(%s == -1) && !PyErr_Occurred()) %s = -2;" % (
1485 Naming.retval_cname, Naming.retval_cname))
1488 if self.return_type.is_pyobject:
1489 code.put_trace_return(Naming.retval_cname)
1491 code.put_trace_return("Py_None")
1493 code.put_finish_refcount_context()
1496 code.putln("#ifdef WITH_THREAD")
1497 code.putln("PyGILState_Release(_save);")
1498 code.putln("#endif")
1500 if not self.return_type.is_void:
1501 code.putln("return %s;" % Naming.retval_cname)
1505 if preprocessor_guard:
1506 code.putln("#endif /*!(%s)*/" % preprocessor_guard)
1508 # ----- Go back and insert temp variable declarations
1509 tempvardecl_code.put_temp_declarations(code.funcstate)
1510 # ----- Python version
1511 code.exit_cfunc_scope()
1513 self.py_func.generate_function_definitions(env, code)
1514 self.generate_wrapper_functions(code)
1516 def declare_argument(self, env, arg):
1517 if arg.type.is_void:
1518 error(arg.pos, "Invalid use of 'void'")
1519 elif not arg.type.is_complete() and not arg.type.is_array:
1521 "Argument type '%s' is incomplete" % arg.type)
1522 return env.declare_arg(arg.name, arg.type, arg.pos)
1524 def generate_arg_type_test(self, arg, code):
1525 # Generate type test for one argument.
1526 if arg.type.typeobj_is_available():
1527 code.globalstate.use_utility_code(arg_type_test_utility_code)
1528 typeptr_cname = arg.type.typeptr_cname
1529 arg_code = "((PyObject *)%s)" % arg.entry.cname
1531 'if (unlikely(!__Pyx_ArgTypeTest(%s, %s, %d, "%s", %s))) %s' % (
1536 arg.type.is_builtin_type,
1537 code.error_goto(arg.pos)))
1539 error(arg.pos, "Cannot test type of extern C class "
1540 "without type object name specification")
1542 def generate_arg_none_check(self, arg, code):
1543 # Generate None check for one argument.
1544 code.globalstate.use_utility_code(arg_type_test_utility_code)
1545 code.putln('if (unlikely(((PyObject *)%s) == Py_None)) {' % arg.entry.cname)
1546 code.putln('''PyErr_Format(PyExc_TypeError, "Argument '%s' must not be None"); %s''' % (
1548 code.error_goto(arg.pos)))
1551 def generate_wrapper_functions(self, code):
1554 def generate_execution_code(self, code):
1555 # Evaluate and store argument default values
1556 for arg in self.args:
1557 default = arg.default
1559 if not default.is_literal:
1560 default.generate_evaluation_code(code)
1561 default.make_owned_reference(code)
1562 result = default.result_as(arg.type)
1565 arg.calculate_default_value_code(code),
1567 if arg.type.is_pyobject:
1568 code.put_giveref(default.result())
1569 default.generate_post_assignment_code(code)
1570 default.free_temps(code)
1571 # For Python class methods, create and store function object
1573 self.assmt.generate_execution_code(code)
1576 # Special code for the __getbuffer__ function
1578 def getbuffer_init(self, code):
1579 info = self.local_scope.arg_entries[1].cname
1580 # Python 3.0 betas have a bug in memoryview which makes it call
1581 # getbuffer with a NULL parameter. For now we work around this;
1582 # the following line should be removed when this bug is fixed.
1583 code.putln("if (%s == NULL) return 0;" % info)
1584 code.putln("%s->obj = Py_None; __Pyx_INCREF(Py_None);" % info)
1585 code.put_giveref("%s->obj" % info) # Do not refnanny object within structs
1587 def getbuffer_error_cleanup(self, code):
1588 info = self.local_scope.arg_entries[1].cname
1589 code.put_gotref("%s->obj" % info)
1590 code.putln("__Pyx_DECREF(%s->obj); %s->obj = NULL;" %
1593 def getbuffer_normal_cleanup(self, code):
1594 info = self.local_scope.arg_entries[1].cname
1595 code.putln("if (%s->obj == Py_None) {" % info)
1596 code.put_gotref("Py_None")
1597 code.putln("__Pyx_DECREF(Py_None); %s->obj = NULL;" % info)
1600 class CFuncDefNode(FuncDefNode):
1601 # C function definition.
1603 # modifiers ['inline']
1604 # visibility 'private' or 'public' or 'extern'
1605 # base_type CBaseTypeNode
1606 # declarator CDeclaratorNode
1609 # decorators [DecoratorNode] list of decorators
1611 # with_gil boolean Acquire GIL around body
1613 # py_func wrapper for calling from Python
1614 # overridable whether or not this is a cpdef function
1615 # inline_in_pxd whether this is an inline function in a pxd file
1617 child_attrs = ["base_type", "declarator", "body", "py_func"]
1619 inline_in_pxd = False
1621 directive_locals = {}
1623 def unqualified_name(self):
1624 return self.entry.name
1626 def analyse_declarations(self, env):
1627 self.directive_locals.update(env.directives['locals'])
1628 base_type = self.base_type.analyse(env)
1629 # The 2 here is because we need both function and argument names.
1630 name_declarator, type = self.declarator.analyse(base_type, env, nonempty = 2 * (self.body is not None))
1631 if not type.is_cfunction:
1633 "Suite attached to non-function declaration")
1634 # Remember the actual type according to the function header
1635 # written here, because the type in the symbol table entry
1636 # may be different if we're overriding a C method inherited
1637 # from the base type of an extension type.
1639 type.is_overridable = self.overridable
1640 declarator = self.declarator
1641 while not hasattr(declarator, 'args'):
1642 declarator = declarator.base
1643 self.args = declarator.args
1644 for formal_arg, type_arg in zip(self.args, type.args):
1645 formal_arg.type = type_arg.type
1646 formal_arg.name = type_arg.name
1647 formal_arg.cname = type_arg.cname
1648 name = name_declarator.name
1649 cname = name_declarator.cname
1650 self.entry = env.declare_cfunction(
1651 name, type, self.pos,
1652 cname = cname, visibility = self.visibility,
1653 defining = self.body is not None,
1654 api = self.api, modifiers = self.modifiers)
1655 self.entry.inline_func_in_pxd = self.inline_in_pxd
1656 self.return_type = type.return_type
1658 if self.overridable and not env.is_module_scope:
1659 if len(self.args) < 1 or not self.args[0].type.is_pyobject:
1660 # An error will be produced in the cdef function
1661 self.overridable = False
1663 if self.overridable:
1665 py_func_body = self.call_self_node(is_module_scope = env.is_module_scope)
1666 self.py_func = DefNode(pos = self.pos,
1667 name = self.entry.name,
1670 starstar_arg = None,
1672 body = py_func_body,
1674 self.py_func.is_module_scope = env.is_module_scope
1675 self.py_func.analyse_declarations(env)
1676 self.entry.as_variable = self.py_func.entry
1677 # Reset scope entry the above cfunction
1678 env.entries[name] = self.entry
1679 if not env.is_module_scope or Options.lookup_module_cpdef:
1680 self.override = OverrideCheckNode(self.pos, py_func = self.py_func)
1681 self.body = StatListNode(self.pos, stats=[self.override, self.body])
1682 self.create_local_scope(env)
1684 def call_self_node(self, omit_optional_args=0, is_module_scope=0):
1686 args = self.type.args
1687 if omit_optional_args:
1688 args = args[:len(args) - self.type.optional_arg_count]
1689 arg_names = [arg.name for arg in args]
1691 cfunc = ExprNodes.NameNode(self.pos, name=self.entry.name)
1693 self_arg = ExprNodes.NameNode(self.pos, name=arg_names[0])
1694 cfunc = ExprNodes.AttributeNode(self.pos, obj=self_arg, attribute=self.entry.name)
1695 skip_dispatch = not is_module_scope or Options.lookup_module_cpdef
1696 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)
1697 return ReturnStatNode(pos=self.pos, return_type=PyrexTypes.py_object_type, value=c_call)
1699 def declare_arguments(self, env):
1700 for arg in self.type.args:
1702 error(arg.pos, "Missing argument name")
1703 self.declare_argument(env, arg)
1705 def need_gil_acquisition(self, lenv):
1706 return self.type.with_gil
1708 def nogil_check(self, env):
1710 with_gil = type.with_gil
1711 if type.nogil and not with_gil:
1712 if type.return_type.is_pyobject:
1714 "Function with Python return type cannot be declared nogil")
1715 for entry in self.local_scope.var_entries:
1716 if entry.type.is_pyobject:
1717 error(self.pos, "Function declared nogil has Python locals or temporaries")
1719 def analyse_expressions(self, env):
1720 self.local_scope.directives = env.directives
1721 if self.py_func is not None:
1722 # this will also analyse the default values
1723 self.py_func.analyse_expressions(env)
1725 self.analyse_default_values(env)
1726 self.acquire_gil = self.need_gil_acquisition(self.local_scope)
1728 def needs_assignment_synthesis(self, env, code=None):
1731 def generate_function_header(self, code, with_pymethdef, with_opt_args = 1, with_dispatch = 1, cname = None):
1734 visibility = self.entry.visibility
1735 for arg in type.args[:len(type.args)-type.optional_arg_count]:
1736 arg_decls.append(arg.declaration_code())
1737 if with_dispatch and self.overridable:
1738 arg_decls.append(PyrexTypes.c_int_type.declaration_code(Naming.skip_dispatch_cname))
1739 if type.optional_arg_count and with_opt_args:
1740 arg_decls.append(type.op_arg_struct.declaration_code(Naming.optional_args_cname))
1741 if type.has_varargs:
1742 arg_decls.append("...")
1744 arg_decls = ["void"]
1746 cname = self.entry.func_cname
1747 entity = type.function_header_code(cname, ', '.join(arg_decls))
1748 if visibility == 'public':
1749 dll_linkage = "DL_EXPORT"
1752 header = self.return_type.declaration_code(entity,
1753 dll_linkage = dll_linkage)
1754 if visibility == 'extern':
1755 storage_class = "%s " % Naming.extern_c_macro
1756 elif visibility == 'public':
1759 storage_class = "static "
1760 if 'inline' in self.modifiers:
1761 self.modifiers[self.modifiers.index('inline')] = 'cython_inline'
1762 code.putln("%s%s %s {" % (
1764 ' '.join(self.modifiers).upper(), # macro forms
1767 def generate_argument_declarations(self, env, code):
1768 for arg in self.args:
1770 result = arg.calculate_default_value_code(code)
1771 code.putln('%s = %s;' % (
1772 arg.type.declaration_code(arg.cname), result))
1774 def generate_keyword_list(self, code):
1777 def generate_argument_parsing_code(self, env, code):
1779 if self.type.optional_arg_count:
1780 code.putln('if (%s) {' % Naming.optional_args_cname)
1781 for arg in self.args:
1783 code.putln('if (%s->%sn > %s) {' % (Naming.optional_args_cname, Naming.pyrex_prefix, i))
1784 declarator = arg.declarator
1785 while not hasattr(declarator, 'name'):
1786 declarator = declarator.base
1787 code.putln('%s = %s->%s;' % (arg.cname, Naming.optional_args_cname, self.type.opt_arg_cname(declarator.name)))
1789 for _ in range(self.type.optional_arg_count):
1793 def generate_argument_conversion_code(self, code):
1796 def generate_argument_type_tests(self, code):
1797 # Generate type tests for args whose type in a parent
1798 # class is a supertype of the declared type.
1799 for arg in self.type.args:
1800 if arg.needs_type_test:
1801 self.generate_arg_type_test(arg, code)
1802 elif arg.type.is_pyobject and not arg.accept_none:
1803 self.generate_arg_none_check(arg, code)
1805 def error_value(self):
1806 if self.return_type.is_pyobject:
1810 return self.entry.type.exception_value
1812 def caller_will_check_exceptions(self):
1813 return self.entry.type.exception_check
1815 def generate_wrapper_functions(self, code):
1816 # If the C signature of a function has changed, we need to generate
1817 # wrappers to put in the slots here.
1820 func_type = entry.type
1821 while entry.prev_entry is not None:
1823 entry = entry.prev_entry
1824 entry.func_cname = "%s%swrap_%s" % (self.entry.func_cname, Naming.pyrex_prefix, k)
1826 self.generate_function_header(code,
1828 with_dispatch = entry.type.is_overridable,
1829 with_opt_args = entry.type.optional_arg_count,
1830 cname = entry.func_cname)
1831 if not self.return_type.is_void:
1833 args = self.type.args
1834 arglist = [arg.cname for arg in args[:len(args)-self.type.optional_arg_count]]
1835 if entry.type.is_overridable:
1836 arglist.append(Naming.skip_dispatch_cname)
1837 elif func_type.is_overridable:
1839 if entry.type.optional_arg_count:
1840 arglist.append(Naming.optional_args_cname)
1841 elif func_type.optional_arg_count:
1842 arglist.append('NULL')
1843 code.putln('%s(%s);' % (self.entry.func_cname, ', '.join(arglist)))
1847 class PyArgDeclNode(Node):
1848 # Argument which must be a Python object (used
1849 # for * and ** arguments).
1852 # entry Symtab.Entry
1853 # annotation ExprNode or None Py3 argument annotation
1856 def generate_function_definitions(self, env, code):
1857 self.entry.generate_function_definitions(env, code)
1859 class DecoratorNode(Node):
1862 # decorator NameNode or CallNode or AttributeNode
1863 child_attrs = ['decorator']
1866 class DefNode(FuncDefNode):
1867 # A Python function definition.
1869 # name string the Python name of the function
1870 # lambda_name string the internal name of a lambda 'function'
1871 # decorators [DecoratorNode] list of decorators
1872 # args [CArgDeclNode] formal arguments
1873 # star_arg PyArgDeclNode or None * argument
1874 # starstar_arg PyArgDeclNode or None ** argument
1875 # doc EncodedString or None
1877 # return_type_annotation
1878 # ExprNode or None the Py3 return type annotation
1880 # The following subnode is constructed internally
1881 # when the def statement is inside a Python class definition.
1883 # assmt AssignmentNode Function construction/assignment
1885 child_attrs = ["args", "star_arg", "starstar_arg", "body", "decorators"]
1890 num_required_kw_args = 0
1891 reqd_kw_flags_cname = "0"
1894 return_type_annotation = None
1899 def __init__(self, pos, **kwds):
1900 FuncDefNode.__init__(self, pos, **kwds)
1902 for arg in self.args:
1909 self.num_kwonly_args = k
1910 self.num_required_kw_args = rk
1911 self.num_required_args = r
1913 def as_cfunction(self, cfunc=None, scope=None):
1915 error(self.star_arg.pos, "cdef function cannot have star argument")
1916 if self.starstar_arg:
1917 error(self.starstar_arg.pos, "cdef function cannot have starstar argument")
1920 for formal_arg in self.args:
1921 name_declarator, type = formal_arg.analyse(scope, nonempty=1)
1922 cfunc_args.append(PyrexTypes.CFuncTypeArg(name = name_declarator.name,
1924 type = py_object_type,
1925 pos = formal_arg.pos))
1926 cfunc_type = PyrexTypes.CFuncType(return_type = py_object_type,
1928 has_varargs = False,
1929 exception_value = None,
1930 exception_check = False,
1933 is_overridable = True)
1934 cfunc = CVarDefNode(self.pos, type=cfunc_type)
1938 cfunc_type = cfunc.type
1939 if len(self.args) != len(cfunc_type.args) or cfunc_type.has_varargs:
1940 error(self.pos, "wrong number of arguments")
1941 error(cfunc.pos, "previous declaration here")
1942 for i, (formal_arg, type_arg) in enumerate(zip(self.args, cfunc_type.args)):
1943 name_declarator, type = formal_arg.analyse(scope, nonempty=1,
1944 is_self_arg = (i == 0 and scope.is_c_class_scope))
1945 if type is None or type is PyrexTypes.py_object_type:
1946 formal_arg.type = type_arg.type
1947 formal_arg.name_declarator = name_declarator
1949 if cfunc_type.exception_value is None:
1950 exception_value = None
1952 exception_value = ExprNodes.ConstNode(self.pos, value=cfunc_type.exception_value, type=cfunc_type.return_type)
1953 declarator = CFuncDeclaratorNode(self.pos,
1954 base = CNameDeclaratorNode(self.pos, name=self.name, cname=None),
1956 has_varargs = False,
1957 exception_check = cfunc_type.exception_check,
1958 exception_value = exception_value,
1959 with_gil = cfunc_type.with_gil,
1960 nogil = cfunc_type.nogil)
1961 return CFuncDefNode(self.pos,
1963 base_type = CAnalysedBaseTypeNode(self.pos, type=cfunc_type.return_type),
1964 declarator = declarator,
1967 overridable = cfunc_type.is_overridable,
1969 with_gil = cfunc_type.with_gil,
1970 nogil = cfunc_type.nogil,
1971 visibility = 'private',
1973 directive_locals = getattr(cfunc, 'directive_locals', {}))
1975 def analyse_declarations(self, env):
1976 self.is_classmethod = self.is_staticmethod = False
1978 for decorator in self.decorators:
1979 func = decorator.decorator
1981 self.is_classmethod |= func.name == 'classmethod'
1982 self.is_staticmethod |= func.name == 'staticmethod'
1984 if self.is_classmethod and env.lookup_here('classmethod'):
1985 # classmethod() was overridden - not much we can do here ...
1986 self.is_classmethod = False
1987 if self.is_staticmethod and env.lookup_here('staticmethod'):
1988 # staticmethod() was overridden - not much we can do here ...
1989 self.is_staticmethod = False
1991 if self.name == '__new__' and env.is_py_class_scope:
1992 self.is_staticmethod = 1
1994 self.analyse_argument_types(env)
1995 if self.name == '<lambda>':
1996 self.declare_lambda_function(env)
1998 self.declare_pyfunction(env)
1999 self.analyse_signature(env)
2000 self.return_type = self.entry.signature.return_type()
2001 self.create_local_scope(env)
2003 def analyse_argument_types(self, env):
2004 directive_locals = self.directive_locals = env.directives['locals']
2005 allow_none_for_extension_args = env.directives['allow_none_for_extension_args']
2006 for arg in self.args:
2007 if hasattr(arg, 'name'):
2009 name_declarator = None
2011 base_type = arg.base_type.analyse(env)
2012 name_declarator, type = \
2013 arg.declarator.analyse(base_type, env)
2014 arg.name = name_declarator.name
2015 if arg.name in directive_locals:
2016 type_node = directive_locals[arg.name]
2017 other_type = type_node.analyse_as_type(env)
2018 if other_type is None:
2019 error(type_node.pos, "Not a type")
2020 elif (type is not PyrexTypes.py_object_type
2021 and not type.same_as(other_type)):
2022 error(arg.base_type.pos, "Signature does not agree with previous declaration")
2023 error(type_node.pos, "Previous declaration here")
2026 if name_declarator and name_declarator.cname:
2028 "Python function argument cannot have C name specification")
2029 arg.type = type.as_argument_type()
2031 arg.needs_conversion = 0
2032 arg.needs_type_test = 0
2034 if arg.type.is_pyobject:
2036 arg.accept_none = True
2038 arg.accept_none = False
2039 elif arg.type.is_extension_type or arg.type.is_builtin_type:
2040 if arg.default and arg.default.constant_result is None:
2041 # special case: def func(MyType obj = None)
2042 arg.accept_none = True
2044 # default depends on compiler directive
2045 arg.accept_none = allow_none_for_extension_args
2047 # probably just a plain 'object'
2048 arg.accept_none = True
2050 arg.accept_none = True # won't be used, but must be there
2052 error(arg.pos, "Only Python type arguments can have 'not None'")
2054 error(arg.pos, "Only Python type arguments can have 'or None'")
2056 def analyse_signature(self, env):
2057 if self.entry.is_special:
2058 self.entry.trivial_signature = len(self.args) == 1 and not (self.star_arg or self.starstar_arg)
2059 elif not env.directives['always_allow_keywords'] and not (self.star_arg or self.starstar_arg):
2060 # Use the simpler calling signature for zero- and one-argument functions.
2061 if self.entry.signature is TypeSlots.pyfunction_signature:
2062 if len(self.args) == 0:
2063 self.entry.signature = TypeSlots.pyfunction_noargs
2064 elif len(self.args) == 1:
2065 if self.args[0].default is None and not self.args[0].kw_only:
2066 self.entry.signature = TypeSlots.pyfunction_onearg
2067 elif self.entry.signature is TypeSlots.pymethod_signature:
2068 if len(self.args) == 1:
2069 self.entry.signature = TypeSlots.unaryfunc
2070 elif len(self.args) == 2:
2071 if self.args[1].default is None and not self.args[1].kw_only:
2072 self.entry.signature = TypeSlots.ibinaryfunc
2074 sig = self.entry.signature
2075 nfixed = sig.num_fixed_args()
2076 if sig is TypeSlots.pymethod_signature and nfixed == 1 \
2077 and len(self.args) == 0 and self.star_arg:
2078 # this is the only case where a diverging number of
2079 # arguments is not an error - when we have no explicit
2080 # 'self' parameter as in method(*args)
2081 sig = self.entry.signature = TypeSlots.pyfunction_signature # self is not 'really' used
2082 self.self_in_stararg = 1
2085 for i in range(min(nfixed, len(self.args))):
2088 if sig.is_self_arg(i) and not self.is_staticmethod:
2089 if self.is_classmethod:
2091 arg.hdr_type = arg.type = Builtin.type_type
2094 arg.hdr_type = arg.type = env.parent_type
2095 arg.needs_conversion = 0
2097 arg.hdr_type = sig.fixed_arg_type(i)
2098 if not arg.type.same_as(arg.hdr_type):
2099 if arg.hdr_type.is_pyobject and arg.type.is_pyobject:
2100 arg.needs_type_test = 1
2102 arg.needs_conversion = 1
2103 if arg.needs_conversion:
2104 arg.hdr_cname = Naming.arg_prefix + arg.name
2106 arg.hdr_cname = Naming.var_prefix + arg.name
2108 if nfixed > len(self.args):
2109 self.bad_signature()
2111 elif nfixed < len(self.args):
2112 if not sig.has_generic_args:
2113 self.bad_signature()
2114 for arg in self.args:
2115 if arg.is_generic and \
2116 (arg.type.is_extension_type or arg.type.is_builtin_type):
2117 arg.needs_type_test = 1
2119 def bad_signature(self):
2120 sig = self.entry.signature
2121 expected_str = "%d" % sig.num_fixed_args()
2122 if sig.has_generic_args:
2123 expected_str = expected_str + " or more"
2125 if name.startswith("__") and name.endswith("__"):
2126 desc = "Special method"
2130 "%s %s has wrong number of arguments "
2131 "(%d declared, %s expected)" % (
2132 desc, self.name, len(self.args), expected_str))
2134 def signature_has_nongeneric_args(self):
2135 argcount = len(self.args)
2136 if argcount == 0 or (
2137 argcount == 1 and (self.args[0].is_self_arg or
2138 self.args[0].is_type_arg)):
2142 def signature_has_generic_args(self):
2143 return self.entry.signature.has_generic_args
2145 def declare_pyfunction(self, env):
2146 #print "DefNode.declare_pyfunction:", self.name, "in", env ###
2148 entry = env.lookup_here(name)
2149 if entry and entry.type.is_cfunction and not self.is_wrapper:
2150 warning(self.pos, "Overriding cdef method with def method.", 5)
2151 entry = env.declare_pyfunction(name, self.pos, allow_redefine=not self.is_wrapper)
2153 prefix = env.next_id(env.scope_prefix)
2155 entry.func_cname = \
2156 Naming.pyfunc_prefix + prefix + name
2157 entry.pymethdef_cname = \
2158 Naming.pymethdef_prefix + prefix + name
2159 if Options.docstrings:
2160 entry.doc = embed_position(self.pos, self.doc)
2162 Naming.funcdoc_prefix + prefix + name
2163 if entry.is_special:
2164 if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
2165 entry.wrapperbase_cname = None
2167 entry.wrapperbase_cname = Naming.wrapperbase_prefix + prefix + name
2171 def declare_lambda_function(self, env):
2173 prefix = env.scope_prefix
2175 Naming.lambda_func_prefix + u'funcdef' + prefix + self.lambda_name
2176 entry = env.declare_lambda_function(func_cname, self.pos)
2177 entry.pymethdef_cname = \
2178 Naming.lambda_func_prefix + u'methdef' + prefix + self.lambda_name
2179 entry.qualified_name = env.qualify_name(self.lambda_name)
2183 def declare_arguments(self, env):
2184 for arg in self.args:
2186 error(arg.pos, "Missing argument name")
2188 env.control_flow.set_state((), (arg.name, 'source'), 'arg')
2189 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2190 if arg.needs_conversion:
2191 arg.entry = env.declare_var(arg.name, arg.type, arg.pos)
2192 if arg.type.is_pyobject:
2193 arg.entry.init = "0"
2194 arg.entry.init_to_none = 0
2196 arg.entry = self.declare_argument(env, arg)
2198 arg.entry.is_self_arg = arg.is_self_arg
2200 if arg.is_self_arg or arg.is_type_arg or \
2201 (arg.type.is_extension_type and not arg.hdr_type.is_extension_type):
2202 arg.entry.is_declared_generic = 1
2203 self.declare_python_arg(env, self.star_arg)
2204 self.declare_python_arg(env, self.starstar_arg)
2206 def declare_python_arg(self, env, arg):
2208 if env.directives['infer_types'] != False:
2209 type = PyrexTypes.unspecified_type
2211 type = py_object_type
2212 entry = env.declare_var(arg.name, type, arg.pos)
2215 entry.init_to_none = 0
2216 entry.xdecref_cleanup = 1
2218 env.control_flow.set_state((), (arg.name, 'initialized'), True)
2220 def analyse_expressions(self, env):
2221 self.local_scope.directives = env.directives
2222 self.analyse_default_values(env)
2223 if self.needs_assignment_synthesis(env):
2224 # Shouldn't we be doing this at the module level too?
2225 self.synthesize_assignment_node(env)
2227 def needs_assignment_synthesis(self, env, code=None):
2228 # Should enable for module level as well, that will require more testing...
2229 if self.entry.is_anonymous:
2231 if env.is_module_scope:
2233 return env.directives['binding']
2235 return code.globalstate.directives['binding']
2236 return env.is_py_class_scope or env.is_closure_scope
2238 def synthesize_assignment_node(self, env):
2241 while genv.is_py_class_scope or genv.is_c_class_scope:
2242 genv = genv.outer_scope
2244 if genv.is_closure_scope:
2245 rhs = ExprNodes.InnerFunctionNode(
2246 self.pos, pymethdef_cname = self.entry.pymethdef_cname)
2248 rhs = ExprNodes.PyCFunctionNode(
2249 self.pos, pymethdef_cname = self.entry.pymethdef_cname, binding = env.directives['binding'])
2251 if env.is_py_class_scope:
2252 if not self.is_staticmethod and not self.is_classmethod:
2256 for decorator in self.decorators[::-1]:
2257 rhs = ExprNodes.SimpleCallNode(
2259 function = decorator.decorator,
2262 self.assmt = SingleAssignmentNode(self.pos,
2263 lhs = ExprNodes.NameNode(self.pos, name = self.name),
2265 self.assmt.analyse_declarations(env)
2266 self.assmt.analyse_expressions(env)
2268 def generate_function_header(self, code, with_pymethdef, proto_only=0):
2270 sig = self.entry.signature
2271 if sig.has_dummy_arg or self.self_in_stararg:
2272 arg_code_list.append(
2273 "PyObject *%s" % Naming.self_cname)
2274 for arg in self.args:
2275 if not arg.is_generic:
2276 if arg.is_self_arg or arg.is_type_arg:
2277 arg_code_list.append("PyObject *%s" % arg.hdr_cname)
2279 arg_code_list.append(
2280 arg.hdr_type.declaration_code(arg.hdr_cname))
2281 if not self.entry.is_special and sig.method_flags() == [TypeSlots.method_noargs]:
2282 arg_code_list.append("CYTHON_UNUSED PyObject *unused")
2283 if sig.has_generic_args:
2284 arg_code_list.append(
2285 "PyObject *%s, PyObject *%s"
2286 % (Naming.args_cname, Naming.kwds_cname))
2287 arg_code = ", ".join(arg_code_list)
2288 dc = self.return_type.declaration_code(self.entry.func_cname)
2289 mf = " ".join(self.modifiers).upper()
2291 header = "static %s%s(%s)" % (mf, dc, arg_code)
2292 code.putln("%s; /*proto*/" % header)
2295 if (Options.docstrings and self.entry.doc and
2296 not self.entry.scope.is_property_scope and
2297 (not self.entry.is_special or self.entry.wrapperbase_cname)):
2298 docstr = self.entry.doc
2299 if docstr.is_unicode:
2300 docstr = docstr.utf8encode()
2302 'static char %s[] = "%s";' % (
2303 self.entry.doc_cname,
2304 split_string_literal(escape_byte_string(docstr))))
2305 if self.entry.is_special:
2307 "struct wrapperbase %s;" % self.entry.wrapperbase_cname)
2310 "static PyMethodDef %s = " %
2311 self.entry.pymethdef_cname)
2312 code.put_pymethoddef(self.entry, ";", allow_skip=False)
2313 code.putln("%s {" % header)
2315 def generate_argument_declarations(self, env, code):
2316 for arg in self.args:
2317 if arg.is_generic: # or arg.needs_conversion:
2318 if arg.needs_conversion:
2319 code.putln("PyObject *%s = 0;" % arg.hdr_cname)
2320 elif not arg.entry.in_closure:
2321 code.put_var_declaration(arg.entry)
2323 def generate_keyword_list(self, code):
2324 if self.signature_has_generic_args() and \
2325 self.signature_has_nongeneric_args():
2327 "static PyObject **%s[] = {" %
2328 Naming.pykwdlist_cname)
2329 for arg in self.args:
2331 pystring_cname = code.intern_identifier(arg.name)
2332 code.put('&%s,' % pystring_cname)
2335 def generate_argument_parsing_code(self, env, code):
2336 # Generate PyArg_ParseTuple call for generic
2337 # arguments, if any.
2338 if self.entry.signature.has_dummy_arg and not self.self_in_stararg:
2339 # get rid of unused argument warning
2340 code.putln("%s = %s;" % (Naming.self_cname, Naming.self_cname))
2342 old_error_label = code.new_error_label()
2343 our_error_label = code.error_label
2344 end_label = code.new_label("argument_unpacking_done")
2346 has_kwonly_args = self.num_kwonly_args > 0
2347 has_star_or_kw_args = self.star_arg is not None \
2348 or self.starstar_arg is not None or has_kwonly_args
2350 for arg in self.args:
2351 if not arg.type.is_pyobject:
2352 done = arg.type.create_from_py_utility_code(env)
2353 if not done: pass # will fail later
2355 if not self.signature_has_generic_args():
2356 if has_star_or_kw_args:
2357 error(self.pos, "This method cannot have * or keyword arguments")
2358 self.generate_argument_conversion_code(code)
2360 elif not self.signature_has_nongeneric_args():
2361 # func(*args) or func(**kw) or func(*args, **kw)
2362 self.generate_stararg_copy_code(code)
2365 positional_args = []
2367 for arg in self.args:
2368 arg_entry = arg.entry
2371 if not arg.is_self_arg and not arg.is_type_arg:
2373 kw_only_args.append(arg)
2375 positional_args.append(arg)
2377 kw_only_args.append(arg)
2378 elif not arg.is_self_arg and not arg.is_type_arg:
2379 positional_args.append(arg)
2381 self.generate_tuple_and_keyword_parsing_code(
2382 positional_args, kw_only_args, end_label, code)
2384 code.error_label = old_error_label
2385 if code.label_used(our_error_label):
2386 if not code.label_used(end_label):
2387 code.put_goto(end_label)
2388 code.put_label(our_error_label)
2389 if has_star_or_kw_args:
2390 self.generate_arg_decref(self.star_arg, code)
2391 if self.starstar_arg:
2392 if self.starstar_arg.entry.xdecref_cleanup:
2393 code.put_var_xdecref(self.starstar_arg.entry)
2395 code.put_var_decref(self.starstar_arg.entry)
2396 code.putln('__Pyx_AddTraceback("%s");' % self.entry.qualified_name)
2397 # The arguments are put into the closure one after the
2398 # other, so when type errors are found, all references in
2399 # the closure instance must be properly ref-counted to
2400 # facilitate generic closure instance deallocation. In
2401 # the case of an argument type error, it's best to just
2402 # DECREF+clear the already handled references, as this
2403 # frees their references as early as possible.
2404 for arg in self.args:
2405 if arg.type.is_pyobject and arg.entry.in_closure:
2406 code.put_var_xdecref_clear(arg.entry)
2407 if self.needs_closure:
2408 code.put_decref(Naming.cur_scope_cname, self.local_scope.scope_class.type)
2409 code.put_finish_refcount_context()
2410 code.putln("return %s;" % self.error_value())
2411 if code.label_used(end_label):
2412 code.put_label(end_label)
2414 def generate_arg_assignment(self, arg, item, code):
2415 if arg.type.is_pyobject:
2417 item = PyrexTypes.typecast(arg.type, PyrexTypes.py_object_type, item)
2419 code.putln("%s = %s;" % (entry.cname, item))
2420 if entry.in_closure:
2421 code.put_var_incref(entry)
2423 func = arg.type.from_py_function
2425 code.putln("%s = %s(%s); %s" % (
2429 code.error_goto_if(arg.type.error_condition(arg.entry.cname), arg.pos)))
2431 error(arg.pos, "Cannot convert Python object argument to type '%s'" % arg.type)
2433 def generate_arg_xdecref(self, arg, code):
2435 code.put_var_xdecref(arg.entry)
2437 def generate_arg_decref(self, arg, code):
2439 code.put_var_decref(arg.entry)
2441 def generate_stararg_copy_code(self, code):
2442 if not self.star_arg:
2443 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2444 code.putln("if (unlikely(PyTuple_GET_SIZE(%s) > 0)) {" %
2446 code.put('__Pyx_RaiseArgtupleInvalid("%s", 1, 0, 0, PyTuple_GET_SIZE(%s)); return %s;' % (
2447 self.name, Naming.args_cname, self.error_value()))
2450 code.globalstate.use_utility_code(keyword_string_check_utility_code)
2452 if self.starstar_arg:
2454 kwarg_check = "unlikely(%s)" % Naming.kwds_cname
2456 kwarg_check = "%s" % Naming.kwds_cname
2458 kwarg_check = "unlikely(%s) && unlikely(PyDict_Size(%s) > 0)" % (
2459 Naming.kwds_cname, Naming.kwds_cname)
2461 "if (%s && unlikely(!__Pyx_CheckKeywordStrings(%s, \"%s\", %d))) return %s;" % (
2462 kwarg_check, Naming.kwds_cname, self.name,
2463 bool(self.starstar_arg), self.error_value()))
2465 if self.starstar_arg:
2466 code.putln("%s = (%s) ? PyDict_Copy(%s) : PyDict_New();" % (
2467 self.starstar_arg.entry.cname,
2470 code.putln("if (unlikely(!%s)) return %s;" % (
2471 self.starstar_arg.entry.cname, self.error_value()))
2472 self.starstar_arg.entry.xdecref_cleanup = 0
2473 code.put_gotref(self.starstar_arg.entry.cname)
2475 if self.self_in_stararg:
2476 # need to create a new tuple with 'self' inserted as first item
2477 code.put("%s = PyTuple_New(PyTuple_GET_SIZE(%s)+1); if (unlikely(!%s)) " % (
2478 self.star_arg.entry.cname,
2480 self.star_arg.entry.cname))
2481 if self.starstar_arg:
2483 code.put_decref_clear(self.starstar_arg.entry.cname, py_object_type)
2484 code.putln("return %s;" % self.error_value())
2487 code.putln("return %s;" % self.error_value())
2488 code.put_gotref(self.star_arg.entry.cname)
2489 code.put_incref(Naming.self_cname, py_object_type)
2490 code.put_giveref(Naming.self_cname)
2491 code.putln("PyTuple_SET_ITEM(%s, 0, %s);" % (
2492 self.star_arg.entry.cname, Naming.self_cname))
2493 temp = code.funcstate.allocate_temp(PyrexTypes.c_py_ssize_t_type, manage_ref=False)
2494 code.putln("for (%s=0; %s < PyTuple_GET_SIZE(%s); %s++) {" % (
2495 temp, temp, Naming.args_cname, temp))
2496 code.putln("PyObject* item = PyTuple_GET_ITEM(%s, %s);" % (
2497 Naming.args_cname, temp))
2498 code.put_incref("item", py_object_type)
2499 code.put_giveref("item")
2500 code.putln("PyTuple_SET_ITEM(%s, %s+1, item);" % (
2501 self.star_arg.entry.cname, temp))
2503 code.funcstate.release_temp(temp)
2504 self.star_arg.entry.xdecref_cleanup = 0
2506 code.put_incref(Naming.args_cname, py_object_type)
2507 code.putln("%s = %s;" % (
2508 self.star_arg.entry.cname,
2510 self.star_arg.entry.xdecref_cleanup = 0
2512 def generate_tuple_and_keyword_parsing_code(self, positional_args,
2513 kw_only_args, success_label, code):
2514 argtuple_error_label = code.new_label("argtuple_error")
2516 min_positional_args = self.num_required_args - self.num_required_kw_args
2517 if len(self.args) > 0 and (self.args[0].is_self_arg or self.args[0].is_type_arg):
2518 min_positional_args -= 1
2519 max_positional_args = len(positional_args)
2520 has_fixed_positional_count = not self.star_arg and \
2521 min_positional_args == max_positional_args
2523 code.globalstate.use_utility_code(raise_double_keywords_utility_code)
2524 code.globalstate.use_utility_code(raise_argtuple_invalid_utility_code)
2525 if self.num_required_kw_args:
2526 code.globalstate.use_utility_code(raise_keyword_required_utility_code)
2528 if self.starstar_arg or self.star_arg:
2529 self.generate_stararg_init_code(max_positional_args, code)
2531 # --- optimised code when we receive keyword arguments
2532 if self.num_required_kw_args:
2533 likely_hint = "likely"
2535 likely_hint = "unlikely"
2536 code.putln("if (%s(%s)) {" % (likely_hint, Naming.kwds_cname))
2537 self.generate_keyword_unpacking_code(
2538 min_positional_args, max_positional_args,
2539 has_fixed_positional_count,
2540 positional_args, kw_only_args, argtuple_error_label, code)
2542 # --- optimised code when we do not receive any keyword arguments
2543 if (self.num_required_kw_args and min_positional_args > 0) or min_positional_args == max_positional_args:
2544 # Python raises arg tuple related errors first, so we must
2545 # check the length here
2546 if min_positional_args == max_positional_args and not self.star_arg:
2550 code.putln('} else if (PyTuple_GET_SIZE(%s) %s %d) {' % (
2551 Naming.args_cname, compare, min_positional_args))
2552 code.put_goto(argtuple_error_label)
2554 if self.num_required_kw_args:
2555 # pure error case: keywords required but not passed
2556 if max_positional_args > min_positional_args and not self.star_arg:
2557 code.putln('} else if (PyTuple_GET_SIZE(%s) > %d) {' % (
2558 Naming.args_cname, max_positional_args))
2559 code.put_goto(argtuple_error_label)
2560 code.putln('} else {')
2561 for i, arg in enumerate(kw_only_args):
2563 pystring_cname = code.intern_identifier(arg.name)
2564 # required keyword-only argument missing
2565 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' % (
2568 code.putln(code.error_goto(self.pos))
2571 elif min_positional_args == max_positional_args:
2572 # parse the exact number of positional arguments from the
2574 code.putln('} else {')
2575 for i, arg in enumerate(positional_args):
2576 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2577 self.generate_arg_assignment(arg, item, code)
2578 self.generate_arg_default_assignments(code)
2581 # parse the positional arguments from the variable length
2583 code.putln('} else {')
2584 self.generate_arg_default_assignments(code)
2585 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2587 code.putln('default:')
2588 reversed_args = list(enumerate(positional_args))[::-1]
2589 for i, arg in reversed_args:
2590 if i >= min_positional_args-1:
2591 if min_positional_args > 1:
2592 code.putln('case %2d:' % (i+1)) # pure code beautification
2594 code.put('case %2d: ' % (i+1))
2595 item = "PyTuple_GET_ITEM(%s, %d)" % (Naming.args_cname, i)
2596 self.generate_arg_assignment(arg, item, code)
2597 if min_positional_args == 0:
2598 code.put('case 0: ')
2599 code.putln('break;')
2601 if min_positional_args:
2602 for i in range(min_positional_args-1, -1, -1):
2603 code.putln('case %2d:' % i)
2604 code.put_goto(argtuple_error_label)
2606 code.put('default: ')
2607 code.put_goto(argtuple_error_label)
2612 if code.label_used(argtuple_error_label):
2613 code.put_goto(success_label)
2614 code.put_label(argtuple_error_label)
2615 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, PyTuple_GET_SIZE(%s)); ' % (
2616 self.name, has_fixed_positional_count,
2617 min_positional_args, max_positional_args,
2619 code.putln(code.error_goto(self.pos))
2621 def generate_arg_default_assignments(self, code):
2622 for arg in self.args:
2623 if arg.is_generic and arg.default:
2627 arg.calculate_default_value_code(code)))
2629 def generate_stararg_init_code(self, max_positional_args, code):
2630 if self.starstar_arg:
2631 self.starstar_arg.entry.xdecref_cleanup = 0
2632 code.putln('%s = PyDict_New(); if (unlikely(!%s)) return %s;' % (
2633 self.starstar_arg.entry.cname,
2634 self.starstar_arg.entry.cname,
2635 self.error_value()))
2636 code.put_gotref(self.starstar_arg.entry.cname)
2638 self.star_arg.entry.xdecref_cleanup = 0
2639 code.putln('if (PyTuple_GET_SIZE(%s) > %d) {' % (
2641 max_positional_args))
2642 code.put('%s = PyTuple_GetSlice(%s, %d, PyTuple_GET_SIZE(%s)); ' % (
2643 self.star_arg.entry.cname, Naming.args_cname,
2644 max_positional_args, Naming.args_cname))
2645 code.put_gotref(self.star_arg.entry.cname)
2646 if self.starstar_arg:
2648 code.putln("if (unlikely(!%s)) {" % self.star_arg.entry.cname)
2649 code.put_decref(self.starstar_arg.entry.cname, py_object_type)
2650 code.putln('return %s;' % self.error_value())
2653 code.putln("if (unlikely(!%s)) return %s;" % (
2654 self.star_arg.entry.cname, self.error_value()))
2655 code.putln('} else {')
2656 code.put("%s = %s; " % (self.star_arg.entry.cname, Naming.empty_tuple))
2657 code.put_incref(Naming.empty_tuple, py_object_type)
2660 def generate_keyword_unpacking_code(self, min_positional_args, max_positional_args,
2661 has_fixed_positional_count, positional_args,
2662 kw_only_args, argtuple_error_label, code):
2663 all_args = tuple(positional_args) + tuple(kw_only_args)
2664 max_args = len(all_args)
2666 code.putln("Py_ssize_t kw_args = PyDict_Size(%s);" %
2668 # the 'values' array collects borrowed references to arguments
2669 # before doing any type coercion etc.
2670 code.putln("PyObject* values[%d] = {%s};" % (
2671 max_args, ','.join('0'*max_args)))
2673 # assign borrowed Python default values to the values array,
2674 # so that they can be overwritten by received arguments below
2675 for i, arg in enumerate(all_args):
2676 if arg.default and arg.type.is_pyobject:
2677 default_value = arg.calculate_default_value_code(code)
2678 code.putln('values[%d] = %s;' % (i, arg.type.as_pyobject(default_value)))
2680 # parse the args tuple and check that it's not too long
2681 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2683 code.putln('default:')
2684 for i in range(max_positional_args-1, -1, -1):
2685 code.put('case %2d: ' % (i+1))
2686 code.putln("values[%d] = PyTuple_GET_ITEM(%s, %d);" % (
2687 i, Naming.args_cname, i))
2688 code.putln('case 0: break;')
2689 if not self.star_arg:
2690 code.put('default: ') # more arguments than allowed
2691 code.put_goto(argtuple_error_label)
2694 # now fill up the positional/required arguments with values
2696 if self.num_required_args or max_positional_args > 0:
2697 last_required_arg = -1
2698 for i, arg in enumerate(all_args):
2700 last_required_arg = i
2701 if last_required_arg < max_positional_args:
2702 last_required_arg = max_positional_args-1
2703 num_required_args = self.num_required_args
2704 if max_positional_args > 0:
2705 code.putln('switch (PyTuple_GET_SIZE(%s)) {' % Naming.args_cname)
2706 for i, arg in enumerate(all_args[:last_required_arg+1]):
2707 if max_positional_args > 0 and i <= max_positional_args:
2708 if self.star_arg and i == max_positional_args:
2709 code.putln('default:')
2711 code.putln('case %2d:' % i)
2712 pystring_cname = code.intern_identifier(arg.name)
2715 # handled separately below
2717 code.putln('if (kw_args > 0) {')
2718 code.putln('PyObject* value = PyDict_GetItem(%s, %s);' % (
2719 Naming.kwds_cname, pystring_cname))
2720 code.putln('if (value) { values[%d] = value; kw_args--; }' % i)
2723 num_required_args -= 1
2724 code.putln('values[%d] = PyDict_GetItem(%s, %s);' % (
2725 i, Naming.kwds_cname, pystring_cname))
2726 code.putln('if (likely(values[%d])) kw_args--;' % i);
2727 if i < min_positional_args:
2729 # special case: we know arg 0 is missing
2731 code.put_goto(argtuple_error_label)
2733 # print the correct number of values (args or
2734 # kwargs) that were passed into positional
2735 # arguments up to this point
2736 code.putln('else {')
2737 code.put('__Pyx_RaiseArgtupleInvalid("%s", %d, %d, %d, %d); ' % (
2738 self.name, has_fixed_positional_count,
2739 min_positional_args, max_positional_args, i))
2740 code.putln(code.error_goto(self.pos))
2743 code.putln('else {')
2744 code.put('__Pyx_RaiseKeywordRequired("%s", %s); ' %(
2745 self.name, pystring_cname))
2746 code.putln(code.error_goto(self.pos))
2748 if max_positional_args > 0:
2751 if kw_only_args and not self.starstar_arg:
2752 # unpack optional keyword-only arguments
2753 # checking for interned strings in a dict is faster than iterating
2754 # but it's too likely that we must iterate if we expect **kwargs
2756 for i, arg in enumerate(all_args[max_positional_args:]):
2757 if not arg.kw_only or not arg.default:
2759 optional_args.append((i+max_positional_args, arg))
2761 # this mimics an unrolled loop so that we can "break" out of it
2762 code.putln('while (kw_args > 0) {')
2763 code.putln('PyObject* value;')
2764 for i, arg in optional_args:
2765 pystring_cname = code.intern_identifier(arg.name)
2767 'value = PyDict_GetItem(%s, %s);' % (
2768 Naming.kwds_cname, pystring_cname))
2770 'if (value) { values[%d] = value; if (!(--kw_args)) break; }' % i)
2771 code.putln('break;')
2774 code.putln('if (unlikely(kw_args > 0)) {')
2775 # non-positional/-required kw args left in dict: default args,
2776 # kw-only args, **kwargs or error
2778 # This is sort of a catch-all: except for checking required
2779 # arguments, this will always do the right thing for unpacking
2780 # keyword arguments, so that we can concentrate on optimising
2781 # common cases above.
2782 if max_positional_args == 0:
2785 code.putln("const Py_ssize_t used_pos_args = (PyTuple_GET_SIZE(%s) < %d) ? PyTuple_GET_SIZE(%s) : %d;" % (
2786 Naming.args_cname, max_positional_args,
2787 Naming.args_cname, max_positional_args))
2788 pos_arg_count = "used_pos_args"
2790 pos_arg_count = "PyTuple_GET_SIZE(%s)" % Naming.args_cname
2791 code.globalstate.use_utility_code(parse_keywords_utility_code)
2793 'if (unlikely(__Pyx_ParseOptionalKeywords(%s, %s, %s, values, %s, "%s") < 0)) ' % (
2795 Naming.pykwdlist_cname,
2796 self.starstar_arg and self.starstar_arg.entry.cname or '0',
2799 code.putln(code.error_goto(self.pos))
2802 # convert arg values to their final type and assign them
2803 for i, arg in enumerate(all_args):
2804 if arg.default and not arg.type.is_pyobject:
2805 code.putln("if (values[%d]) {" % i)
2806 self.generate_arg_assignment(arg, "values[%d]" % i, code)
2807 if arg.default and not arg.type.is_pyobject:
2808 code.putln('} else {')
2812 arg.calculate_default_value_code(code)))
2815 def generate_argument_conversion_code(self, code):
2816 # Generate code to convert arguments from signature type to
2817 # declared type, if needed. Also copies signature arguments
2818 # into closure fields.
2819 for arg in self.args:
2820 if arg.needs_conversion:
2821 self.generate_arg_conversion(arg, code)
2822 elif arg.entry.in_closure:
2823 code.putln('%s = %s;' % (arg.entry.cname, arg.hdr_cname))
2824 if arg.type.is_pyobject:
2825 code.put_var_incref(arg.entry)
2827 def generate_arg_conversion(self, arg, code):
2828 # Generate conversion code for one argument.
2829 old_type = arg.hdr_type
2831 if old_type.is_pyobject:
2833 code.putln("if (%s) {" % arg.hdr_cname)
2835 code.putln("assert(%s); {" % arg.hdr_cname)
2836 self.generate_arg_conversion_from_pyobject(arg, code)
2838 elif new_type.is_pyobject:
2839 self.generate_arg_conversion_to_pyobject(arg, code)
2841 if new_type.assignable_from(old_type):
2843 "%s = %s;" % (arg.entry.cname, arg.hdr_cname))
2846 "Cannot convert 1 argument from '%s' to '%s'" %
2847 (old_type, new_type))
2849 def generate_arg_conversion_from_pyobject(self, arg, code):
2851 func = new_type.from_py_function
2852 # copied from CoerceFromPyTypeNode
2854 lhs = arg.entry.cname
2855 rhs = "%s(%s)" % (func, arg.hdr_cname)
2856 if new_type.is_enum:
2857 rhs = PyrexTypes.typecast(new_type, PyrexTypes.c_long_type, rhs)
2858 code.putln("%s = %s; %s" % (
2861 code.error_goto_if(new_type.error_condition(arg.entry.cname), arg.pos)))
2864 "Cannot convert Python object argument to type '%s'"
2867 def generate_arg_conversion_to_pyobject(self, arg, code):
2868 old_type = arg.hdr_type
2869 func = old_type.to_py_function
2871 code.putln("%s = %s(%s); %s" % (
2875 code.error_goto_if_null(arg.entry.cname, arg.pos)))
2876 code.put_var_gotref(arg.entry)
2879 "Cannot convert argument of type '%s' to Python object"
2882 def generate_argument_type_tests(self, code):
2883 # Generate type tests for args whose signature
2884 # type is PyObject * and whose declared type is
2885 # a subtype thereof.
2886 for arg in self.args:
2887 if arg.needs_type_test:
2888 self.generate_arg_type_test(arg, code)
2889 elif not arg.accept_none and arg.type.is_pyobject:
2890 self.generate_arg_none_check(arg, code)
2892 def error_value(self):
2893 return self.entry.signature.error_value
2895 def caller_will_check_exceptions(self):
2898 class OverrideCheckNode(StatNode):
2899 # A Node for dispatching to the def method if it
2908 child_attrs = ['body']
2912 def analyse_expressions(self, env):
2913 self.args = env.arg_entries
2914 if self.py_func.is_module_scope:
2919 self.func_node = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
2920 call_tuple = ExprNodes.TupleNode(self.pos, args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2921 call_node = ExprNodes.SimpleCallNode(self.pos,
2922 function=self.func_node,
2923 args=[ExprNodes.NameNode(self.pos, name=arg.name) for arg in self.args[first_arg:]])
2924 self.body = ReturnStatNode(self.pos, value=call_node)
2925 self.body.analyse_expressions(env)
2927 def generate_execution_code(self, code):
2928 interned_attr_cname = code.intern_identifier(self.py_func.entry.name)
2929 # Check to see if we are an extension type
2930 if self.py_func.is_module_scope:
2931 self_arg = "((PyObject *)%s)" % Naming.module_cname
2933 self_arg = "((PyObject *)%s)" % self.args[0].cname
2934 code.putln("/* Check if called by wrapper */")
2935 code.putln("if (unlikely(%s)) ;" % Naming.skip_dispatch_cname)
2936 code.putln("/* Check if overriden in Python */")
2937 if self.py_func.is_module_scope:
2938 code.putln("else {")
2940 code.putln("else if (unlikely(Py_TYPE(%s)->tp_dictoffset != 0)) {" % self_arg)
2941 func_node_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
2942 self.func_node.set_cname(func_node_temp)
2943 # need to get attribute manually--scope would return cdef method
2944 err = code.error_goto_if_null(func_node_temp, self.pos)
2945 code.putln("%s = PyObject_GetAttr(%s, %s); %s" % (
2946 func_node_temp, self_arg, interned_attr_cname, err))
2947 code.put_gotref(func_node_temp)
2948 is_builtin_function_or_method = "PyCFunction_Check(%s)" % func_node_temp
2949 is_overridden = "(PyCFunction_GET_FUNCTION(%s) != (void *)&%s)" % (
2950 func_node_temp, self.py_func.entry.func_cname)
2951 code.putln("if (!%s || %s) {" % (is_builtin_function_or_method, is_overridden))
2952 self.body.generate_execution_code(code)
2954 code.put_decref_clear(func_node_temp, PyrexTypes.py_object_type)
2955 code.funcstate.release_temp(func_node_temp)
2958 class ClassDefNode(StatNode, BlockNode):
2961 class PyClassDefNode(ClassDefNode):
2962 # A Python class definition.
2964 # name EncodedString Name of the class
2965 # doc string or None
2966 # body StatNode Attribute definition code
2967 # entry Symtab.Entry
2968 # scope PyClassScope
2969 # decorators [DecoratorNode] list of decorators or None
2971 # The following subnodes are constructed internally:
2973 # dict DictNode Class dictionary or Py3 namespace
2974 # classobj ClassNode Class object
2975 # target NameNode Variable to assign class object to
2977 child_attrs = ["body", "dict", "metaclass", "mkw", "bases", "class_result", "target"]
2980 py3_style_class = False # Python3 style class (bases+kwargs)
2982 def __init__(self, pos, name, bases, doc, body, decorators = None,
2983 keyword_args = None, starstar_arg = None):
2984 StatNode.__init__(self, pos)
2988 self.decorators = decorators
2990 if self.doc and Options.docstrings:
2991 doc = embed_position(self.pos, self.doc)
2992 doc_node = ExprNodes.StringNode(pos, value = doc)
2995 if keyword_args or starstar_arg:
2996 self.py3_style_class = True
2998 self.metaclass = None
2999 if keyword_args and not starstar_arg:
3000 for i, item in list(enumerate(keyword_args.key_value_pairs))[::-1]:
3001 if item.key.value == 'metaclass':
3002 if self.metaclass is not None:
3003 error(item.pos, "keyword argument 'metaclass' passed multiple times")
3004 # special case: we already know the metaclass,
3005 # so we don't need to do the "build kwargs,
3006 # find metaclass" dance at runtime
3007 self.metaclass = item.value
3008 del keyword_args.key_value_pairs[i]
3009 if starstar_arg or (keyword_args and keyword_args.key_value_pairs):
3010 self.mkw = ExprNodes.KeywordArgsNode(
3011 pos, keyword_args = keyword_args, starstar_arg = starstar_arg)
3013 self.mkw = ExprNodes.NullNode(pos)
3014 if self.metaclass is None:
3015 self.metaclass = ExprNodes.PyClassMetaclassNode(
3016 pos, mkw = self.mkw, bases = self.bases)
3017 self.dict = ExprNodes.PyClassNamespaceNode(pos, name = name,
3018 doc = doc_node, metaclass = self.metaclass, bases = self.bases,
3020 self.classobj = ExprNodes.Py3ClassNode(pos, name = name,
3021 bases = self.bases, dict = self.dict, doc = doc_node,
3022 metaclass = self.metaclass, mkw = self.mkw)
3024 self.dict = ExprNodes.DictNode(pos, key_value_pairs = [])
3025 self.metaclass = None
3028 self.classobj = ExprNodes.ClassNode(pos, name = name,
3029 bases = bases, dict = self.dict, doc = doc_node)
3030 self.target = ExprNodes.NameNode(pos, name = name)
3032 def as_cclass(self):
3034 Return this node as if it were declared as an extension class
3036 if self.py3_style_class:
3037 error(self.classobj.pos, "Python3 style class could not be represented as C class")
3039 bases = self.classobj.bases.args
3041 base_class_name = None
3042 base_class_module = None
3043 elif len(bases) == 1:
3046 from ExprNodes import AttributeNode, NameNode
3047 while isinstance(base, AttributeNode):
3048 path.insert(0, base.attribute)
3050 if isinstance(base, NameNode):
3051 path.insert(0, base.name)
3052 base_class_name = path[-1]
3054 base_class_module = u'.'.join(path[:-1])
3056 base_class_module = None
3058 error(self.classobj.bases.args.pos, "Invalid base class")
3060 error(self.classobj.bases.args.pos, "C class may only have one base class")
3063 return CClassDefNode(self.pos,
3064 visibility = 'private',
3066 class_name = self.name,
3067 base_class_module = base_class_module,
3068 base_class_name = base_class_name,
3069 decorators = self.decorators,
3074 def create_scope(self, env):
3076 while genv.is_py_class_scope or genv.is_c_class_scope:
3077 genv = genv.outer_scope
3078 cenv = self.scope = PyClassScope(name = self.name, outer_scope = genv)
3081 def analyse_declarations(self, env):
3082 class_result = self.classobj
3084 from ExprNodes import SimpleCallNode
3085 for decorator in self.decorators[::-1]:
3086 class_result = SimpleCallNode(
3088 function = decorator.decorator,
3089 args = [class_result])
3090 self.class_result = class_result
3091 self.class_result.analyse_declarations(env)
3092 self.target.analyse_target_declaration(env)
3093 cenv = self.create_scope(env)
3094 cenv.directives = env.directives
3095 cenv.class_obj_cname = self.target.entry.cname
3096 self.body.analyse_declarations(cenv)
3098 def analyse_expressions(self, env):
3099 if self.py3_style_class:
3100 self.bases.analyse_expressions(env)
3101 self.metaclass.analyse_expressions(env)
3102 self.mkw.analyse_expressions(env)
3103 self.dict.analyse_expressions(env)
3104 self.class_result.analyse_expressions(env)
3105 genv = env.global_scope()
3107 self.body.analyse_expressions(cenv)
3108 self.target.analyse_target_expression(env, self.classobj)
3110 def generate_function_definitions(self, env, code):
3111 self.generate_lambda_definitions(self.scope, code)
3112 self.body.generate_function_definitions(self.scope, code)
3114 def generate_execution_code(self, code):
3115 code.pyclass_stack.append(self)
3117 if self.py3_style_class:
3118 self.bases.generate_evaluation_code(code)
3119 self.mkw.generate_evaluation_code(code)
3120 self.metaclass.generate_evaluation_code(code)
3121 self.dict.generate_evaluation_code(code)
3122 cenv.namespace_cname = cenv.class_obj_cname = self.dict.result()
3123 self.body.generate_execution_code(code)
3124 self.class_result.generate_evaluation_code(code)
3125 cenv.namespace_cname = cenv.class_obj_cname = self.classobj.result()
3126 self.target.generate_assignment_code(self.class_result, code)
3127 self.dict.generate_disposal_code(code)
3128 self.dict.free_temps(code)
3129 if self.py3_style_class:
3130 self.mkw.generate_disposal_code(code)
3131 self.mkw.free_temps(code)
3132 self.metaclass.generate_disposal_code(code)
3133 self.metaclass.free_temps(code)
3134 self.bases.generate_disposal_code(code)
3135 self.bases.free_temps(code)
3136 code.pyclass_stack.pop()
3138 class CClassDefNode(ClassDefNode):
3139 # An extension type definition.
3141 # visibility 'private' or 'public' or 'extern'
3142 # typedef_flag boolean
3144 # module_name string or None For import of extern type objects
3145 # class_name string Unqualified name of class
3146 # as_name string or None Name to declare as in this scope
3147 # base_class_module string or None Module containing the base class
3148 # base_class_name string or None Name of the base class
3149 # objstruct_name string or None Specified C name of object struct
3150 # typeobj_name string or None Specified C name of type object
3151 # in_pxd boolean Is in a .pxd file
3152 # decorators [DecoratorNode] list of decorators or None
3153 # doc string or None
3154 # body StatNode or None
3155 # entry Symtab.Entry
3156 # base_type PyExtensionType or None
3157 # buffer_defaults_node DictNode or None Declares defaults for a buffer
3158 # buffer_defaults_pos
3160 child_attrs = ["body"]
3161 buffer_defaults_node = None
3162 buffer_defaults_pos = None
3163 typedef_flag = False
3165 objstruct_name = None
3169 def analyse_declarations(self, env):
3170 #print "CClassDefNode.analyse_declarations:", self.class_name
3171 #print "...visibility =", self.visibility
3172 #print "...module_name =", self.module_name
3175 if self.buffer_defaults_node:
3176 buffer_defaults = Buffer.analyse_buffer_options(self.buffer_defaults_pos,
3177 env, [], self.buffer_defaults_node,
3178 need_complete=False)
3180 buffer_defaults = None
3182 if env.in_cinclude and not self.objstruct_name:
3183 error(self.pos, "Object struct name specification required for "
3184 "C class defined in 'extern from' block")
3187 "Decorators not allowed on cdef classes (used on type '%s')" % self.class_name)
3188 self.base_type = None
3189 # Now that module imports are cached, we need to
3190 # import the modules for extern classes.
3191 if self.module_name:
3193 for module in env.cimported_modules:
3194 if module.name == self.module_name:
3195 self.module = module
3196 if self.module is None:
3197 self.module = ModuleScope(self.module_name, None, env.context)
3198 self.module.has_extern_class = 1
3199 env.add_imported_module(self.module)
3201 if self.base_class_name:
3202 if self.base_class_module:
3203 base_class_scope = env.find_module(self.base_class_module, self.pos)
3205 base_class_scope = env
3206 if self.base_class_name == 'object':
3207 # extension classes are special and don't need to inherit from object
3208 if base_class_scope is None or base_class_scope.lookup('object') is None:
3209 self.base_class_name = None
3210 self.base_class_module = None
3211 base_class_scope = None
3212 if base_class_scope:
3213 base_class_entry = base_class_scope.find(self.base_class_name, self.pos)
3214 if base_class_entry:
3215 if not base_class_entry.is_type:
3216 error(self.pos, "'%s' is not a type name" % self.base_class_name)
3217 elif not base_class_entry.type.is_extension_type and \
3218 not (base_class_entry.type.is_builtin_type and \
3219 base_class_entry.type.objstruct_cname):
3220 error(self.pos, "'%s' is not an extension type" % self.base_class_name)
3221 elif not base_class_entry.type.is_complete():
3222 error(self.pos, "Base class '%s' of type '%s' is incomplete" % (
3223 self.base_class_name, self.class_name))
3224 elif base_class_entry.type.scope and base_class_entry.type.scope.directives and \
3225 base_class_entry.type.scope.directives['final']:
3226 error(self.pos, "Base class '%s' of type '%s' is final" % (
3227 self.base_class_name, self.class_name))
3228 elif base_class_entry.type.is_builtin_type and \
3229 base_class_entry.type.name in ('tuple', 'str', 'bytes'):
3230 error(self.pos, "inheritance from PyVarObject types like '%s' is not currently supported"
3231 % base_class_entry.type.name)
3233 self.base_type = base_class_entry.type
3234 has_body = self.body is not None
3235 if self.module_name and self.visibility != 'extern':
3236 module_path = self.module_name.split(".")
3237 home_scope = env.find_imported_module(module_path, self.pos)
3243 if self.visibility == 'extern':
3244 if self.module_name == '__builtin__' and self.class_name in Builtin.builtin_types:
3245 warning(self.pos, "%s already a builtin Cython type" % self.class_name, 1)
3247 self.entry = home_scope.declare_c_class(
3248 name = self.class_name,
3250 defining = has_body and self.in_pxd,
3251 implementing = has_body and not self.in_pxd,
3252 module_name = self.module_name,
3253 base_type = self.base_type,
3254 objstruct_cname = self.objstruct_name,
3255 typeobj_cname = self.typeobj_name,
3256 visibility = self.visibility,
3257 typedef_flag = self.typedef_flag,
3259 buffer_defaults = buffer_defaults)
3260 if home_scope is not env and self.visibility == 'extern':
3261 env.add_imported_entry(self.class_name, self.entry, self.pos)
3262 self.scope = scope = self.entry.type.scope
3263 if scope is not None:
3264 scope.directives = env.directives
3266 if self.doc and Options.docstrings:
3267 scope.doc = embed_position(self.pos, self.doc)
3270 self.body.analyse_declarations(scope)
3274 scope.implemented = 1
3275 env.allocate_vtable_names(self.entry)
3277 def analyse_expressions(self, env):
3279 scope = self.entry.type.scope
3280 self.body.analyse_expressions(scope)
3282 def generate_function_definitions(self, env, code):
3284 self.generate_lambda_definitions(self.scope, code)
3285 self.body.generate_function_definitions(self.scope, code)
3287 def generate_execution_code(self, code):
3288 # This is needed to generate evaluation code for
3289 # default values of method arguments.
3291 self.body.generate_execution_code(code)
3293 def annotate(self, code):
3295 self.body.annotate(code)
3298 class PropertyNode(StatNode):
3299 # Definition of a property in an extension type.
3302 # doc EncodedString or None Doc string
3305 child_attrs = ["body"]
3307 def analyse_declarations(self, env):
3308 entry = env.declare_property(self.name, self.doc, self.pos)
3310 entry.scope.directives = env.directives
3311 self.body.analyse_declarations(entry.scope)
3313 def analyse_expressions(self, env):
3314 self.body.analyse_expressions(env)
3316 def generate_function_definitions(self, env, code):
3317 self.body.generate_function_definitions(env, code)
3319 def generate_execution_code(self, code):
3322 def annotate(self, code):
3323 self.body.annotate(code)
3326 class GlobalNode(StatNode):
3327 # Global variable declaration.
3333 def analyse_declarations(self, env):
3334 for name in self.names:
3335 env.declare_global(name, self.pos)
3337 def analyse_expressions(self, env):
3340 def generate_execution_code(self, code):
3344 class ExprStatNode(StatNode):
3345 # Expression used as a statement.
3349 child_attrs = ["expr"]
3351 def analyse_declarations(self, env):
3353 if isinstance(self.expr, ExprNodes.GeneralCallNode):
3354 func = self.expr.function.as_cython_attribute()
3355 if func == u'declare':
3356 args, kwds = self.expr.explicit_args_kwds()
3358 error(self.expr.pos, "Variable names must be specified.")
3359 for var, type_node in kwds.key_value_pairs:
3360 type = type_node.analyse_as_type(env)
3362 error(type_node.pos, "Unknown type")
3364 env.declare_var(var.value, type, var.pos, is_cdef = True)
3365 self.__class__ = PassStatNode
3367 def analyse_expressions(self, env):
3368 self.expr.analyse_expressions(env)
3370 def nogil_check(self, env):
3371 if self.expr.type.is_pyobject and self.expr.is_temp:
3374 gil_message = "Discarding owned Python object"
3376 def generate_execution_code(self, code):
3377 self.expr.generate_evaluation_code(code)
3378 if not self.expr.is_temp and self.expr.result():
3379 code.putln("%s;" % self.expr.result())
3380 self.expr.generate_disposal_code(code)
3381 self.expr.free_temps(code)
3383 def generate_function_definitions(self, env, code):
3384 self.expr.generate_function_definitions(env, code)
3386 def annotate(self, code):
3387 self.expr.annotate(code)
3390 class AssignmentNode(StatNode):
3391 # Abstract base class for assignment nodes.
3393 # The analyse_expressions and generate_execution_code
3394 # phases of assignments are split into two sub-phases
3395 # each, to enable all the right hand sides of a
3396 # parallel assignment to be evaluated before assigning
3397 # to any of the left hand sides.
3399 def analyse_expressions(self, env):
3400 self.analyse_types(env)
3402 # def analyse_expressions(self, env):
3403 # self.analyse_expressions_1(env)
3404 # self.analyse_expressions_2(env)
3406 def generate_execution_code(self, code):
3407 self.generate_rhs_evaluation_code(code)
3408 self.generate_assignment_code(code)
3411 class SingleAssignmentNode(AssignmentNode):
3412 # The simplest case:
3416 # lhs ExprNode Left hand side
3417 # rhs ExprNode Right hand side
3418 # first bool Is this guaranteed the first assignment to lhs?
3420 child_attrs = ["lhs", "rhs"]
3422 declaration_only = False
3424 def analyse_declarations(self, env):
3427 # handle declarations of the form x = cython.foo()
3428 if isinstance(self.rhs, ExprNodes.CallNode):
3429 func_name = self.rhs.function.as_cython_attribute()
3431 args, kwds = self.rhs.explicit_args_kwds()
3433 if func_name in ['declare', 'typedef']:
3434 if len(args) > 2 or kwds is not None:
3435 error(self.rhs.pos, "Can only declare one type at a time.")
3437 type = args[0].analyse_as_type(env)
3439 error(args[0].pos, "Unknown type")
3442 if func_name == 'declare':
3443 if isinstance(lhs, ExprNodes.NameNode):
3444 vars = [(lhs.name, lhs.pos)]
3445 elif isinstance(lhs, ExprNodes.TupleNode):
3446 vars = [(var.name, var.pos) for var in lhs.args]
3448 error(lhs.pos, "Invalid declaration")
3450 for var, pos in vars:
3451 env.declare_var(var, type, pos, is_cdef = True)
3456 self.declaration_only = True
3458 self.declaration_only = True
3459 if not isinstance(lhs, ExprNodes.NameNode):
3460 error(lhs.pos, "Invalid declaration.")
3461 env.declare_typedef(lhs.name, type, self.pos, visibility='private')
3463 elif func_name in ['struct', 'union']:
3464 self.declaration_only = True
3465 if len(args) > 0 or kwds is None:
3466 error(self.rhs.pos, "Struct or union members must be given by name.")
3469 for member, type_node in kwds.key_value_pairs:
3470 type = type_node.analyse_as_type(env)
3472 error(type_node.pos, "Unknown type")
3474 members.append((member.value, type, member.pos))
3475 if len(members) < len(kwds.key_value_pairs):
3477 if not isinstance(self.lhs, ExprNodes.NameNode):
3478 error(self.lhs.pos, "Invalid declaration.")
3479 name = self.lhs.name
3480 scope = StructOrUnionScope(name)
3481 env.declare_struct_or_union(name, func_name, scope, False, self.rhs.pos)
3482 for member, type, pos in members:
3483 scope.declare_var(member, type, pos)
3485 if self.declaration_only:
3488 self.lhs.analyse_target_declaration(env)
3490 def analyse_types(self, env, use_temp = 0):
3491 self.rhs.analyse_types(env)
3492 self.lhs.analyse_target_types(env)
3493 self.lhs.gil_assignment_check(env)
3494 self.rhs = self.rhs.coerce_to(self.lhs.type, env)
3496 self.rhs = self.rhs.coerce_to_temp(env)
3498 def generate_rhs_evaluation_code(self, code):
3499 self.rhs.generate_evaluation_code(code)
3501 def generate_assignment_code(self, code):
3502 self.lhs.generate_assignment_code(self.rhs, code)
3504 def generate_function_definitions(self, env, code):
3505 self.rhs.generate_function_definitions(env, code)
3507 def annotate(self, code):
3508 self.lhs.annotate(code)
3509 self.rhs.annotate(code)
3512 class CascadedAssignmentNode(AssignmentNode):
3513 # An assignment with multiple left hand sides:
3517 # lhs_list [ExprNode] Left hand sides
3518 # rhs ExprNode Right hand sides
3522 # coerced_rhs_list [ExprNode] RHS coerced to type of each LHS
3524 child_attrs = ["lhs_list", "rhs", "coerced_rhs_list"]
3525 coerced_rhs_list = None
3527 def analyse_declarations(self, env):
3528 for lhs in self.lhs_list:
3529 lhs.analyse_target_declaration(env)
3531 def analyse_types(self, env, use_temp = 0):
3532 self.rhs.analyse_types(env)
3533 if not self.rhs.is_simple():
3535 self.rhs = self.rhs.coerce_to_temp(env)
3537 self.rhs = self.rhs.coerce_to_simple(env)
3538 from ExprNodes import CloneNode
3539 self.coerced_rhs_list = []
3540 for lhs in self.lhs_list:
3541 lhs.analyse_target_types(env)
3542 lhs.gil_assignment_check(env)
3543 rhs = CloneNode(self.rhs)
3544 rhs = rhs.coerce_to(lhs.type, env)
3545 self.coerced_rhs_list.append(rhs)
3547 def generate_rhs_evaluation_code(self, code):
3548 self.rhs.generate_evaluation_code(code)
3550 def generate_assignment_code(self, code):
3551 for i in range(len(self.lhs_list)):
3552 lhs = self.lhs_list[i]
3553 rhs = self.coerced_rhs_list[i]
3554 rhs.generate_evaluation_code(code)
3555 lhs.generate_assignment_code(rhs, code)
3556 # Assignment has disposed of the cloned RHS
3557 self.rhs.generate_disposal_code(code)
3558 self.rhs.free_temps(code)
3560 def generate_function_definitions(self, env, code):
3561 self.rhs.generate_function_definitions(env, code)
3563 def annotate(self, code):
3564 for i in range(len(self.lhs_list)):
3565 lhs = self.lhs_list[i].annotate(code)
3566 rhs = self.coerced_rhs_list[i].annotate(code)
3567 self.rhs.annotate(code)
3570 class ParallelAssignmentNode(AssignmentNode):
3571 # A combined packing/unpacking assignment:
3575 # This has been rearranged by the parser into
3577 # a = d ; b = e ; c = f
3579 # but we must evaluate all the right hand sides
3580 # before assigning to any of the left hand sides.
3582 # stats [AssignmentNode] The constituent assignments
3584 child_attrs = ["stats"]
3586 def analyse_declarations(self, env):
3587 for stat in self.stats:
3588 stat.analyse_declarations(env)
3590 def analyse_expressions(self, env):
3591 for stat in self.stats:
3592 stat.analyse_types(env, use_temp = 1)
3594 # def analyse_expressions(self, env):
3595 # for stat in self.stats:
3596 # stat.analyse_expressions_1(env, use_temp = 1)
3597 # for stat in self.stats:
3598 # stat.analyse_expressions_2(env)
3600 def generate_execution_code(self, code):
3601 for stat in self.stats:
3602 stat.generate_rhs_evaluation_code(code)
3603 for stat in self.stats:
3604 stat.generate_assignment_code(code)
3606 def generate_function_definitions(self, env, code):
3607 for stat in self.stats:
3608 stat.generate_function_definitions(env, code)
3610 def annotate(self, code):
3611 for stat in self.stats:
3615 class InPlaceAssignmentNode(AssignmentNode):
3616 # An in place arithmetic operand:
3622 # lhs ExprNode Left hand side
3623 # rhs ExprNode Right hand side
3624 # op char one of "+-*/%^&|"
3625 # dup (ExprNode) copy of lhs used for operation (auto-generated)
3627 # This code is a bit tricky because in order to obey Python
3628 # semantics the sub-expressions (e.g. indices) of the lhs must
3629 # not be evaluated twice. So we must re-use the values calculated
3630 # in evaluation phase for the assignment phase as well.
3631 # Fortunately, the type of the lhs node is fairly constrained
3632 # (it must be a NameNode, AttributeNode, or IndexNode).
3634 child_attrs = ["lhs", "rhs"]
3636 def analyse_declarations(self, env):
3637 self.lhs.analyse_target_declaration(env)
3639 def analyse_types(self, env):
3640 self.rhs.analyse_types(env)
3641 self.lhs.analyse_target_types(env)
3643 def generate_execution_code(self, code):
3645 self.rhs.generate_evaluation_code(code)
3646 self.lhs.generate_subexpr_evaluation_code(code)
3647 c_op = self.operator
3651 error(self.pos, "No C inplace power operator")
3652 if isinstance(self.lhs, ExprNodes.IndexNode) and self.lhs.is_buffer_access:
3653 if self.lhs.type.is_pyobject:
3654 error(self.pos, "In-place operators not allowed on object buffers in this release.")
3655 if c_op in ('/', '%') and self.lhs.type.is_int and not code.directives['cdivision']:
3656 error(self.pos, "In-place non-c divide operators not allowed on int buffers.")
3657 self.lhs.generate_buffer_setitem_code(self.rhs, code, c_op)
3660 # TODO: make sure overload is declared
3661 code.putln("%s %s= %s;" % (self.lhs.result(), c_op, self.rhs.result()))
3662 self.lhs.generate_subexpr_disposal_code(code)
3663 self.lhs.free_subexpr_temps(code)
3664 self.rhs.generate_disposal_code(code)
3665 self.rhs.free_temps(code)
3667 def annotate(self, code):
3668 self.lhs.annotate(code)
3669 self.rhs.annotate(code)
3671 def create_binop_node(self):
3673 return ExprNodes.binop_node(self.pos, self.operator, self.lhs, self.rhs)
3676 class PrintStatNode(StatNode):
3679 # arg_tuple TupleNode
3680 # stream ExprNode or None (stdout)
3681 # append_newline boolean
3683 child_attrs = ["arg_tuple", "stream"]
3685 def analyse_expressions(self, env):
3687 self.stream.analyse_expressions(env)
3688 self.stream = self.stream.coerce_to_pyobject(env)
3689 self.arg_tuple.analyse_expressions(env)
3690 self.arg_tuple = self.arg_tuple.coerce_to_pyobject(env)
3691 env.use_utility_code(printing_utility_code)
3692 if len(self.arg_tuple.args) == 1 and self.append_newline:
3693 env.use_utility_code(printing_one_utility_code)
3695 nogil_check = Node.gil_error
3696 gil_message = "Python print statement"
3698 def generate_execution_code(self, code):
3700 self.stream.generate_evaluation_code(code)
3701 stream_result = self.stream.py_result()
3704 if len(self.arg_tuple.args) == 1 and self.append_newline:
3705 arg = self.arg_tuple.args[0]
3706 arg.generate_evaluation_code(code)
3709 "if (__Pyx_PrintOne(%s, %s) < 0) %s" % (
3712 code.error_goto(self.pos)))
3713 arg.generate_disposal_code(code)
3714 arg.free_temps(code)
3716 self.arg_tuple.generate_evaluation_code(code)
3718 "if (__Pyx_Print(%s, %s, %d) < 0) %s" % (
3720 self.arg_tuple.py_result(),
3721 self.append_newline,
3722 code.error_goto(self.pos)))
3723 self.arg_tuple.generate_disposal_code(code)
3724 self.arg_tuple.free_temps(code)
3727 self.stream.generate_disposal_code(code)
3728 self.stream.free_temps(code)
3730 def generate_function_definitions(self, env, code):
3732 self.stream.generate_function_definitions(env, code)
3733 self.arg_tuple.generate_function_definitions(env, code)
3735 def annotate(self, code):
3737 self.stream.annotate(code)
3738 self.arg_tuple.annotate(code)
3741 class ExecStatNode(StatNode):
3746 child_attrs = ["args"]
3748 def analyse_expressions(self, env):
3749 for i, arg in enumerate(self.args):
3750 arg.analyse_expressions(env)
3751 arg = arg.coerce_to_pyobject(env)
3753 env.use_utility_code(Builtin.pyexec_utility_code)
3755 nogil_check = Node.gil_error
3756 gil_message = "Python exec statement"
3758 def generate_execution_code(self, code):
3760 for arg in self.args:
3761 arg.generate_evaluation_code(code)
3762 args.append( arg.py_result() )
3763 args = tuple(args + ['0', '0'][:3-len(args)])
3764 temp_result = code.funcstate.allocate_temp(PyrexTypes.py_object_type, manage_ref=True)
3765 code.putln("%s = __Pyx_PyRun(%s, %s, %s);" % (
3766 (temp_result,) + args))
3767 for arg in self.args:
3768 arg.generate_disposal_code(code)
3769 arg.free_temps(code)
3771 code.error_goto_if_null(temp_result, self.pos))
3772 code.put_gotref(temp_result)
3773 code.put_decref_clear(temp_result, py_object_type)
3774 code.funcstate.release_temp(temp_result)
3776 def annotate(self, code):
3777 for arg in self.args:
3781 class DelStatNode(StatNode):
3786 child_attrs = ["args"]
3788 def analyse_declarations(self, env):
3789 for arg in self.args:
3790 arg.analyse_target_declaration(env)
3792 def analyse_expressions(self, env):
3793 for arg in self.args:
3794 arg.analyse_target_expression(env, None)
3795 if arg.type.is_pyobject:
3797 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3799 elif arg.type.is_cpp_class:
3800 error(arg.pos, "Deletion of non-heap C++ object")
3802 error(arg.pos, "Deletion of non-Python, non-C++ object")
3803 #arg.release_target_temp(env)
3805 def nogil_check(self, env):
3806 for arg in self.args:
3807 if arg.type.is_pyobject:
3810 gil_message = "Deleting Python object"
3812 def generate_execution_code(self, code):
3813 for arg in self.args:
3814 if arg.type.is_pyobject:
3815 arg.generate_deletion_code(code)
3816 elif arg.type.is_ptr and arg.type.base_type.is_cpp_class:
3817 arg.generate_result_code(code)
3818 code.putln("delete %s;" % arg.result())
3819 # else error reported earlier
3821 def annotate(self, code):
3822 for arg in self.args:
3826 class PassStatNode(StatNode):
3831 def analyse_expressions(self, env):
3834 def generate_execution_code(self, code):
3838 class BreakStatNode(StatNode):
3842 def analyse_expressions(self, env):
3845 def generate_execution_code(self, code):
3846 if not code.break_label:
3847 error(self.pos, "break statement not inside loop")
3849 code.put_goto(code.break_label)
3852 class ContinueStatNode(StatNode):
3856 def analyse_expressions(self, env):
3859 def generate_execution_code(self, code):
3860 if code.funcstate.in_try_finally:
3861 error(self.pos, "continue statement inside try of try...finally")
3862 elif not code.continue_label:
3863 error(self.pos, "continue statement not inside loop")
3865 code.put_goto(code.continue_label)
3868 class ReturnStatNode(StatNode):
3871 # value ExprNode or None
3872 # return_type PyrexType
3874 child_attrs = ["value"]
3876 def analyse_expressions(self, env):
3877 return_type = env.return_type
3878 self.return_type = return_type
3880 error(self.pos, "Return not inside a function body")
3883 self.value.analyse_types(env)
3884 if return_type.is_void or return_type.is_returncode:
3885 error(self.value.pos,
3886 "Return with value in void function")
3888 self.value = self.value.coerce_to(env.return_type, env)
3890 if (not return_type.is_void
3891 and not return_type.is_pyobject
3892 and not return_type.is_returncode):
3893 error(self.pos, "Return value required")
3895 def nogil_check(self, env):
3896 if self.return_type.is_pyobject:
3899 gil_message = "Returning Python object"
3901 def generate_execution_code(self, code):
3902 code.mark_pos(self.pos)
3903 if not self.return_type:
3904 # error reported earlier
3906 if self.return_type.is_pyobject:
3907 code.put_xdecref(Naming.retval_cname,
3910 self.value.generate_evaluation_code(code)
3911 self.value.make_owned_reference(code)
3914 Naming.retval_cname,
3915 self.value.result_as(self.return_type)))
3916 self.value.generate_post_assignment_code(code)
3917 self.value.free_temps(code)
3919 if self.return_type.is_pyobject:
3920 code.put_init_to_py_none(Naming.retval_cname, self.return_type)
3921 elif self.return_type.is_returncode:
3924 Naming.retval_cname,
3925 self.return_type.default_value))
3926 for cname, type in code.funcstate.temps_holding_reference():
3927 code.put_decref_clear(cname, type)
3928 code.put_goto(code.return_label)
3930 def generate_function_definitions(self, env, code):
3931 if self.value is not None:
3932 self.value.generate_function_definitions(env, code)
3934 def annotate(self, code):
3936 self.value.annotate(code)
3939 class RaiseStatNode(StatNode):
3942 # exc_type ExprNode or None
3943 # exc_value ExprNode or None
3944 # exc_tb ExprNode or None
3946 child_attrs = ["exc_type", "exc_value", "exc_tb"]
3948 def analyse_expressions(self, env):
3950 self.exc_type.analyse_types(env)
3951 self.exc_type = self.exc_type.coerce_to_pyobject(env)
3953 self.exc_value.analyse_types(env)
3954 self.exc_value = self.exc_value.coerce_to_pyobject(env)
3956 self.exc_tb.analyse_types(env)
3957 self.exc_tb = self.exc_tb.coerce_to_pyobject(env)
3958 env.use_utility_code(raise_utility_code)
3960 nogil_check = Node.gil_error
3961 gil_message = "Raising exception"
3963 def generate_execution_code(self, code):
3965 self.exc_type.generate_evaluation_code(code)
3966 type_code = self.exc_type.py_result()
3970 self.exc_value.generate_evaluation_code(code)
3971 value_code = self.exc_value.py_result()
3975 self.exc_tb.generate_evaluation_code(code)
3976 tb_code = self.exc_tb.py_result()
3980 "__Pyx_Raise(%s, %s, %s);" % (
3984 for obj in (self.exc_type, self.exc_value, self.exc_tb):
3986 obj.generate_disposal_code(code)
3987 obj.free_temps(code)
3989 code.error_goto(self.pos))
3991 def generate_function_definitions(self, env, code):
3992 if self.exc_type is not None:
3993 self.exc_type.generate_function_definitions(env, code)
3994 if self.exc_value is not None:
3995 self.exc_value.generate_function_definitions(env, code)
3996 if self.exc_tb is not None:
3997 self.exc_tb.generate_function_definitions(env, code)
3999 def annotate(self, code):
4001 self.exc_type.annotate(code)
4003 self.exc_value.annotate(code)
4005 self.exc_tb.annotate(code)
4008 class ReraiseStatNode(StatNode):
4012 def analyse_expressions(self, env):
4013 env.use_utility_code(restore_exception_utility_code)
4015 nogil_check = Node.gil_error
4016 gil_message = "Raising exception"
4018 def generate_execution_code(self, code):
4019 vars = code.funcstate.exc_vars
4021 for varname in vars:
4022 code.put_giveref(varname)
4023 code.putln("__Pyx_ErrRestore(%s, %s, %s);" % tuple(vars))
4024 for varname in vars:
4025 code.put("%s = 0; " % varname)
4027 code.putln(code.error_goto(self.pos))
4029 error(self.pos, "Reraise not inside except clause")
4032 class AssertStatNode(StatNode):
4036 # value ExprNode or None
4038 child_attrs = ["cond", "value"]
4040 def analyse_expressions(self, env):
4041 self.cond = self.cond.analyse_boolean_expression(env)
4043 self.value.analyse_types(env)
4044 self.value = self.value.coerce_to_pyobject(env)
4046 nogil_check = Node.gil_error
4047 gil_message = "Raising exception"
4049 def generate_execution_code(self, code):
4050 code.putln("#ifndef CYTHON_WITHOUT_ASSERTIONS")
4051 self.cond.generate_evaluation_code(code)
4053 "if (unlikely(!%s)) {" %
4056 self.value.generate_evaluation_code(code)
4058 "PyErr_SetObject(PyExc_AssertionError, %s);" %
4059 self.value.py_result())
4060 self.value.generate_disposal_code(code)
4061 self.value.free_temps(code)
4064 "PyErr_SetNone(PyExc_AssertionError);")
4066 code.error_goto(self.pos))
4069 self.cond.generate_disposal_code(code)
4070 self.cond.free_temps(code)
4071 code.putln("#endif")
4073 def generate_function_definitions(self, env, code):
4074 self.cond.generate_function_definitions(env, code)
4075 if self.value is not None:
4076 self.value.generate_function_definitions(env, code)
4078 def annotate(self, code):
4079 self.cond.annotate(code)
4081 self.value.annotate(code)
4084 class IfStatNode(StatNode):
4087 # if_clauses [IfClauseNode]
4088 # else_clause StatNode or None
4090 child_attrs = ["if_clauses", "else_clause"]
4092 def analyse_control_flow(self, env):
4093 env.start_branching(self.pos)
4094 for if_clause in self.if_clauses:
4095 if_clause.analyse_control_flow(env)
4096 env.next_branch(if_clause.end_pos())
4097 if self.else_clause:
4098 self.else_clause.analyse_control_flow(env)
4099 env.finish_branching(self.end_pos())
4101 def analyse_declarations(self, env):
4102 for if_clause in self.if_clauses:
4103 if_clause.analyse_declarations(env)
4104 if self.else_clause:
4105 self.else_clause.analyse_declarations(env)
4107 def analyse_expressions(self, env):
4108 for if_clause in self.if_clauses:
4109 if_clause.analyse_expressions(env)
4110 if self.else_clause:
4111 self.else_clause.analyse_expressions(env)
4113 def generate_execution_code(self, code):
4114 code.mark_pos(self.pos)
4115 end_label = code.new_label()
4116 for if_clause in self.if_clauses:
4117 if_clause.generate_execution_code(code, end_label)
4118 if self.else_clause:
4119 code.putln("/*else*/ {")
4120 self.else_clause.generate_execution_code(code)
4122 code.put_label(end_label)
4124 def generate_function_definitions(self, env, code):
4125 for clause in self.if_clauses:
4126 clause.generate_function_definitions(env, code)
4127 if self.else_clause is not None:
4128 self.else_clause.generate_function_definitions(env, code)
4130 def annotate(self, code):
4131 for if_clause in self.if_clauses:
4132 if_clause.annotate(code)
4133 if self.else_clause:
4134 self.else_clause.annotate(code)
4137 class IfClauseNode(Node):
4138 # if or elif clause in an if statement
4140 # condition ExprNode
4143 child_attrs = ["condition", "body"]
4145 def analyse_control_flow(self, env):
4146 self.body.analyse_control_flow(env)
4148 def analyse_declarations(self, env):
4149 self.body.analyse_declarations(env)
4151 def analyse_expressions(self, env):
4153 self.condition.analyse_temp_boolean_expression(env)
4154 self.body.analyse_expressions(env)
4156 def get_constant_condition_result(self):
4157 if self.condition.has_constant_result():
4158 return bool(self.condition.constant_result)
4162 def generate_execution_code(self, code, end_label):
4163 self.condition.generate_evaluation_code(code)
4166 self.condition.result())
4167 self.condition.generate_disposal_code(code)
4168 self.condition.free_temps(code)
4169 self.body.generate_execution_code(code)
4170 code.put_goto(end_label)
4173 def generate_function_definitions(self, env, code):
4174 self.condition.generate_function_definitions(env, code)
4175 self.body.generate_function_definitions(env, code)
4177 def annotate(self, code):
4178 self.condition.annotate(code)
4179 self.body.annotate(code)
4182 class SwitchCaseNode(StatNode):
4183 # Generated in the optimization of an if-elif-else node
4185 # conditions [ExprNode]
4188 child_attrs = ['conditions', 'body']
4190 def generate_execution_code(self, code):
4191 for cond in self.conditions:
4192 code.mark_pos(cond.pos)
4193 cond.generate_evaluation_code(code)
4194 code.putln("case %s:" % cond.result())
4195 self.body.generate_execution_code(code)
4196 code.putln("break;")
4198 def generate_function_definitions(self, env, code):
4199 for cond in self.conditions:
4200 cond.generate_function_definitions(env, code)
4201 self.body.generate_function_definitions(env, code)
4203 def annotate(self, code):
4204 for cond in self.conditions:
4206 self.body.annotate(code)
4208 class SwitchStatNode(StatNode):
4209 # Generated in the optimization of an if-elif-else node
4212 # cases [SwitchCaseNode]
4213 # else_clause StatNode or None
4215 child_attrs = ['test', 'cases', 'else_clause']
4217 def generate_execution_code(self, code):
4218 self.test.generate_evaluation_code(code)
4219 code.putln("switch (%s) {" % self.test.result())
4220 for case in self.cases:
4221 case.generate_execution_code(code)
4222 if self.else_clause is not None:
4223 code.putln("default:")
4224 self.else_clause.generate_execution_code(code)
4225 code.putln("break;")
4228 def generate_function_definitions(self, env, code):
4229 self.test.generate_function_definitions(env, code)
4230 for case in self.cases:
4231 case.generate_function_definitions(env, code)
4232 if self.else_clause is not None:
4233 self.else_clause.generate_function_definitions(env, code)
4235 def annotate(self, code):
4236 self.test.annotate(code)
4237 for case in self.cases:
4239 if self.else_clause is not None:
4240 self.else_clause.annotate(code)
4242 class LoopNode(object):
4244 def analyse_control_flow(self, env):
4245 env.start_branching(self.pos)
4246 self.body.analyse_control_flow(env)
4247 env.next_branch(self.body.end_pos())
4248 if self.else_clause:
4249 self.else_clause.analyse_control_flow(env)
4250 env.finish_branching(self.end_pos())
4253 class WhileStatNode(LoopNode, StatNode):
4256 # condition ExprNode
4258 # else_clause StatNode
4260 child_attrs = ["condition", "body", "else_clause"]
4262 def analyse_declarations(self, env):
4263 self.body.analyse_declarations(env)
4264 if self.else_clause:
4265 self.else_clause.analyse_declarations(env)
4267 def analyse_expressions(self, env):
4269 self.condition.analyse_temp_boolean_expression(env)
4270 self.body.analyse_expressions(env)
4271 if self.else_clause:
4272 self.else_clause.analyse_expressions(env)
4274 def generate_execution_code(self, code):
4275 old_loop_labels = code.new_loop_labels()
4278 self.condition.generate_evaluation_code(code)
4279 self.condition.generate_disposal_code(code)
4282 self.condition.result())
4283 self.condition.free_temps(code)
4284 self.body.generate_execution_code(code)
4285 code.put_label(code.continue_label)
4287 break_label = code.break_label
4288 code.set_loop_labels(old_loop_labels)
4289 if self.else_clause:
4290 code.putln("/*else*/ {")
4291 self.else_clause.generate_execution_code(code)
4293 code.put_label(break_label)
4295 def generate_function_definitions(self, env, code):
4296 self.condition.generate_function_definitions(env, code)
4297 self.body.generate_function_definitions(env, code)
4298 if self.else_clause is not None:
4299 self.else_clause.generate_function_definitions(env, code)
4301 def annotate(self, code):
4302 self.condition.annotate(code)
4303 self.body.annotate(code)
4304 if self.else_clause:
4305 self.else_clause.annotate(code)
4308 def ForStatNode(pos, **kw):
4309 if 'iterator' in kw:
4310 return ForInStatNode(pos, **kw)
4312 return ForFromStatNode(pos, **kw)
4314 class ForInStatNode(LoopNode, StatNode):
4318 # iterator IteratorNode
4320 # else_clause StatNode
4321 # item NextNode used internally
4323 child_attrs = ["target", "iterator", "body", "else_clause"]
4326 def analyse_declarations(self, env):
4327 self.target.analyse_target_declaration(env)
4328 self.body.analyse_declarations(env)
4329 if self.else_clause:
4330 self.else_clause.analyse_declarations(env)
4332 def analyse_expressions(self, env):
4334 self.target.analyse_target_types(env)
4335 self.iterator.analyse_expressions(env)
4336 self.item = ExprNodes.NextNode(self.iterator, env)
4337 self.item = self.item.coerce_to(self.target.type, env)
4338 self.body.analyse_expressions(env)
4339 if self.else_clause:
4340 self.else_clause.analyse_expressions(env)
4342 def generate_execution_code(self, code):
4343 old_loop_labels = code.new_loop_labels()
4344 self.iterator.allocate_counter_temp(code)
4345 self.iterator.generate_evaluation_code(code)
4348 self.item.generate_evaluation_code(code)
4349 self.target.generate_assignment_code(self.item, code)
4350 self.body.generate_execution_code(code)
4351 code.put_label(code.continue_label)
4354 break_label = code.break_label
4355 code.set_loop_labels(old_loop_labels)
4357 if self.else_clause:
4358 # in nested loops, the 'else' block can contain a
4359 # 'continue' statement for the outer loop, but we may need
4360 # to generate cleanup code before taking that path, so we
4362 orig_continue_label = code.continue_label
4363 code.continue_label = code.new_label('outer_continue')
4365 code.putln("/*else*/ {")
4366 self.else_clause.generate_execution_code(code)
4369 if code.label_used(code.continue_label):
4370 code.put_goto(break_label)
4371 code.put_label(code.continue_label)
4372 self.iterator.generate_disposal_code(code)
4373 code.put_goto(orig_continue_label)
4374 code.set_loop_labels(old_loop_labels)
4376 if code.label_used(break_label):
4377 code.put_label(break_label)
4378 self.iterator.release_counter_temp(code)
4379 self.iterator.generate_disposal_code(code)
4380 self.iterator.free_temps(code)
4382 def generate_function_definitions(self, env, code):
4383 self.target.generate_function_definitions(env, code)
4384 self.iterator.generate_function_definitions(env, code)
4385 self.body.generate_function_definitions(env, code)
4386 if self.else_clause is not None:
4387 self.else_clause.generate_function_definitions(env, code)
4389 def annotate(self, code):
4390 self.target.annotate(code)
4391 self.iterator.annotate(code)
4392 self.body.annotate(code)
4393 if self.else_clause:
4394 self.else_clause.annotate(code)
4395 self.item.annotate(code)
4398 class ForFromStatNode(LoopNode, StatNode):
4399 # for name from expr rel name rel expr
4406 # step ExprNode or None
4408 # else_clause StatNode or None
4414 # loopvar_node ExprNode (usually a NameNode or temp node)
4415 # py_loopvar_node PyTempNode or None
4416 child_attrs = ["target", "bound1", "bound2", "step", "body", "else_clause"]
4418 is_py_target = False
4420 py_loopvar_node = None
4423 gil_message = "For-loop using object bounds or target"
4425 def nogil_check(self, env):
4426 for x in (self.target, self.bound1, self.bound2):
4427 if x.type.is_pyobject:
4430 def analyse_declarations(self, env):
4431 self.target.analyse_target_declaration(env)
4432 self.body.analyse_declarations(env)
4433 if self.else_clause:
4434 self.else_clause.analyse_declarations(env)
4436 def analyse_expressions(self, env):
4438 self.target.analyse_target_types(env)
4439 self.bound1.analyse_types(env)
4440 self.bound2.analyse_types(env)
4441 if self.step is not None:
4442 if isinstance(self.step, ExprNodes.UnaryMinusNode):
4443 warning(self.step.pos, "Probable infinite loop in for-from-by statment. Consider switching the directions of the relations.", 2)
4444 self.step.analyse_types(env)
4446 target_type = self.target.type
4447 if self.target.type.is_numeric:
4448 loop_type = self.target.type
4450 loop_type = PyrexTypes.c_int_type
4451 if not self.bound1.type.is_pyobject:
4452 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound1.type)
4453 if not self.bound2.type.is_pyobject:
4454 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.bound2.type)
4455 if self.step is not None and not self.step.type.is_pyobject:
4456 loop_type = PyrexTypes.widest_numeric_type(loop_type, self.step.type)
4457 self.bound1 = self.bound1.coerce_to(loop_type, env)
4458 self.bound2 = self.bound2.coerce_to(loop_type, env)
4459 if not self.bound2.is_literal:
4460 self.bound2 = self.bound2.coerce_to_temp(env)
4461 if self.step is not None:
4462 self.step = self.step.coerce_to(loop_type, env)
4463 if not self.step.is_literal:
4464 self.step = self.step.coerce_to_temp(env)
4466 target_type = self.target.type
4467 if not (target_type.is_pyobject or target_type.is_numeric):
4468 error(self.target.pos,
4469 "for-from loop variable must be c numeric type or Python object")
4470 if target_type.is_numeric:
4471 self.is_py_target = False
4472 if isinstance(self.target, ExprNodes.IndexNode) and self.target.is_buffer_access:
4473 raise error(self.pos, "Buffer indexing not allowed as for loop target.")
4474 self.loopvar_node = self.target
4475 self.py_loopvar_node = None
4477 self.is_py_target = True
4478 c_loopvar_node = ExprNodes.TempNode(self.pos, loop_type, env)
4479 self.loopvar_node = c_loopvar_node
4480 self.py_loopvar_node = \
4481 ExprNodes.CloneNode(c_loopvar_node).coerce_to_pyobject(env)
4482 self.body.analyse_expressions(env)
4483 if self.else_clause:
4484 self.else_clause.analyse_expressions(env)
4486 def generate_execution_code(self, code):
4487 old_loop_labels = code.new_loop_labels()
4488 from_range = self.from_range
4489 self.bound1.generate_evaluation_code(code)
4490 self.bound2.generate_evaluation_code(code)
4491 offset, incop = self.relation_table[self.relation1]
4492 if self.step is not None:
4493 self.step.generate_evaluation_code(code)
4494 step = self.step.result()
4495 incop = "%s=%s" % (incop[0], step)
4497 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4498 self.loopvar_node.allocate(code)
4499 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4500 self.py_loopvar_node.allocate(code)
4502 loopvar_name = code.funcstate.allocate_temp(self.target.type, False)
4504 loopvar_name = self.loopvar_node.result()
4506 "for (%s = %s%s; %s %s %s; %s%s) {" % (
4508 self.bound1.result(), offset,
4509 loopvar_name, self.relation2, self.bound2.result(),
4510 loopvar_name, incop))
4511 if self.py_loopvar_node:
4512 self.py_loopvar_node.generate_evaluation_code(code)
4513 self.target.generate_assignment_code(self.py_loopvar_node, code)
4515 code.putln("%s = %s;" % (
4516 self.target.result(), loopvar_name))
4517 self.body.generate_execution_code(code)
4518 code.put_label(code.continue_label)
4519 if self.py_loopvar_node:
4520 # This mess is to make for..from loops with python targets behave
4521 # exactly like those with C targets with regards to re-assignment
4522 # of the loop variable.
4524 if self.target.entry.is_pyglobal:
4525 # We know target is a NameNode, this is the only ugly case.
4526 target_node = ExprNodes.PyTempNode(self.target.pos, None)
4527 target_node.allocate(code)
4528 interned_cname = code.intern_identifier(self.target.entry.name)
4529 code.globalstate.use_utility_code(ExprNodes.get_name_interned_utility_code)
4530 code.putln("%s = __Pyx_GetName(%s, %s); %s" % (
4531 target_node.result(),
4532 Naming.module_cname,
4534 code.error_goto_if_null(target_node.result(), self.target.pos)))
4535 code.put_gotref(target_node.result())
4537 target_node = self.target
4538 from_py_node = ExprNodes.CoerceFromPyTypeNode(self.loopvar_node.type, target_node, None)
4539 from_py_node.temp_code = loopvar_name
4540 from_py_node.generate_result_code(code)
4541 if self.target.entry.is_pyglobal:
4542 code.put_decref(target_node.result(), target_node.type)
4543 target_node.release(code)
4545 if self.py_loopvar_node:
4546 # This is potentially wasteful, but we don't want the semantics to
4547 # depend on whether or not the loop is a python type.
4548 self.py_loopvar_node.generate_evaluation_code(code)
4549 self.target.generate_assignment_code(self.py_loopvar_node, code)
4551 code.funcstate.release_temp(loopvar_name)
4552 break_label = code.break_label
4553 code.set_loop_labels(old_loop_labels)
4554 if self.else_clause:
4555 code.putln("/*else*/ {")
4556 self.else_clause.generate_execution_code(code)
4558 code.put_label(break_label)
4559 self.bound1.generate_disposal_code(code)
4560 self.bound1.free_temps(code)
4561 self.bound2.generate_disposal_code(code)
4562 self.bound2.free_temps(code)
4563 if isinstance(self.loopvar_node, ExprNodes.TempNode):
4564 self.loopvar_node.release(code)
4565 if isinstance(self.py_loopvar_node, ExprNodes.TempNode):
4566 self.py_loopvar_node.release(code)
4567 if self.step is not None:
4568 self.step.generate_disposal_code(code)
4569 self.step.free_temps(code)
4572 # {relop : (initial offset, increment op)}
4579 def generate_function_definitions(self, env, code):
4580 self.target.generate_function_definitions(env, code)
4581 self.bound1.generate_function_definitions(env, code)
4582 self.bound2.generate_function_definitions(env, code)
4583 if self.step is not None:
4584 self.step.generate_function_definitions(env, code)
4585 self.body.generate_function_definitions(env, code)
4586 if self.else_clause is not None:
4587 self.else_clause.generate_function_definitions(env, code)
4589 def annotate(self, code):
4590 self.target.annotate(code)
4591 self.bound1.annotate(code)
4592 self.bound2.annotate(code)
4594 self.step.annotate(code)
4595 self.body.annotate(code)
4596 if self.else_clause:
4597 self.else_clause.annotate(code)
4600 class WithStatNode(StatNode):
4602 Represents a Python with statement.
4604 This is only used at parse tree level; and is not present in
4605 analysis or generation phases.
4607 # manager The with statement manager object
4608 # target Node (lhs expression)
4610 child_attrs = ["manager", "target", "body"]
4612 class TryExceptStatNode(StatNode):
4613 # try .. except statement
4616 # except_clauses [ExceptClauseNode]
4617 # else_clause StatNode or None
4619 child_attrs = ["body", "except_clauses", "else_clause"]
4621 def analyse_control_flow(self, env):
4622 env.start_branching(self.pos)
4623 self.body.analyse_control_flow(env)
4624 successful_try = env.control_flow # grab this for later
4625 env.next_branch(self.body.end_pos())
4626 env.finish_branching(self.body.end_pos())
4628 env.start_branching(self.except_clauses[0].pos)
4629 for except_clause in self.except_clauses:
4630 except_clause.analyse_control_flow(env)
4631 env.next_branch(except_clause.end_pos())
4633 # the else cause it executed only when the try clause finishes
4634 env.control_flow.incoming = successful_try
4635 if self.else_clause:
4636 self.else_clause.analyse_control_flow(env)
4637 env.finish_branching(self.end_pos())
4639 def analyse_declarations(self, env):
4640 self.body.analyse_declarations(env)
4641 for except_clause in self.except_clauses:
4642 except_clause.analyse_declarations(env)
4643 if self.else_clause:
4644 self.else_clause.analyse_declarations(env)
4645 env.use_utility_code(reset_exception_utility_code)
4647 def analyse_expressions(self, env):
4648 self.body.analyse_expressions(env)
4649 default_clause_seen = 0
4650 for except_clause in self.except_clauses:
4651 except_clause.analyse_expressions(env)
4652 if default_clause_seen:
4653 error(except_clause.pos, "default 'except:' must be last")
4654 if not except_clause.pattern:
4655 default_clause_seen = 1
4656 self.has_default_clause = default_clause_seen
4657 if self.else_clause:
4658 self.else_clause.analyse_expressions(env)
4660 nogil_check = Node.gil_error
4661 gil_message = "Try-except statement"
4663 def generate_execution_code(self, code):
4664 old_return_label = code.return_label
4665 old_break_label = code.break_label
4666 old_continue_label = code.continue_label
4667 old_error_label = code.new_error_label()
4668 our_error_label = code.error_label
4669 except_end_label = code.new_label('exception_handled')
4670 except_error_label = code.new_label('except_error')
4671 except_return_label = code.new_label('except_return')
4672 try_return_label = code.new_label('try_return')
4673 try_break_label = code.new_label('try_break')
4674 try_continue_label = code.new_label('try_continue')
4675 try_end_label = code.new_label('try_end')
4678 code.putln("PyObject %s;" %
4679 ', '.join(['*%s' % var for var in Naming.exc_save_vars]))
4680 code.putln("__Pyx_ExceptionSave(%s);" %
4681 ', '.join(['&%s' % var for var in Naming.exc_save_vars]))
4682 for var in Naming.exc_save_vars:
4683 code.put_xgotref(var)
4686 code.return_label = try_return_label
4687 code.break_label = try_break_label
4688 code.continue_label = try_continue_label
4689 self.body.generate_execution_code(code)
4692 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4693 code.error_label = except_error_label
4694 code.return_label = except_return_label
4695 if self.else_clause:
4698 self.else_clause.generate_execution_code(code)
4701 for var in Naming.exc_save_vars:
4702 code.put_xdecref_clear(var, py_object_type)
4703 code.put_goto(try_end_label)
4704 if code.label_used(try_return_label):
4705 code.put_label(try_return_label)
4706 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4707 code.putln("__Pyx_ExceptionReset(%s);" %
4708 ', '.join(Naming.exc_save_vars))
4709 code.put_goto(old_return_label)
4710 code.put_label(our_error_label)
4711 for temp_name, type in temps_to_clean_up:
4712 code.put_xdecref_clear(temp_name, type)
4713 for except_clause in self.except_clauses:
4714 except_clause.generate_handling_code(code, except_end_label)
4716 error_label_used = code.label_used(except_error_label)
4717 if error_label_used or not self.has_default_clause:
4718 if error_label_used:
4719 code.put_label(except_error_label)
4720 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4721 code.putln("__Pyx_ExceptionReset(%s);" %
4722 ', '.join(Naming.exc_save_vars))
4723 code.put_goto(old_error_label)
4725 for exit_label, old_label in zip(
4726 [try_break_label, try_continue_label, except_return_label],
4727 [old_break_label, old_continue_label, old_return_label]):
4729 if code.label_used(exit_label):
4730 code.put_label(exit_label)
4731 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4732 code.putln("__Pyx_ExceptionReset(%s);" %
4733 ', '.join(Naming.exc_save_vars))
4734 code.put_goto(old_label)
4736 if code.label_used(except_end_label):
4737 code.put_label(except_end_label)
4738 for var in Naming.exc_save_vars: code.put_xgiveref(var)
4739 code.putln("__Pyx_ExceptionReset(%s);" %
4740 ', '.join(Naming.exc_save_vars))
4741 code.put_label(try_end_label)
4744 code.return_label = old_return_label
4745 code.break_label = old_break_label
4746 code.continue_label = old_continue_label
4747 code.error_label = old_error_label
4749 def generate_function_definitions(self, env, code):
4750 self.body.generate_function_definitions(env, code)
4751 for except_clause in self.except_clauses:
4752 except_clause.generate_function_definitions(env, code)
4753 if self.else_clause is not None:
4754 self.else_clause.generate_function_definitions(env, code)
4756 def annotate(self, code):
4757 self.body.annotate(code)
4758 for except_node in self.except_clauses:
4759 except_node.annotate(code)
4760 if self.else_clause:
4761 self.else_clause.annotate(code)
4764 class ExceptClauseNode(Node):
4765 # Part of try ... except statement.
4767 # pattern [ExprNode]
4768 # target ExprNode or None
4770 # excinfo_target NameNode or None optional target for exception info
4771 # match_flag string result of exception match
4772 # exc_value ExcValueNode used internally
4773 # function_name string qualified name of enclosing function
4774 # exc_vars (string * 3) local exception variables
4776 # excinfo_target is never set by the parser, but can be set by a transform
4777 # in order to extract more extensive information about the exception as a
4778 # sys.exc_info()-style tuple into a target variable
4780 child_attrs = ["pattern", "target", "body", "exc_value", "excinfo_target"]
4783 excinfo_target = None
4785 def analyse_declarations(self, env):
4787 self.target.analyse_target_declaration(env)
4788 if self.excinfo_target is not None:
4789 self.excinfo_target.analyse_target_declaration(env)
4790 self.body.analyse_declarations(env)
4792 def analyse_expressions(self, env):
4794 genv = env.global_scope()
4795 self.function_name = env.qualified_name
4797 # normalise/unpack self.pattern into a list
4798 for i, pattern in enumerate(self.pattern):
4799 pattern.analyse_expressions(env)
4800 self.pattern[i] = pattern.coerce_to_pyobject(env)
4803 self.exc_value = ExprNodes.ExcValueNode(self.pos, env)
4804 self.target.analyse_target_expression(env, self.exc_value)
4805 if self.excinfo_target is not None:
4807 self.excinfo_tuple = ExprNodes.TupleNode(pos=self.pos, args=[
4808 ExprNodes.ExcValueNode(pos=self.pos, env=env) for x in range(3)])
4809 self.excinfo_tuple.analyse_expressions(env)
4810 self.excinfo_target.analyse_target_expression(env, self.excinfo_tuple)
4812 self.body.analyse_expressions(env)
4814 def generate_handling_code(self, code, end_label):
4815 code.mark_pos(self.pos)
4818 for pattern in self.pattern:
4819 pattern.generate_evaluation_code(code)
4820 exc_tests.append("PyErr_ExceptionMatches(%s)" % pattern.py_result())
4822 match_flag = code.funcstate.allocate_temp(PyrexTypes.c_int_type, False)
4824 "%s = %s;" % (match_flag, ' || '.join(exc_tests)))
4825 for pattern in self.pattern:
4826 pattern.generate_disposal_code(code)
4827 pattern.free_temps(code)
4831 code.funcstate.release_temp(match_flag)
4833 code.putln("/*except:*/ {")
4835 if not getattr(self.body, 'stats', True) and \
4836 self.excinfo_target is None and self.target is None:
4837 # most simple case: no exception variable, empty body (pass)
4838 # => reset the exception state, done
4839 code.putln("PyErr_Restore(0,0,0);")
4840 code.put_goto(end_label)
4844 exc_vars = [code.funcstate.allocate_temp(py_object_type,
4847 code.putln('__Pyx_AddTraceback("%s");' % self.function_name)
4848 # We always have to fetch the exception value even if
4849 # there is no target, because this also normalises the
4850 # exception and stores it in the thread state.
4851 code.globalstate.use_utility_code(get_exception_utility_code)
4852 exc_args = "&%s, &%s, &%s" % tuple(exc_vars)
4853 code.putln("if (__Pyx_GetException(%s) < 0) %s" % (exc_args,
4854 code.error_goto(self.pos)))
4858 self.exc_value.set_var(exc_vars[1])
4859 self.exc_value.generate_evaluation_code(code)
4860 self.target.generate_assignment_code(self.exc_value, code)
4861 if self.excinfo_target is not None:
4862 for tempvar, node in zip(exc_vars, self.excinfo_tuple.args):
4863 node.set_var(tempvar)
4864 self.excinfo_tuple.generate_evaluation_code(code)
4865 self.excinfo_target.generate_assignment_code(self.excinfo_tuple, code)
4867 old_break_label, old_continue_label = code.break_label, code.continue_label
4868 code.break_label = code.new_label('except_break')
4869 code.continue_label = code.new_label('except_continue')
4871 old_exc_vars = code.funcstate.exc_vars
4872 code.funcstate.exc_vars = exc_vars
4873 self.body.generate_execution_code(code)
4874 code.funcstate.exc_vars = old_exc_vars
4875 for var in exc_vars:
4876 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4877 code.put_goto(end_label)
4879 if code.label_used(code.break_label):
4880 code.put_label(code.break_label)
4881 for var in exc_vars:
4882 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4883 code.put_goto(old_break_label)
4884 code.break_label = old_break_label
4886 if code.label_used(code.continue_label):
4887 code.put_label(code.continue_label)
4888 for var in exc_vars:
4889 code.putln("__Pyx_DECREF(%s); %s = 0;" % (var, var))
4890 code.put_goto(old_continue_label)
4891 code.continue_label = old_continue_label
4893 for temp in exc_vars:
4894 code.funcstate.release_temp(temp)
4899 def generate_function_definitions(self, env, code):
4900 if self.target is not None:
4901 self.target.generate_function_definitions(env, code)
4902 self.body.generate_function_definitions(env, code)
4904 def annotate(self, code):
4906 for pattern in self.pattern:
4907 pattern.annotate(code)
4909 self.target.annotate(code)
4910 self.body.annotate(code)
4913 class TryFinallyStatNode(StatNode):
4914 # try ... finally statement
4917 # finally_clause StatNode
4919 # The plan is that we funnel all continue, break
4920 # return and error gotos into the beginning of the
4921 # finally block, setting a variable to remember which
4922 # one we're doing. At the end of the finally block, we
4923 # switch on the variable to figure out where to go.
4924 # In addition, if we're doing an error, we save the
4925 # exception on entry to the finally block and restore
4928 child_attrs = ["body", "finally_clause"]
4930 preserve_exception = 1
4932 disallow_continue_in_try_finally = 0
4933 # There doesn't seem to be any point in disallowing
4934 # continue in the try block, since we have no problem
4937 def create_analysed(pos, env, body, finally_clause):
4938 node = TryFinallyStatNode(pos, body=body, finally_clause=finally_clause)
4940 create_analysed = staticmethod(create_analysed)
4942 def analyse_control_flow(self, env):
4943 env.start_branching(self.pos)
4944 self.body.analyse_control_flow(env)
4945 env.next_branch(self.body.end_pos())
4946 env.finish_branching(self.body.end_pos())
4947 self.finally_clause.analyse_control_flow(env)
4949 def analyse_declarations(self, env):
4950 self.body.analyse_declarations(env)
4951 self.finally_clause.analyse_declarations(env)
4953 def analyse_expressions(self, env):
4954 self.body.analyse_expressions(env)
4955 self.finally_clause.analyse_expressions(env)
4957 nogil_check = Node.gil_error
4958 gil_message = "Try-finally statement"
4960 def generate_execution_code(self, code):
4961 old_error_label = code.error_label
4962 old_labels = code.all_new_labels()
4963 new_labels = code.get_all_labels()
4964 new_error_label = code.error_label
4965 catch_label = code.new_label()
4968 if self.disallow_continue_in_try_finally:
4969 was_in_try_finally = code.funcstate.in_try_finally
4970 code.funcstate.in_try_finally = 1
4971 self.body.generate_execution_code(code)
4972 if self.disallow_continue_in_try_finally:
4973 code.funcstate.in_try_finally = was_in_try_finally
4976 temps_to_clean_up = code.funcstate.all_free_managed_temps()
4977 code.mark_pos(self.finally_clause.pos)
4981 error_label_used = 0
4982 for i, new_label in enumerate(new_labels):
4983 if new_label in code.labels_used:
4984 cases_used.append(i)
4985 if new_label == new_error_label:
4986 error_label_used = 1
4987 error_label_case = i
4991 if error_label_used and self.preserve_exception:
4993 "PyObject *%s, *%s, *%s;" % Naming.exc_vars)
4995 "int %s;" % Naming.exc_lineno_name)
4996 exc_var_init_zero = ''.join(["%s = 0; " % var for var in Naming.exc_vars])
4997 exc_var_init_zero += '%s = 0;' % Naming.exc_lineno_name
4998 code.putln(exc_var_init_zero)
5000 exc_var_init_zero = None
5001 code.use_label(catch_label)
5003 "__pyx_why = 0; goto %s;" % catch_label)
5004 for i in cases_used:
5005 new_label = new_labels[i]
5006 #if new_label and new_label != "<try>":
5007 if new_label == new_error_label and self.preserve_exception:
5008 self.put_error_catcher(code,
5009 new_error_label, i+1, catch_label, temps_to_clean_up)
5011 code.put('%s: ' % new_label)
5012 if exc_var_init_zero:
5013 code.putln(exc_var_init_zero)
5014 code.putln("__pyx_why = %s; goto %s;" % (
5017 code.put_label(catch_label)
5018 code.set_all_labels(old_labels)
5019 if error_label_used:
5020 code.new_error_label()
5021 finally_error_label = code.error_label
5022 self.finally_clause.generate_execution_code(code)
5023 if error_label_used:
5024 if finally_error_label in code.labels_used and self.preserve_exception:
5025 over_label = code.new_label()
5026 code.put_goto(over_label);
5027 code.put_label(finally_error_label)
5028 code.putln("if (__pyx_why == %d) {" % (error_label_case + 1))
5029 for var in Naming.exc_vars:
5030 code.putln("Py_XDECREF(%s);" % var)
5032 code.put_goto(old_error_label)
5033 code.put_label(over_label)
5034 code.error_label = old_error_label
5037 "switch (__pyx_why) {")
5038 for i in cases_used:
5039 old_label = old_labels[i]
5040 if old_label == old_error_label and self.preserve_exception:
5041 self.put_error_uncatcher(code, i+1, old_error_label)
5043 code.use_label(old_label)
5045 "case %s: goto %s;" % (
5053 def generate_function_definitions(self, env, code):
5054 self.body.generate_function_definitions(env, code)
5055 self.finally_clause.generate_function_definitions(env, code)
5057 def put_error_catcher(self, code, error_label, i, catch_label, temps_to_clean_up):
5058 code.globalstate.use_utility_code(restore_exception_utility_code)
5065 for temp_name, type in temps_to_clean_up:
5066 code.put_xdecref_clear(temp_name, type)
5068 "__Pyx_ErrFetch(&%s, &%s, &%s);" %
5072 Naming.exc_lineno_name, Naming.lineno_cname))
5073 code.put_goto(catch_label)
5076 def put_error_uncatcher(self, code, i, error_label):
5077 code.globalstate.use_utility_code(restore_exception_utility_code)
5082 "__Pyx_ErrRestore(%s, %s, %s);" %
5086 Naming.lineno_cname, Naming.exc_lineno_name))
5087 for var in Naming.exc_vars:
5091 code.put_goto(error_label)
5095 def annotate(self, code):
5096 self.body.annotate(code)
5097 self.finally_clause.annotate(code)
5100 class GILStatNode(TryFinallyStatNode):
5101 # 'with gil' or 'with nogil' statement
5103 # state string 'gil' or 'nogil'
5107 preserve_exception = 0
5109 def __init__(self, pos, state, body):
5111 TryFinallyStatNode.__init__(self, pos,
5113 finally_clause = GILExitNode(pos, state = state))
5115 def analyse_expressions(self, env):
5116 env.use_utility_code(force_init_threads_utility_code)
5117 was_nogil = env.nogil
5119 TryFinallyStatNode.analyse_expressions(self, env)
5120 env.nogil = was_nogil
5124 def generate_execution_code(self, code):
5125 code.mark_pos(self.pos)
5127 if self.state == 'gil':
5128 code.putln("#ifdef WITH_THREAD")
5129 code.putln("PyGILState_STATE _save = PyGILState_Ensure();")
5130 code.putln("#endif")
5132 code.putln("#ifdef WITH_THREAD")
5133 code.putln("PyThreadState *_save;")
5134 code.putln("#endif")
5135 code.putln("Py_UNBLOCK_THREADS")
5136 TryFinallyStatNode.generate_execution_code(self, code)
5140 class GILExitNode(StatNode):
5141 # Used as the 'finally' block in a GILStatNode
5143 # state string 'gil' or 'nogil'
5147 def analyse_expressions(self, env):
5150 def generate_execution_code(self, code):
5151 if self.state == 'gil':
5152 code.putln("#ifdef WITH_THREAD")
5153 code.putln("PyGILState_Release(_save);")
5154 code.putln("#endif")
5156 code.putln("Py_BLOCK_THREADS")
5159 class CImportStatNode(StatNode):
5162 # module_name string Qualified name of module being imported
5163 # as_name string or None Name specified in "as" clause, if any
5167 def analyse_declarations(self, env):
5168 if not env.is_module_scope:
5169 error(self.pos, "cimport only allowed at module level")
5171 module_scope = env.find_module(self.module_name, self.pos)
5172 if "." in self.module_name:
5173 names = [EncodedString(name) for name in self.module_name.split(".")]
5175 top_module_scope = env.context.find_submodule(top_name)
5176 module_scope = top_module_scope
5177 for name in names[1:]:
5178 submodule_scope = module_scope.find_submodule(name)
5179 module_scope.declare_module(name, submodule_scope, self.pos)
5180 module_scope = submodule_scope
5182 env.declare_module(self.as_name, module_scope, self.pos)
5184 env.declare_module(top_name, top_module_scope, self.pos)
5186 name = self.as_name or self.module_name
5187 env.declare_module(name, module_scope, self.pos)
5189 def analyse_expressions(self, env):
5192 def generate_execution_code(self, code):
5196 class FromCImportStatNode(StatNode):
5197 # from ... cimport statement
5199 # module_name string Qualified name of module
5200 # imported_names [(pos, name, as_name, kind)] Names to be imported
5204 def analyse_declarations(self, env):
5205 if not env.is_module_scope:
5206 error(self.pos, "cimport only allowed at module level")
5208 module_scope = env.find_module(self.module_name, self.pos)
5209 env.add_imported_module(module_scope)
5210 for pos, name, as_name, kind in self.imported_names:
5212 for local_name, entry in module_scope.entries.items():
5213 env.add_imported_entry(local_name, entry, pos)
5215 entry = module_scope.lookup(name)
5217 if kind and not self.declaration_matches(entry, kind):
5218 entry.redeclared(pos)
5220 if kind == 'struct' or kind == 'union':
5221 entry = module_scope.declare_struct_or_union(name,
5222 kind = kind, scope = None, typedef_flag = 0, pos = pos)
5223 elif kind == 'class':
5224 entry = module_scope.declare_c_class(name, pos = pos,
5225 module_name = self.module_name)
5227 submodule_scope = env.context.find_module(name, relative_to = module_scope, pos = self.pos)
5228 if submodule_scope.parent_module is module_scope:
5229 env.declare_module(as_name or name, submodule_scope, self.pos)
5231 error(pos, "Name '%s' not declared in module '%s'"
5232 % (name, self.module_name))
5235 local_name = as_name or name
5236 env.add_imported_entry(local_name, entry, pos)
5238 def declaration_matches(self, entry, kind):
5239 if not entry.is_type:
5243 if not type.is_extension_type:
5246 if not type.is_struct_or_union:
5248 if kind != type.kind:
5252 def analyse_expressions(self, env):
5255 def generate_execution_code(self, code):
5259 class FromImportStatNode(StatNode):
5260 # from ... import statement
5263 # items [(string, NameNode)]
5264 # interned_items [(string, NameNode, ExprNode)]
5265 # item PyTempNode used internally
5266 # import_star boolean used internally
5268 child_attrs = ["module"]
5271 def analyse_declarations(self, env):
5272 for name, target in self.items:
5274 if not env.is_module_scope:
5275 error(self.pos, "import * only allowed at module level")
5277 env.has_import_star = 1
5278 self.import_star = 1
5280 target.analyse_target_declaration(env)
5282 def analyse_expressions(self, env):
5284 self.module.analyse_expressions(env)
5285 self.item = ExprNodes.RawCNameExprNode(self.pos, py_object_type)
5286 self.interned_items = []
5287 for name, target in self.items:
5289 for _, entry in env.entries.items():
5290 if not entry.is_type and entry.type.is_extension_type:
5291 env.use_utility_code(ExprNodes.type_test_utility_code)
5294 entry = env.lookup(target.name)
5295 # check whether or not entry is already cimported
5296 if (entry.is_type and entry.type.name == name
5297 and hasattr(entry.type, 'module_name')):
5298 if entry.type.module_name == self.module.module_name.value:
5299 # cimported with absolute name
5302 # cimported with relative name
5303 module = env.find_module(self.module.module_name.value,
5305 if entry.type.module_name == module.qualified_name:
5307 except AttributeError:
5309 target.analyse_target_expression(env, None)
5310 if target.type is py_object_type:
5313 coerced_item = self.item.coerce_to(target.type, env)
5314 self.interned_items.append((name, target, coerced_item))
5316 def generate_execution_code(self, code):
5317 self.module.generate_evaluation_code(code)
5318 if self.import_star:
5320 'if (%s(%s) < 0) %s;' % (
5322 self.module.py_result(),
5323 code.error_goto(self.pos)))
5324 item_temp = code.funcstate.allocate_temp(py_object_type, manage_ref=True)
5325 self.item.set_cname(item_temp)
5326 for name, target, coerced_item in self.interned_items:
5327 cname = code.intern_identifier(name)
5329 '%s = PyObject_GetAttr(%s, %s); %s' % (
5331 self.module.py_result(),
5333 code.error_goto_if_null(item_temp, self.pos)))
5334 code.put_gotref(item_temp)
5335 if coerced_item is None:
5336 target.generate_assignment_code(self.item, code)
5338 coerced_item.allocate_temp_result(code)
5339 coerced_item.generate_result_code(code)
5340 target.generate_assignment_code(coerced_item, code)
5341 code.put_decref_clear(item_temp, py_object_type)
5342 code.funcstate.release_temp(item_temp)
5343 self.module.generate_disposal_code(code)
5344 self.module.free_temps(code)
5348 #------------------------------------------------------------------------------------
5350 # Runtime support code
5352 #------------------------------------------------------------------------------------
5354 utility_function_predeclarations = \
5356 /* inline attribute */
5357 #ifndef CYTHON_INLINE
5358 #if defined(__GNUC__)
5359 #define CYTHON_INLINE __inline__
5360 #elif defined(_MSC_VER)
5361 #define CYTHON_INLINE __inline
5362 #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
5363 #define CYTHON_INLINE inline
5365 #define CYTHON_INLINE
5369 /* unused attribute */
5370 #ifndef CYTHON_UNUSED
5371 # if defined(__GNUC__)
5372 # if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4))
5373 # define CYTHON_UNUSED __attribute__ ((__unused__))
5375 # define CYTHON_UNUSED
5377 # elif defined(__ICC) || defined(__INTEL_COMPILER)
5378 # define CYTHON_UNUSED __attribute__ ((__unused__))
5380 # define CYTHON_UNUSED
5384 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*/
5388 if Options.gcc_branch_hints:
5389 branch_prediction_macros = \
5392 /* Test for GCC > 2.95 */
5393 #if __GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))
5394 #define likely(x) __builtin_expect(!!(x), 1)
5395 #define unlikely(x) __builtin_expect(!!(x), 0)
5396 #else /* __GNUC__ > 2 ... */
5397 #define likely(x) (x)
5398 #define unlikely(x) (x)
5399 #endif /* __GNUC__ > 2 ... */
5400 #else /* __GNUC__ */
5401 #define likely(x) (x)
5402 #define unlikely(x) (x)
5403 #endif /* __GNUC__ */
5406 branch_prediction_macros = \
5408 #define likely(x) (x)
5409 #define unlikely(x) (x)
5412 #get_name_predeclaration = \
5413 #"static PyObject *__Pyx_GetName(PyObject *dict, char *name); /*proto*/"
5415 #get_name_interned_predeclaration = \
5416 #"static PyObject *__Pyx_GetName(PyObject *dict, PyObject *name); /*proto*/"
5418 #------------------------------------------------------------------------------------
5420 printing_utility_code = UtilityCode(
5422 static int __Pyx_Print(PyObject*, PyObject *, int); /*proto*/
5423 #if PY_MAJOR_VERSION >= 3
5424 static PyObject* %s = 0;
5425 static PyObject* %s = 0;
5427 """ % (Naming.print_function, Naming.print_function_kwargs),
5429 #if PY_MAJOR_VERSION >= 3
5433 """ % (Naming.print_function, Naming.print_function_kwargs),
5435 #if PY_MAJOR_VERSION < 3
5436 static PyObject *__Pyx_GetStdout(void) {
5437 PyObject *f = PySys_GetObject((char *)"stdout");
5439 PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout");
5444 static int __Pyx_Print(PyObject* f, PyObject *arg_tuple, int newline) {
5449 if (!(f = __Pyx_GetStdout()))
5452 for (i=0; i < PyTuple_GET_SIZE(arg_tuple); i++) {
5453 if (PyFile_SoftSpace(f, 1)) {
5454 if (PyFile_WriteString(" ", f) < 0)
5457 v = PyTuple_GET_ITEM(arg_tuple, i);
5458 if (PyFile_WriteObject(v, f, Py_PRINT_RAW) < 0)
5460 if (PyString_Check(v)) {
5461 char *s = PyString_AsString(v);
5462 Py_ssize_t len = PyString_Size(v);
5464 isspace(Py_CHARMASK(s[len-1])) &&
5466 PyFile_SoftSpace(f, 0);
5470 if (PyFile_WriteString("\n", f) < 0)
5472 PyFile_SoftSpace(f, 0);
5477 #else /* Python 3 has a print function */
5479 static int __Pyx_Print(PyObject* stream, PyObject *arg_tuple, int newline) {
5480 PyObject* kwargs = 0;
5481 PyObject* result = 0;
5482 PyObject* end_string;
5483 if (unlikely(!%(PRINT_FUNCTION)s)) {
5484 %(PRINT_FUNCTION)s = __Pyx_GetAttrString(%(BUILTINS)s, "print");
5485 if (!%(PRINT_FUNCTION)s)
5489 kwargs = PyDict_New();
5490 if (unlikely(!kwargs))
5492 if (unlikely(PyDict_SetItemString(kwargs, "file", stream) < 0))
5495 end_string = PyUnicode_FromStringAndSize(" ", 1);
5496 if (unlikely(!end_string))
5498 if (PyDict_SetItemString(kwargs, "end", end_string) < 0) {
5499 Py_DECREF(end_string);
5502 Py_DECREF(end_string);
5504 } else if (!newline) {
5505 if (unlikely(!%(PRINT_KWARGS)s)) {
5506 %(PRINT_KWARGS)s = PyDict_New();
5507 if (unlikely(!%(PRINT_KWARGS)s))
5509 end_string = PyUnicode_FromStringAndSize(" ", 1);
5510 if (unlikely(!end_string))
5512 if (PyDict_SetItemString(%(PRINT_KWARGS)s, "end", end_string) < 0) {
5513 Py_DECREF(end_string);
5516 Py_DECREF(end_string);
5518 kwargs = %(PRINT_KWARGS)s;
5520 result = PyObject_Call(%(PRINT_FUNCTION)s, arg_tuple, kwargs);
5521 if (unlikely(kwargs) && (kwargs != %(PRINT_KWARGS)s))
5528 if (kwargs != %(PRINT_KWARGS)s)
5534 """ % {'BUILTINS' : Naming.builtins_cname,
5535 'PRINT_FUNCTION' : Naming.print_function,
5536 'PRINT_KWARGS' : Naming.print_function_kwargs}
5540 printing_one_utility_code = UtilityCode(
5542 static int __Pyx_PrintOne(PyObject* stream, PyObject *o); /*proto*/
5545 #if PY_MAJOR_VERSION < 3
5547 static int __Pyx_PrintOne(PyObject* f, PyObject *o) {
5549 if (!(f = __Pyx_GetStdout()))
5552 if (PyFile_SoftSpace(f, 0)) {
5553 if (PyFile_WriteString(" ", f) < 0)
5556 if (PyFile_WriteObject(o, f, Py_PRINT_RAW) < 0)
5558 if (PyFile_WriteString("\n", f) < 0)
5561 /* the line below is just to avoid compiler
5562 * compiler warnings about unused functions */
5563 return __Pyx_Print(f, NULL, 0);
5566 #else /* Python 3 has a print function */
5568 static int __Pyx_PrintOne(PyObject* stream, PyObject *o) {
5570 PyObject* arg_tuple = PyTuple_New(1);
5571 if (unlikely(!arg_tuple))
5574 PyTuple_SET_ITEM(arg_tuple, 0, o);
5575 res = __Pyx_Print(stream, arg_tuple, 1);
5576 Py_DECREF(arg_tuple);
5582 requires=[printing_utility_code])
5586 #------------------------------------------------------------------------------------
5588 # Exception raising code
5590 # Exceptions are raised by __Pyx_Raise() and stored as plain
5591 # type/value/tb in PyThreadState->curexc_*. When being caught by an
5592 # 'except' statement, curexc_* is moved over to exc_* by
5593 # __Pyx_GetException()
5595 restore_exception_utility_code = UtilityCode(
5597 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5598 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5601 static CYTHON_INLINE void __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
5602 PyObject *tmp_type, *tmp_value, *tmp_tb;
5603 PyThreadState *tstate = PyThreadState_GET();
5605 tmp_type = tstate->curexc_type;
5606 tmp_value = tstate->curexc_value;
5607 tmp_tb = tstate->curexc_traceback;
5608 tstate->curexc_type = type;
5609 tstate->curexc_value = value;
5610 tstate->curexc_traceback = tb;
5611 Py_XDECREF(tmp_type);
5612 Py_XDECREF(tmp_value);
5616 static CYTHON_INLINE void __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
5617 PyThreadState *tstate = PyThreadState_GET();
5618 *type = tstate->curexc_type;
5619 *value = tstate->curexc_value;
5620 *tb = tstate->curexc_traceback;
5622 tstate->curexc_type = 0;
5623 tstate->curexc_value = 0;
5624 tstate->curexc_traceback = 0;
5629 # The following function is based on do_raise() from ceval.c. There
5630 # are separate versions for Python2 and Python3 as exception handling
5631 # has changed quite a lot between the two versions.
5633 raise_utility_code = UtilityCode(
5635 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5638 #if PY_MAJOR_VERSION < 3
5639 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5643 /* First, check the traceback argument, replacing None with NULL. */
5644 if (tb == Py_None) {
5648 else if (tb != NULL && !PyTraceBack_Check(tb)) {
5649 PyErr_SetString(PyExc_TypeError,
5650 "raise: arg 3 must be a traceback or None");
5653 /* Next, replace a missing value with None */
5654 if (value == NULL) {
5658 #if PY_VERSION_HEX < 0x02050000
5659 if (!PyClass_Check(type))
5661 if (!PyType_Check(type))
5664 /* Raising an instance. The value should be a dummy. */
5665 if (value != Py_None) {
5666 PyErr_SetString(PyExc_TypeError,
5667 "instance exception may not have a separate value");
5670 /* Normalize to raise <class>, <instance> */
5673 #if PY_VERSION_HEX < 0x02050000
5674 if (PyInstance_Check(type)) {
5675 type = (PyObject*) ((PyInstanceObject*)type)->in_class;
5680 PyErr_SetString(PyExc_TypeError,
5681 "raise: exception must be an old-style class or instance");
5685 type = (PyObject*) Py_TYPE(type);
5687 if (!PyType_IsSubtype((PyTypeObject *)type, (PyTypeObject *)PyExc_BaseException)) {
5688 PyErr_SetString(PyExc_TypeError,
5689 "raise: exception class must be a subclass of BaseException");
5695 __Pyx_ErrRestore(type, value, tb);
5704 #else /* Python 3+ */
5706 static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
5707 if (tb == Py_None) {
5709 } else if (tb && !PyTraceBack_Check(tb)) {
5710 PyErr_SetString(PyExc_TypeError,
5711 "raise: arg 3 must be a traceback or None");
5714 if (value == Py_None)
5717 if (PyExceptionInstance_Check(type)) {
5719 PyErr_SetString(PyExc_TypeError,
5720 "instance exception may not have a separate value");
5724 type = (PyObject*) Py_TYPE(value);
5725 } else if (!PyExceptionClass_Check(type)) {
5726 PyErr_SetString(PyExc_TypeError,
5727 "raise: exception class must be a subclass of BaseException");
5731 PyErr_SetObject(type, value);
5734 PyThreadState *tstate = PyThreadState_GET();
5735 PyObject* tmp_tb = tstate->curexc_traceback;
5738 tstate->curexc_traceback = tb;
5748 requires=[restore_exception_utility_code])
5750 #------------------------------------------------------------------------------------
5752 get_exception_utility_code = UtilityCode(
5754 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5757 static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
5758 PyObject *local_type, *local_value, *local_tb;
5759 PyObject *tmp_type, *tmp_value, *tmp_tb;
5760 PyThreadState *tstate = PyThreadState_GET();
5761 local_type = tstate->curexc_type;
5762 local_value = tstate->curexc_value;
5763 local_tb = tstate->curexc_traceback;
5764 tstate->curexc_type = 0;
5765 tstate->curexc_value = 0;
5766 tstate->curexc_traceback = 0;
5767 PyErr_NormalizeException(&local_type, &local_value, &local_tb);
5768 if (unlikely(tstate->curexc_type))
5770 #if PY_MAJOR_VERSION >= 3
5771 if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0))
5775 *value = local_value;
5777 Py_INCREF(local_type);
5778 Py_INCREF(local_value);
5779 Py_INCREF(local_tb);
5780 tmp_type = tstate->exc_type;
5781 tmp_value = tstate->exc_value;
5782 tmp_tb = tstate->exc_traceback;
5783 tstate->exc_type = local_type;
5784 tstate->exc_value = local_value;
5785 tstate->exc_traceback = local_tb;
5786 /* Make sure tstate is in a consistent state when we XDECREF
5787 these objects (XDECREF may run arbitrary code). */
5788 Py_XDECREF(tmp_type);
5789 Py_XDECREF(tmp_value);
5796 Py_XDECREF(local_type);
5797 Py_XDECREF(local_value);
5798 Py_XDECREF(local_tb);
5804 #------------------------------------------------------------------------------------
5806 get_exception_tuple_utility_code = UtilityCode(proto="""
5807 static PyObject *__Pyx_GetExceptionTuple(void); /*proto*/
5809 # I doubt that calling __Pyx_GetException() here is correct as it moves
5810 # the exception from tstate->curexc_* to tstate->exc_*, which prevents
5811 # exception handlers later on from receiving it.
5813 static PyObject *__Pyx_GetExceptionTuple(void) {
5814 PyObject *type = NULL, *value = NULL, *tb = NULL;
5815 if (__Pyx_GetException(&type, &value, &tb) == 0) {
5816 PyObject* exc_info = PyTuple_New(3);
5821 PyTuple_SET_ITEM(exc_info, 0, type);
5822 PyTuple_SET_ITEM(exc_info, 1, value);
5823 PyTuple_SET_ITEM(exc_info, 2, tb);
5830 requires=[get_exception_utility_code])
5832 #------------------------------------------------------------------------------------
5834 reset_exception_utility_code = UtilityCode(
5836 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
5837 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
5840 static CYTHON_INLINE void __Pyx_ExceptionSave(PyObject **type, PyObject **value, PyObject **tb) {
5841 PyThreadState *tstate = PyThreadState_GET();
5842 *type = tstate->exc_type;
5843 *value = tstate->exc_value;
5844 *tb = tstate->exc_traceback;
5850 static void __Pyx_ExceptionReset(PyObject *type, PyObject *value, PyObject *tb) {
5851 PyObject *tmp_type, *tmp_value, *tmp_tb;
5852 PyThreadState *tstate = PyThreadState_GET();
5853 tmp_type = tstate->exc_type;
5854 tmp_value = tstate->exc_value;
5855 tmp_tb = tstate->exc_traceback;
5856 tstate->exc_type = type;
5857 tstate->exc_value = value;
5858 tstate->exc_traceback = tb;
5859 Py_XDECREF(tmp_type);
5860 Py_XDECREF(tmp_value);
5865 #------------------------------------------------------------------------------------
5867 arg_type_test_utility_code = UtilityCode(
5869 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5870 const char *name, int exact); /*proto*/
5873 static int __Pyx_ArgTypeTest(PyObject *obj, PyTypeObject *type, int none_allowed,
5874 const char *name, int exact)
5877 PyErr_Format(PyExc_SystemError, "Missing type object");
5880 if (none_allowed && obj == Py_None) return 1;
5882 if (Py_TYPE(obj) == type) return 1;
5885 if (PyObject_TypeCheck(obj, type)) return 1;
5887 PyErr_Format(PyExc_TypeError,
5888 "Argument '%s' has incorrect type (expected %s, got %s)",
5889 name, type->tp_name, Py_TYPE(obj)->tp_name);
5894 #------------------------------------------------------------------------------------
5896 # __Pyx_RaiseArgtupleInvalid raises the correct exception when too
5897 # many or too few positional arguments were found. This handles
5898 # Py_ssize_t formatting correctly.
5900 raise_argtuple_invalid_utility_code = UtilityCode(
5902 static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact,
5903 Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); /*proto*/
5906 static void __Pyx_RaiseArgtupleInvalid(
5907 const char* func_name,
5911 Py_ssize_t num_found)
5913 Py_ssize_t num_expected;
5914 const char *number, *more_or_less;
5916 if (num_found < num_min) {
5917 num_expected = num_min;
5918 more_or_less = "at least";
5920 num_expected = num_max;
5921 more_or_less = "at most";
5924 more_or_less = "exactly";
5926 number = (num_expected == 1) ? "" : "s";
5927 PyErr_Format(PyExc_TypeError,
5928 #if PY_VERSION_HEX < 0x02050000
5929 "%s() takes %s %d positional argument%s (%d given)",
5931 "%s() takes %s %zd positional argument%s (%zd given)",
5933 func_name, more_or_less, num_expected, number, num_found);
5937 raise_keyword_required_utility_code = UtilityCode(
5939 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(const char* func_name, PyObject* kw_name); /*proto*/
5942 static CYTHON_INLINE void __Pyx_RaiseKeywordRequired(
5943 const char* func_name,
5946 PyErr_Format(PyExc_TypeError,
5947 #if PY_MAJOR_VERSION >= 3
5948 "%s() needs keyword-only argument %U", func_name, kw_name);
5950 "%s() needs keyword-only argument %s", func_name,
5951 PyString_AS_STRING(kw_name));
5956 raise_double_keywords_utility_code = UtilityCode(
5958 static void __Pyx_RaiseDoubleKeywordsError(
5959 const char* func_name, PyObject* kw_name); /*proto*/
5962 static void __Pyx_RaiseDoubleKeywordsError(
5963 const char* func_name,
5966 PyErr_Format(PyExc_TypeError,
5967 #if PY_MAJOR_VERSION >= 3
5968 "%s() got multiple values for keyword argument '%U'", func_name, kw_name);
5970 "%s() got multiple values for keyword argument '%s'", func_name,
5971 PyString_AS_STRING(kw_name));
5976 #------------------------------------------------------------------------------------
5978 # __Pyx_CheckKeywordStrings raises an error if non-string keywords
5979 # were passed to a function, or if any keywords were passed to a
5980 # function that does not accept them.
5982 keyword_string_check_utility_code = UtilityCode(
5984 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(PyObject *kwdict,
5985 const char* function_name, int kw_allowed); /*proto*/
5988 static CYTHON_INLINE int __Pyx_CheckKeywordStrings(
5990 const char* function_name,
5995 while (PyDict_Next(kwdict, &pos, &key, 0)) {
5996 #if PY_MAJOR_VERSION < 3
5997 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key)))
5999 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key)))
6001 goto invalid_keyword_type;
6003 if ((!kw_allowed) && unlikely(key))
6004 goto invalid_keyword;
6006 invalid_keyword_type:
6007 PyErr_Format(PyExc_TypeError,
6008 "%s() keywords must be strings", function_name);
6011 PyErr_Format(PyExc_TypeError,
6012 #if PY_MAJOR_VERSION < 3
6013 "%s() got an unexpected keyword argument '%s'",
6014 function_name, PyString_AsString(key));
6016 "%s() got an unexpected keyword argument '%U'",
6017 function_name, key);
6023 #------------------------------------------------------------------------------------
6025 # __Pyx_ParseOptionalKeywords copies the optional/unknown keyword
6026 # arguments from the kwds dict into kwds2. If kwds2 is NULL, unknown
6027 # keywords will raise an invalid keyword error.
6029 # Three kinds of errors are checked: 1) non-string keywords, 2)
6030 # unexpected keywords and 3) overlap with positional arguments.
6032 # If num_posargs is greater 0, it denotes the number of positional
6033 # arguments that were passed and that must therefore not appear
6034 # amongst the keywords as well.
6036 # This method does not check for required keyword arguments.
6039 parse_keywords_utility_code = UtilityCode(
6041 static int __Pyx_ParseOptionalKeywords(PyObject *kwds, PyObject **argnames[], \
6042 PyObject *kwds2, PyObject *values[], Py_ssize_t num_pos_args, \
6043 const char* function_name); /*proto*/
6046 static int __Pyx_ParseOptionalKeywords(
6048 PyObject **argnames[],
6051 Py_ssize_t num_pos_args,
6052 const char* function_name)
6054 PyObject *key = 0, *value = 0;
6057 PyObject*** first_kw_arg = argnames + num_pos_args;
6059 while (PyDict_Next(kwds, &pos, &key, &value)) {
6060 name = first_kw_arg;
6061 while (*name && (**name != key)) name++;
6063 values[name-argnames] = value;
6065 #if PY_MAJOR_VERSION < 3
6066 if (unlikely(!PyString_CheckExact(key)) && unlikely(!PyString_Check(key))) {
6068 if (unlikely(!PyUnicode_CheckExact(key)) && unlikely(!PyUnicode_Check(key))) {
6070 goto invalid_keyword_type;
6072 for (name = first_kw_arg; *name; name++) {
6073 #if PY_MAJOR_VERSION >= 3
6074 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6075 PyUnicode_Compare(**name, key) == 0) break;
6077 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6078 _PyString_Eq(**name, key)) break;
6082 values[name-argnames] = value;
6084 /* unexpected keyword found */
6085 for (name=argnames; name != first_kw_arg; name++) {
6086 if (**name == key) goto arg_passed_twice;
6087 #if PY_MAJOR_VERSION >= 3
6088 if (PyUnicode_GET_SIZE(**name) == PyUnicode_GET_SIZE(key) &&
6089 PyUnicode_Compare(**name, key) == 0) goto arg_passed_twice;
6091 if (PyString_GET_SIZE(**name) == PyString_GET_SIZE(key) &&
6092 _PyString_Eq(**name, key)) goto arg_passed_twice;
6096 if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad;
6098 goto invalid_keyword;
6106 __Pyx_RaiseDoubleKeywordsError(function_name, **name);
6108 invalid_keyword_type:
6109 PyErr_Format(PyExc_TypeError,
6110 "%s() keywords must be strings", function_name);
6113 PyErr_Format(PyExc_TypeError,
6114 #if PY_MAJOR_VERSION < 3
6115 "%s() got an unexpected keyword argument '%s'",
6116 function_name, PyString_AsString(key));
6118 "%s() got an unexpected keyword argument '%U'",
6119 function_name, key);
6126 #------------------------------------------------------------------------------------
6128 traceback_utility_code = UtilityCode(
6130 static void __Pyx_AddTraceback(const char *funcname); /*proto*/
6133 #include "compile.h"
6134 #include "frameobject.h"
6135 #include "traceback.h"
6137 static void __Pyx_AddTraceback(const char *funcname) {
6138 PyObject *py_srcfile = 0;
6139 PyObject *py_funcname = 0;
6140 PyObject *py_globals = 0;
6141 PyCodeObject *py_code = 0;
6142 PyFrameObject *py_frame = 0;
6144 #if PY_MAJOR_VERSION < 3
6145 py_srcfile = PyString_FromString(%(FILENAME)s);
6147 py_srcfile = PyUnicode_FromString(%(FILENAME)s);
6149 if (!py_srcfile) goto bad;
6151 #if PY_MAJOR_VERSION < 3
6152 py_funcname = PyString_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6154 py_funcname = PyUnicode_FromFormat( "%%s (%%s:%%d)", funcname, %(CFILENAME)s, %(CLINENO)s);
6158 #if PY_MAJOR_VERSION < 3
6159 py_funcname = PyString_FromString(funcname);
6161 py_funcname = PyUnicode_FromString(funcname);
6164 if (!py_funcname) goto bad;
6165 py_globals = PyModule_GetDict(%(GLOBALS)s);
6166 if (!py_globals) goto bad;
6167 py_code = PyCode_New(
6168 0, /*int argcount,*/
6169 #if PY_MAJOR_VERSION >= 3
6170 0, /*int kwonlyargcount,*/
6173 0, /*int stacksize,*/
6175 %(EMPTY_BYTES)s, /*PyObject *code,*/
6176 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6177 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6178 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6179 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6180 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6181 py_srcfile, /*PyObject *filename,*/
6182 py_funcname, /*PyObject *name,*/
6183 %(LINENO)s, /*int firstlineno,*/
6184 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6186 if (!py_code) goto bad;
6187 py_frame = PyFrame_New(
6188 PyThreadState_GET(), /*PyThreadState *tstate,*/
6189 py_code, /*PyCodeObject *code,*/
6190 py_globals, /*PyObject *globals,*/
6191 0 /*PyObject *locals*/
6193 if (!py_frame) goto bad;
6194 py_frame->f_lineno = %(LINENO)s;
6195 PyTraceBack_Here(py_frame);
6197 Py_XDECREF(py_srcfile);
6198 Py_XDECREF(py_funcname);
6199 Py_XDECREF(py_code);
6200 Py_XDECREF(py_frame);
6203 'FILENAME': Naming.filename_cname,
6204 'LINENO': Naming.lineno_cname,
6205 'CFILENAME': Naming.cfilenm_cname,
6206 'CLINENO': Naming.clineno_cname,
6207 'GLOBALS': Naming.module_cname,
6208 'EMPTY_TUPLE' : Naming.empty_tuple,
6209 'EMPTY_BYTES' : Naming.empty_bytes,
6212 #------------------------------------------------------------------------------------
6214 unraisable_exception_utility_code = UtilityCode(
6216 static void __Pyx_WriteUnraisable(const char *name); /*proto*/
6219 static void __Pyx_WriteUnraisable(const char *name) {
6220 PyObject *old_exc, *old_val, *old_tb;
6222 __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
6223 #if PY_MAJOR_VERSION < 3
6224 ctx = PyString_FromString(name);
6226 ctx = PyUnicode_FromString(name);
6228 __Pyx_ErrRestore(old_exc, old_val, old_tb);
6230 PyErr_WriteUnraisable(Py_None);
6232 PyErr_WriteUnraisable(ctx);
6237 requires=[restore_exception_utility_code])
6239 #------------------------------------------------------------------------------------
6241 set_vtable_utility_code = UtilityCode(
6243 static int __Pyx_SetVtable(PyObject *dict, void *vtable); /*proto*/
6246 static int __Pyx_SetVtable(PyObject *dict, void *vtable) {
6247 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6248 PyObject *ob = PyCapsule_New(vtable, 0, 0);
6250 PyObject *ob = PyCObject_FromVoidPtr(vtable, 0);
6254 if (PyDict_SetItemString(dict, "__pyx_vtable__", ob) < 0)
6264 #------------------------------------------------------------------------------------
6266 get_vtable_utility_code = UtilityCode(
6268 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr); /*proto*/
6271 static int __Pyx_GetVtable(PyObject *dict, void *vtabptr) {
6272 PyObject *ob = PyMapping_GetItemString(dict, (char *)"__pyx_vtable__");
6275 #if PY_VERSION_HEX >= 0x02070000 && !(PY_MAJOR_VERSION==3&&PY_MINOR_VERSION==0)
6276 *(void **)vtabptr = PyCapsule_GetPointer(ob, 0);
6278 *(void **)vtabptr = PyCObject_AsVoidPtr(ob);
6280 if (!*(void **)vtabptr)
6290 #------------------------------------------------------------------------------------
6292 init_string_tab_utility_code = UtilityCode(
6294 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
6297 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
6299 #if PY_MAJOR_VERSION < 3
6300 if (t->is_unicode) {
6301 *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
6302 } else if (t->intern) {
6303 *t->p = PyString_InternFromString(t->s);
6305 *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
6307 #else /* Python 3+ has unicode identifiers */
6308 if (t->is_unicode | t->is_str) {
6310 *t->p = PyUnicode_InternFromString(t->s);
6311 } else if (t->encoding) {
6312 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
6314 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
6317 *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
6328 #------------------------------------------------------------------------------------
6330 force_init_threads_utility_code = UtilityCode(
6332 #ifndef __PYX_FORCE_INIT_THREADS
6333 #if PY_VERSION_HEX < 0x02040200
6334 #define __PYX_FORCE_INIT_THREADS 1
6336 #define __PYX_FORCE_INIT_THREADS 0
6341 #------------------------------------------------------------------------------------
6343 # Note that cPython ignores PyTrace_EXCEPTION,
6344 # but maybe some other profilers don't.
6346 profile_utility_code = UtilityCode(proto="""
6347 #ifndef CYTHON_PROFILE
6348 #define CYTHON_PROFILE 1
6351 #ifndef CYTHON_PROFILE_REUSE_FRAME
6352 #define CYTHON_PROFILE_REUSE_FRAME 0
6357 #include "compile.h"
6358 #include "frameobject.h"
6359 #include "traceback.h"
6361 #if CYTHON_PROFILE_REUSE_FRAME
6362 #define CYTHON_FRAME_MODIFIER static
6363 #define CYTHON_FRAME_DEL
6365 #define CYTHON_FRAME_MODIFIER
6366 #define CYTHON_FRAME_DEL Py_DECREF(%(FRAME)s)
6369 #define __Pyx_TraceDeclarations \\
6370 static PyCodeObject *%(FRAME_CODE)s = NULL; \\
6371 CYTHON_FRAME_MODIFIER PyFrameObject *%(FRAME)s = NULL; \\
6372 int __Pyx_use_tracing = 0;
6374 #define __Pyx_TraceCall(funcname, srcfile, firstlineno) \\
6375 if (unlikely(PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc)) { \\
6376 __Pyx_use_tracing = __Pyx_TraceSetupAndCall(&%(FRAME_CODE)s, &%(FRAME)s, funcname, srcfile, firstlineno); \\
6379 #define __Pyx_TraceException() \\
6380 if (unlikely(__Pyx_use_tracing( && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6381 PyObject *exc_info = __Pyx_GetExceptionTuple(); \\
6383 PyThreadState_GET()->c_profilefunc( \\
6384 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_EXCEPTION, exc_info); \\
6385 Py_DECREF(exc_info); \\
6389 #define __Pyx_TraceReturn(result) \\
6390 if (unlikely(__Pyx_use_tracing) && PyThreadState_GET()->use_tracing && PyThreadState_GET()->c_profilefunc) { \\
6391 PyThreadState_GET()->c_profilefunc( \\
6392 PyThreadState_GET()->c_profileobj, %(FRAME)s, PyTrace_RETURN, (PyObject*)result); \\
6393 CYTHON_FRAME_DEL; \\
6396 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6397 static int __Pyx_TraceSetupAndCall(PyCodeObject** code, PyFrameObject** frame, const char *funcname, const char *srcfile, int firstlineno); /*proto*/
6401 #define __Pyx_TraceDeclarations
6402 #define __Pyx_TraceCall(funcname, srcfile, firstlineno)
6403 #define __Pyx_TraceException()
6404 #define __Pyx_TraceReturn(result)
6406 #endif /* CYTHON_PROFILE */
6409 "FRAME": Naming.frame_cname,
6410 "FRAME_CODE": Naming.frame_code_cname,
6416 static int __Pyx_TraceSetupAndCall(PyCodeObject** code,
6417 PyFrameObject** frame,
6418 const char *funcname,
6419 const char *srcfile,
6421 if (*frame == NULL || !CYTHON_PROFILE_REUSE_FRAME) {
6422 if (*code == NULL) {
6423 *code = __Pyx_createFrameCodeObject(funcname, srcfile, firstlineno);
6424 if (*code == NULL) return 0;
6426 *frame = PyFrame_New(
6427 PyThreadState_GET(), /*PyThreadState *tstate*/
6428 *code, /*PyCodeObject *code*/
6429 PyModule_GetDict(%(MODULE)s), /*PyObject *globals*/
6430 0 /*PyObject *locals*/
6432 if (*frame == NULL) return 0;
6435 (*frame)->f_tstate = PyThreadState_GET();
6437 return PyThreadState_GET()->c_profilefunc(PyThreadState_GET()->c_profileobj, *frame, PyTrace_CALL, NULL) == 0;
6440 static PyCodeObject *__Pyx_createFrameCodeObject(const char *funcname, const char *srcfile, int firstlineno) {
6441 PyObject *py_srcfile = 0;
6442 PyObject *py_funcname = 0;
6443 PyCodeObject *py_code = 0;
6445 #if PY_MAJOR_VERSION < 3
6446 py_funcname = PyString_FromString(funcname);
6447 py_srcfile = PyString_FromString(srcfile);
6449 py_funcname = PyUnicode_FromString(funcname);
6450 py_srcfile = PyUnicode_FromString(srcfile);
6452 if (!py_funcname | !py_srcfile) goto bad;
6454 py_code = PyCode_New(
6455 0, /*int argcount,*/
6456 #if PY_MAJOR_VERSION >= 3
6457 0, /*int kwonlyargcount,*/
6460 0, /*int stacksize,*/
6462 %(EMPTY_BYTES)s, /*PyObject *code,*/
6463 %(EMPTY_TUPLE)s, /*PyObject *consts,*/
6464 %(EMPTY_TUPLE)s, /*PyObject *names,*/
6465 %(EMPTY_TUPLE)s, /*PyObject *varnames,*/
6466 %(EMPTY_TUPLE)s, /*PyObject *freevars,*/
6467 %(EMPTY_TUPLE)s, /*PyObject *cellvars,*/
6468 py_srcfile, /*PyObject *filename,*/
6469 py_funcname, /*PyObject *name,*/
6470 firstlineno, /*int firstlineno,*/
6471 %(EMPTY_BYTES)s /*PyObject *lnotab*/
6475 Py_XDECREF(py_srcfile);
6476 Py_XDECREF(py_funcname);
6481 #endif /* CYTHON_PROFILE */
6483 'EMPTY_TUPLE' : Naming.empty_tuple,
6484 'EMPTY_BYTES' : Naming.empty_bytes,
6485 "MODULE": Naming.module_cname,